lunes, 1 de diciembre de 2008

Convertir un campo público a propiedad Visual Studio - VB y C#

Cómo hacer para convertir automáticamente un campo (variable) a una propiedad pública y utilizarlo con una combinación de teclas en el Visual Studio 2008.

La idea es crear una macro que se encargue de hacer la conversión de la línea actual de código donde estemos parados y poder ejecutar esta macro con alguna combinación de teclas.

Por ejemplo, queremos convertir esta línea:
Public id As Integer

En esto:
Private _id As Integer
Public Property id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
NOTA: En Visual Studio 2010 será mucho más simple la declaración de propiedades en VB, pareciéndose más a la declaración en C#

Lo primero que se necesita es abrir el explorador de macros (Menú View, Other Windows, Macro Explorer) o bien con ALT+F8.
En la nueva ventana, hacer click derecho en MyMacros y seleccionar "New Module", ponerle como nombre thepirat, y nuevamente click derecho (ahora sobre el nuevo módulo recién creado) y seleccionar "New Macro".
A continuación aparecerá el editor de macros y estaremos situados dentro de un método que seguramente se llama Sub Macro1() adentro del módulo llamado thepirat.

Adentro de este módulo, copiar y reemplazar TODO el código por el siguiente código
 

'The-Pirat 2008
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.Text.RegularExpressions

'http://msdn.microsoft.com/en-us/library/envdte.textselection_members.aspx

Public Module thepirat
'Declaro la expresión regular
Private Const REGEX_Declaracion_VB As String = _
"(public|private|dim)\s+(?'var'\w+)\s+as\s+(?'tipo'.*)"
Private Const REGEX_Declaracion_CSHARP As String = _
"(public\s|private\s|internal\s)?(?'tipo'.+)\s+(?'var'\w+)\s*;"

''' <summary>
''' Convierte un campo en propiedad pública.
''' Acepta la forma: Dim variable as tipo, public v as t, private v as t
''' </summary>
''' <remarks></remarks>
Public Sub campo2prop()
'Creo un punto de UNDO
DTE.UndoContext.Open("UndoCampoPropiedad")
Try
'Obtengo el documento activo
Dim doc = CType(DTE.ActiveDocument, EnvDTE.Document)
'Obtengo la selección del documento activo
Dim ts As TextSelection = doc.Selection
'Selecciono la línea completa
ts.SelectLine()
'Determino si es VB o C#
Dim bVB As Boolean = EsVisualBasic(doc.Name)
'Obtengo el texto de la selección (la línea)
Dim sLinea As String = ts.Text.Trim()
'Obtengo el nombre de la variable y su tipo
Dim sVar As String = "", sTipo As String = ""
ObtenerVariableYtipo(bVB, sLinea, sVar, sTipo)
'Si fue exitoso, imprimo la propiedad
ts.Insert(DevolverPropiedad(bVB, sVar, sTipo))
Catch ex As Exception
MsgBox(ex.Message)
Finally
'Cierro el punto de UNDO
DTE.UndoContext.Close()
End Try
End Sub

'Determina si es VB o C#
Private Function EsVisualBasic(ByVal nombre As String) As Boolean
If (nombre.EndsWith(".cs") Or nombre.EndsWith(".cpp") Or nombre.EndsWith(".h") Or nombre.EndsWith(".idl") Or nombre.EndsWith(".jsl")) Then
Return False
ElseIf (nombre.EndsWith(".vb")) Then
Return True
Else
Throw New Exception("Tipo de archivo irreconocible")
End If
End Function

'Devuelve el nombre de la variable y el nombre del tipo de la variable a partir de la línea de declaración
Private Sub ObtenerVariableYtipo(ByVal VisualBasic As Boolean, ByVal Linea As String, _
ByRef var As String, ByRef tipo As String)
var = ""
tipo = ""
'Obtengo el nombre de la variable y su tipo
Dim mc = Regex.Matches(Linea.Trim, If(VisualBasic, REGEX_Declaracion_VB, REGEX_Declaracion_CSHARP), _
RegexOptions.IgnoreCase Or RegexOptions.Singleline)

If mc.Count = 0 Then
Throw New Exception("La línea actual no es la declaración de una variable")
End If

For Each m As Match In mc
var = m.Groups("var").ToString
tipo = m.Groups("tipo").ToString
Next
End Sub

'Devuelve el texto convertido a propiedad
Private Function DevolverPropiedad(ByVal VisualBasic As Boolean, _
ByRef var As String, ByRef tipo As String) As String
If VisualBasic Then
Return (String.Format( _
"Private _{1} As {2}{3}" & _
"Public Property {1}() As {2}{3}" & _
"{0}Get{3}" & _
"{0}{0}Return _{1}{3}" & _
"{0}End Get{3}" & _
"{0}Set(ByVal value As {2}){3}" & _
"{0}{0}_{1} = value{3}" & _
"{0}End Set{3}" & _
"End Property{3}", _
vbTab, var, tipo, vbCrLf))
Else
Return (String.Format( _
"{0}{0}public {1} {2} {{ get; set; }}", vbTab, tipo, var))
End If
End Function

End Module
A continuación guardar y cerrar la ventana del editor de macros.

Ahora ya existe el método thepirat.campo2prop que a partir de la línea actual del editor del Visual Studio, convierte la declaración de un campo a una declaración de una propiedad con el mismo nombre.



Sólo falta vincular un acceso directo para poder utilizar la macro con una combinación de teclas.

Para esto, ir al menú Tools, Customize y luego click en el botón Keyboard... Buscar el método campo2prop como se muestra a continuación:


Presionar la combinación de teclas deseada en la parte indicada y luego darle click en Assign

Listo! Ahora desde cualquier ventana del editor de Visual Studio, se puede hacer esto:

Me paro en la línea de la declaración de un campo:


Presiono mi combinación de teclas y obtengo:



lunes, 20 de octubre de 2008

Cómo sugerir texto a partir de lo capturado, al estilo de Google en VB.NET

Esta función toma como parámetro un texto, por ejemplo "isaac new" y devuelve una lista con posibles coincidencias, por ejemplo "Isaac Newell" e "Isaac Newton", etc...

Util para sugerir texto en búsquedas.


Aquí está el código para VB.NET:
Imports System.Xml

Public Class google

Public Shared Function getList(ByVal prefixText As String) As String()

Dim doc As New XmlDocument()

Dim suggArList As List(Of String) = New List(Of String)()

Dim url As String = "http://google.com/complete/search?output=toolbar&q=" & prefixText

doc.Load(url)

For Each node As XmlNode In doc.SelectNodes("//CompleteSuggestion")

Dim value As String = node.SelectSingleNode("suggestion/@data").InnerText

suggArList.Add(value)

Next

Return suggArList.ToArray()

End Function

End Class

martes, 5 de agosto de 2008

Cómo cambiar el comportamiento por defecto al pulsar CTRL+ENTER en el Internet Explorer

Al pulsar CTRL+ENTER en la barra de direcciones del IE, éste automáticamente completa el texto escrito con el prefijo "http://www." y el postfijo ".com".

Por ejemplo si ponemos yahoo y luego CTRL+ENTER, el IE irá a la página "http://www.yahoo.com" automáticamente.

Si se requiere cambiar este comportamiento, por ejemplo, que el postfijo sea ".com.ar" en vez de ".com", hay que crear una carpeta y una clave en el registro de windows.

Desde el regedit.exe acceder a la ruta
"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar"
Ahi dentro crear una carpeta que se llame "QuickComplete"
Y dentro de esa carpeta crear una clave de tipo string (REG_SZ) con nombre "QuickComplete", cuyo contenido sea, por ejemplo:
"http://www.%s.com.ar" (sin las comillas)

En definitiva, la ruta completa de la clave a agregar es:
"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar\QuickComplete\QuickComplete"

Notar que el wildcard %s será reemplazado con el texto que contenga la barra de exploración

lunes, 14 de julio de 2008

Efectuar un CVS update desatentido disparado desde SQL Server

El requerimiento:
Hacer un update de un repositorio de CVS utilizando el protocolo pserver con usuario y constreñas conocidas.
Es necesario que el update se pueda efectuar "desatendidamente" desde un procedimiento de SQL Server 2000/2005/2008

El problema:
Al hacer el login al CVS, la constraseña del pserver es guardada en algún lugar del registro asociado con la sesión de usuario, así que si se dispara el update desde otra sesión o desde otro usuario (por ejemplo desde un job de SQL Server) surge el problema de que la contraseña no queda guardada y el update no puede ser efectuado.
Aunque se cree la credencial y el proxy adecuado en SQL, el problema sigue existiendo.

La solución:
Efectuar el checkout del módulo localmente.
Crear un archivo de texto plano que sólo contenga la contraseña del usuario del CVS y un archivo .bat que haga el login y el update.

El contenido de UpdateCVS.bat es el siguiente:


:Asigno el PATH a la carpeta que contiene el archivo CVS.exe
PATH = C:\Program Files\TortoiseCVS

:Voy a la carpeta que tiene el checkout
C:
CD \repositorio\Carpeta

:Seteo la configuracion del CVS
SET CVSROOT = :pserver:usuario@cvs.miempresa.com:2401/home/cvs

:Intruduzco el password redireccionando el stdin
:Es necesario que el password esté en el archivo c:\passw
cvs.exe login<c:\passw

:Disparo el Update
cvs.exe -q update -d -P


Dentro del .bat, el comando CVS Login preguntará la contraseña. Para que ésta sea introducirla automáticamente, se redirecciona el standard input al archivo que contiene la contraseña. Esto se hace con el caracter "<".
El archivo passw debe terminar con un retorno (enter).

Luego, para ejecutar el .bat desde T-SQL:
Exec xp_CMDShell 'UpdateCVS.bat'

Este exec puede ponerse dentro en un Job para automatizar completamente el proceso.

Datos personales