28 abr 2009

Como leer y escribir en el Registro de Windows desde una aplicación .NET

Para trabajar sobre el registro de Windows utilizaremos las cases Registry y RegistryKey del Namespace Microsoft.Win32. Con éstas 2 clases podremos realizar todas tareas de lectura y escritura en el registro.
Este es un ejemplo muy sencillo, por lo tanto vamos a crear una clave Key, dentro crearemos un valor Value luego los eliminaremos. Después leeremos todos los Values que se encuentren en HKLM\Microsoft\Windows\CurrentVersion\Run, que son los que indican qué aplicaciones se ejecutan al iniciar Windows para todos los usuarios.

Debajo de estas líneas está el código, uno de los ejemplos más sencillos para leer y escribir en el Registro de Windows.

Trabajar con el Registro de Windows en nuestra aplicación .NET


Imports Microsoft.Win32
Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
CrearKey()
End Sub

Private Sub CrearKey()
Dim KeyPath As String = "Software\Test"
Registry.CurrentUser.CreateSubKey(KeyPath)
End Sub


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
CrearValue()
End Sub

Private Sub CrearValue()
Dim KeyPath As String = "Software\Test"
Dim ValueName As String = "TestValue"

Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey(KeyPath, True) ' True indica que se abre para escritura
If key IsNot Nothing Then ' Si key es Nothing significa que no se encontró
key.SetValue(ValueName, "Esto es una prueba", RegistryValueKind.String)
Else
If MessageBox.Show(String.Format("No se encontró la clave 'HKCU\{0}'. Desea crearla?", KeyPath), "", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
CrearKey() ' Creamos la clave y volvemos a intentar crear el valor
CrearValue()
End If
End If
End Sub


Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
EliminarValue()
End Sub

Private Sub EliminarValue()
Dim KeyPath As String = "Software\Test"
Dim ValueName As String = "TestValue"

Dim Key As RegistryKey = Registry.CurrentUser.OpenSubKey(KeyPath, True)

If Key IsNot Nothing Then
If Key.GetValueNames().Contains(ValueName) Then ' Buscamos el nombre del valor en la lista de todos los valores de la clave
Key.DeleteValue(ValueName) ' Borramos el valor
Else
MessageBox.Show(String.Format("No se encontró el valor '{0}'.", ValueName))
End If
Else
MessageBox.Show(String.Format("No se encontró la clave 'HKCU\{0}'.", KeyPath))
End If
End Sub

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
EliminarKey()
End Sub

Private Sub EliminarKey()
Dim KeyPath As String = "Software\Test"

Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey(KeyPath)

If key IsNot Nothing Then
Registry.CurrentUser.DeleteSubKey(KeyPath) ' Borramos la sub clave
Else
MessageBox.Show(String.Format("No se encontró la clave 'HKCU\{0}'.", KeyPath))
End If
End Sub


Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
LeerRegistro()
End Sub

Private Sub LeerRegistro()
Dim KeyPath As String = "Software\Microsoft\Windows\CurrentVersion\Run"
Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey(KeyPath, False) ' Abrimos para sólo lectura

If key IsNot Nothing Then
Dim sb As New System.Text.StringBuilder()

Dim values As String() = key.GetValueNames() ' Obtenemos los nombres de todos los valores en la key
For Each value As String In values
sb.AppendLine(String.Format("{0} > {1} ({2})", value, key.GetValue(value), key.GetValueKind(value).ToString()))
Next

Me.TextBox1.Text = sb.ToString() ' Mostramos el resultado en nuestra TextBox Multilínea
End If
End Sub
End Class


Registro de Windows - Aprendiendo.NET

9 mar 2009

Como imprimir un formulario - Microsoft.VisualBasic.PowerPacks.Printing.PrintForm

Este código muestra una forma sencilla de imprimir un formulario, para lo cual utilizaremos la clase PrintForm, que se encuentra en el Namespace Microsoft.VisualBasic.PowerPacks.Printing.

Lo primero que haremos será chequear si tenemos la referencia, para lo cual haremos click con el botón derecho sobre nuestro cuadro de herramientas y en el menú seleccionaremos la opción Choose Items..., cuando se abra el diálogo para seleccionar las referencias buscaremos la que corresponde al namespace antes mencionado y si no está seleccionada la seleccionaremos en este momento.

Microsoft.VisualBasic.PowerPacks.Printing.PrintForm

Puede ocurrir que no se muestre en el cuadro de herramientas, para poder verla haremos un click con el botón derecho sobre el cuadro de herramientas y en el menú seleccionaremos la opción Show All, que nos agregará varias secciones al cuadro de herramientas, la que buscamos se encuentra bajo el título de VisualBasic PowerPacks.

Ahora ya podemos arrastrar este componente a nuestro form y crear el siguiente método para poder imprimir el formulario:

    Private Sub Imprimir()
PrintForm1.PrintAction = Printing.PrintAction.PrintToPreview ' Crea una vista previa
' PrintForm1.PrintAction = Printing.PrintAction.PrintToFile ' Imprime a un archivo
' PrintForm1.PrintAction = Printing.PrintAction.PrintToPrinter ' Envía a la impresora
PrintForm1.Print() ' Finalmente hacemos la impresión
End Sub

27 feb 2009

Utilizando el portapapeles de Windows en nuestras aplicaciones .NET

Para manejar el portapapeles de Windows, el .Net Framework provee la clase Clipboard, del namespace My.Computerla cual posee todo lo necesario para copiar y pegar archivos, textos, imágenes, etc.


Veamos como copiar elementos al portapapeles:


  • My.Computer.Clipboard.SetImage(PictureBox1.Image) - Copia la imagen del picturebox

  • My.Computer.Clipboard.SetText(WebBrowser1.DocumentText, TextDataFormat.Html) - Copia el código HTML del documento que estamos mostrando en el WebBrowser como texto y setea el formato de éste como HTML.

  • My.Computer.Clipboard.SetText(RichTextBox1.Rtf, TextDataFormat.Rtf) - Ídem anterior pero formato RTF.

  • My.Computer.Clipboard.SetText(TextBox1.Text) - Copia un texto cualquiera, sin formato.

  • My.Computer.Clipboard.SetData(MyClassInstance.GetType().Name, MyClassInstance) - Copia el objeto MyClassInstance al portapapeles.



Ahora tenemos que recuperar los objetos que copiamos al portapapeles:


  • PictureBox2.Image = My.Computer.Clipboard.GetImage() - Recupera la imagen copiada al portapapeles y la setea como Image en el PictureBox2.

  • WebBrowser2.DocumentText = My.Computer.Clipboard.GetText(TextDataFormat.Html) - Obtiene el texto con formato HTML

  • RichTextBox2.Rtf = My.Computer.Clipboard.GetText(TextDataFormat.Rtf) - Idem anterior con formato RTF.

  • TextBox2.Text = My.Computer.Clipboard.GetText() - Recupera un texto sin formato y lo asigna en TextBox2.Text

  • Dim MyClassNewInstance As MyClass = CType(My.Computer.Clipboard.GetData(GetType(MyClass).Name), MyClass) - Recupera el objeto de tipo MyClass que copiamos anteriormente.



Para limpiar ó vaciar el portapapeles utilizaremos:


  • My.Computer.Clipboard.Clear()



Algunos controles que podemos hacer sobre la info contenida en el portapapeles:


  • If My.Computer.Clipboard.ContainsImage() Then - Para saber si hay una imagen en el portapapeles

  • If My.Computer.Clipboard.ContainsText(TextDataFormat.Html) - Para saber si el portapapeles contiene un texto en formato HTML

  • If My.Computer.Clipboard.ContainsData(GetType(MyClass).Name) Then - Comprueba si hay un objeto del tipo MyClass en el portapapeles.



Al preguntar por My.Computer.Clipboard.ContainsText(), se puede preguntar por varios formatos, los mismos se especifican en el Enum TextDataFormat:


  • CommaSeparatedValue

  • Html

  • Rtf

  • Text

  • UnicodeText



Y ese sería un resumen de los usos más frecuentes del portapapeles, aunque también se puede utilizar de varias maneras más, estas son las que consideré más útiles.

Una aclaración con respecto a copiar y pegar objetos, yo utilicé como nombre del formato el nombre del tipo tal cual se devuelve por GetType().Name, en ese parámetro se puede escribir cualquier String, pero considero una buena práctica utilizar el nombre del tipo para que al recuperar sepamos qué es lo que estamos buscando.

11 feb 2009

Trabajando con Archivos y Carpetas: System.IO.Path

La clase System.IO.Path provee una serie de métodos para realizar las tareas más comunes a la hora de trabajar con rutas de archivos o directorios, a continuación veremos los métodos de esta clase y para qué sirve cada uno.



  • System.IO.Path.AltDirectorySeparatorChar : Devuelve el caracter alternativo usado como separador de directorios en el sistema actual. Generalmente "/".

  • System.IO.Path.ChangeExtension("C:\prueba.txt", "xml") : Cambia la extensión del archivo pasado como primer parámetro, en este ejemplo devuelve C:\prueba.xml.

  • System.IO.Path.Combine("C:\Directorio1\", "prueba.xml") : Combina ambas rutas para generar una sola. Atención al segundo parámetro porque si empieza con el separador de directorio no funcionará como esperamos.

  • System.IO.Path.DirectorySeparatorChar : Devuelve el caracter usado como separador de directorios en el sistema actual. Generalmente "\".

  • System.IO.Path.GetDirectoryName("C:\Directorio1\prueba.txt") : Devuelve la ruta al directorio según la ruta que recibe por parámetro. En este ejemplo devuelve "C:\Directorio1"

  • System.IO.Path.GetExtension("C:\Directorio1\prueba.xml") : Devuelve la extensión del archivo que recibe por parámetro, por el ejemplo ".xml" si el archivo no tiene extensión devuelve "".

  • System.IO.Path.GetFileName("C:\Directorio1\prueba.xml") : Devuelve el nombre del archivo especificado en el parámetro sin el resto de la ruta. En este ejemplo devuelve "prueba.xml". Si la ruta especificada termina con el separador de directorios, devuelve "".

  • System.IO.Path.GetFileNameWithoutExtension("C:\Directorio1\prueba.xml") : Idem que GetFileName() pero sin extensión. En el ejemplo "prueba"

  • System.IO.Path.GetFullPath("C:") Devuelve la ruta actual sobre la unidad C: Por ejemplo "C:\miApp\bin\Debug

  • System.IO.Path.GetFullPath("\prueba1") : Devuelve la ruta absoluta, toma en cuenta la unidad actual o la ruta actual.

  • System.IO.Path.GetInvalidFileNameChars() : Devuelve los caracteres que no pueden formar parte del nombre de un archivo

  • System.IO.Path.GetInvalidPathChars() : Devuleve los caracteres no válidos para una ruta.

  • System.IO.Path.GetPathRoot("C:\Directorio1\prueba.xml") : Devuelve la raíz de la ruta especificada, en este caso "C:\"

  • System.IO.Path.GetRandomFileName() : Devuelve un nombre randómico para usar como nombre de archivo o directorio.

  • System.IO.Path.GetTempFileName() : Devuelve un nombre de archivo temporal, apuntando al directorio especificado en %TEMP%. Por ejemplo "C:\Documents and settings\usuario\Configuración local\Temp\tmp131E.tmp"

  • System.IO.Path.GetTempPath() : Devuelve la ruta al directorio temporal, siguiendo con el ejemplo anterior, "C:\Documents and settings\usuario\Configuración local\Temp\"

  • System.IO.Path.HasExtension("C:\prueba.xml") : Devuelve un valor Boolean indicando si la ruta especificada contiene una extensión, en el ejemplo la extensión es ".xml" o sea que devuelve True

  • System.IO.Path.IsPathRooted("..\Directorio1\prueba.xml") : Devuelve un valor Boolean indicando si la ruta especificada es absoluta o no, en el ejemplo la ruta es relativa por lo que devuelve False

  • System.IO.Path.PathSeparator : Devuelve el separador de rutas, generalmente ";"

  • System.IO.Path.VolumeSeparatorChar : Devuelve el caracter separador de volúmenes, generalmente ":"


Estos son todos los miembors de la clase System.IO.Path con una breve descripción de cada uno.

6 feb 2009

Problema al crear un WebService: Failed to access IIS metabase - SOLUCIONADO

Intentando crear un WebService con C# me encontré con que cada vez que intentaba ejecutarlo IIS me devolvía el siguiente error: Failed to access IIS metabase problem.

Busqué por acá y por alla, descargué un código VBS pero nada... después de probar las mil y una soluciones encontré la solución definitiva, así que decidí publicarla aquí para tenerla siempre a mano y de paso le puede servir a alguien más.

La solución consiste en abrir una consola, ir al directorio de instalación del Framework, 2.0 en este caso y ejecutar un comando que hará una reinstalación de ASP.Net



C:\> cd WINDOWS\Microsoft.NET\Framework\v2.0.50727

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\> aspnet_regiis.exe -i

Start installing ASP.NET (2.0.50727).
......................
Finished installing ASP.NET (2.0.50727).

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\>