Pues eso… Si usas el texto copiado de Visual Studio para después mostrarlo coloreado en una publicación en la WEB (un blog, etc.) este truco que te explico aquí te será de gran ayuda, ya que le indica que a demás de colorear el código «normal» (instrucciones, comentarios y cadenas entrecomilladas) también copie el color de los tipos.
Esto lo utilizo con mi utilidad de colorear el código (gsColorearCodigo), concretamente usando la opción Colorear desde RTF del menú contextual de la caja de textos donde se pega el código a colorear.
Y ( lo que decía ese párrafo anterior 🙂 ) antes, al copiar texto del editor de Visual Studio, éste me contenía los colores de los tipos de datos (verde azulado), pero últimamente no lo hacía, así que… esta mañana me puse a ver las opciones del editor de textos (realmente buscando otra cosa, todo hay que decirlo) y me topé con una opción que no era muy aclaratorio de que podía ser eso lo que lo solucionara: Usar clasificación precisa. Pero al estar justo debajo de Copiar texto enriquecido al copiar o cortar, pues… ¡tuve que probarlo! 😉
Y eso es… aquí te dejo la nota «adicional» que puse en el post anterior en el que explico sobre la nueva versión de la utilidad de colorear código.
Nota adicional sobre el coloreado de Visual Studio
Comenté en el párrafo anterior que Visual Studio no pasa los colores de las clases (verde azulado) y antes lo hacía. ¿Lo habrán quitado?
No, no lo han quitado.
Y es que el que lo haga o no depende de una opción en la configuración del editor de textos de Visual Studio.
Esa opción en español es: Usar clasificación precisa. En inglés es: Use accurate classification.
Y con esos nombres… ¿Quién lo iba a saber?
Para poder cambiar (activar) esa opción lo tienes que hacer en: (ver la captura) Herramientas>Opciones>Editor de textos>Avanzadas En inglés sería: Tools>Options>Text editor>Advanced
Opción para que al copiar el código en Visual Studio coloree también las definiciones de los tipos
Fíjate que también tiene que estar seleccionada la opción Copiar texto enriquecido al copiar o cortar (Copy rich text on copy/cut).
Al pegar el texto coloreado, quedaría así:
'''<summary>
''' Devuelve la versión de la DLL.
''' Si completa es True, se devuelve también el nombre de la DLL:
''' gsColorear v 1.0.7.0 (para .NET Framework 4.7.2 revisión del dd/MMM/yyyy)
'''</summary>
PublicSharedFunction Version(Optional completa AsBoolean = False) AsString
Dim res = ""
Dim ensamblado = System.Reflection.Assembly.GetExecutingAssembly
'Dim m_fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(ensamblado.Location)
'res = $"v {m_fvi.FileVersion}"
Dim versionAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyVersionAttribute), False)
'DirectCast(DirectCast(versionAttr, System.Reflection.AssemblyVersionAttribute())(0), System.Reflection.AssemblyVersionAt
Dim vers = If(versionAttr.Length > 0, (TryCast(versionAttr(0), System.Reflection.AssemblyVersionAttribute)).Version,
"1.0.7.0")
Dim fileVerAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyFileVersionAttribute), False)
Dim versF = If(fileVerAttr.Length > 0, (TryCast(fileVerAttr(0), System.Reflection.AssemblyFileVersionAttribute)).Version,
"1.0.7.1")
res = $"v {vers} ({versF})"
If completa Then
Dim prodAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyProductAttribute), False)
Dim producto = If(prodAttr.Length > 0, (TryCast(prodAttr(0), System.Reflection.AssemblyProductAttribute)).Product,
"gsColorear")
res = $"{producto}{res} (para .NET Framework 4.7.2 revisión del 09/Sep/2020)"
EndIf
Return res
EndFunction
Pues eso… si eres de los que no entran habitualmente en el sitio del Guille (www.elguille.info) y prefieres ver las cosas publicadas aquí en el blog, te diré que ayer publiqué la nueva versión de la utilidad gsColorearCodigo. Y digo NUEVA porque la actualización anterior que publiqué fue hace ya unos 13 añitos de nada 😉 y era para .NET 2.0, mientras que la nueva es para .NET Framework 4.8.
Para facilitar la «coloración» del código a publicar en la WEB esta nueva versión permite copiar el código de Visual Studio, pegarlo en la ventana de la utilidad y generar el código HTML a partir del contenido RTF (ver la figura 1).
Figura 1. La utilidad gsColorearCodigo usando Colorear desde RTF
Esto tiene dos ventajas, la primera es que no es necesario que la utilidad analice el código fuente buscando palabras clave y comentarios, etc. Ya que lo único que tiene que hacer es convertir el código interno del formato RTF y convertirlo en etiquetas span.
Además que al hacerlo así se gana tiempo… te lo digo por experiencia, ya que prácticamente todo el código coloreado que publico desde hace 12 o 13 años lo hago usando esa opción… así que… ya sabes… 😉
Y para muestra, un código coloreado, precisamente el que usé para hacer la captura de la figura 1.
Te lo vuelvo a mostrar en la captura de la figura 2, que es el editor de Visual Studio 2019.
Figura 2. El código a copiar del editor de Visual Studio 2019
Y este es el código HTML generado :
'''<summary>
''' Devuelve la versión de la DLL.
''' Si completa es True, se devuelve también el nombre de la DLL:
''' gsColorear v 1.0.7.0 (para .NET Framework 4.7.2 revisión del dd/MMM/yyyy)
'''</summary>
PublicSharedFunction Version(Optional completa AsBoolean = False) AsString
Dim res = ""
Dim ensamblado = System.Reflection.Assembly.GetExecutingAssembly
'Dim m_fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(ensamblado.Location)
'res = $"v {m_fvi.FileVersion}"
Dim versionAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyVersionAttribute), False)
'DirectCast(DirectCast(versionAttr, System.Reflection.AssemblyVersionAttribute())(0), System.Reflection.AssemblyVersionAt
Dim vers = If(versionAttr.Length > 0, (TryCast(versionAttr(0), System.Reflection.AssemblyVersionAttribute)).Version,
"1.0.7.0")
Dim fileVerAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyFileVersionAttribute), False)
Dim versF = If(fileVerAttr.Length > 0, (TryCast(fileVerAttr(0), System.Reflection.AssemblyFileVersionAttribute)).Version,
"1.0.7.1")
res = $"v {vers} ({versF})"
If completa Then
Dim prodAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyProductAttribute), False)
Dim producto = If(prodAttr.Length > 0, (TryCast(prodAttr(0), System.Reflection.AssemblyProductAttribute)).Product,
"gsColorear")
res = $"{producto}{res} (para .NET Framework 4.7.2 revisión del 09/Sep/2020)"
EndIf
Return res
EndFunction
En este caso, el VS no ha pasado los colores de los tipos (verde azulado), pero en otras ocasiones sí que lo hacía y quedaba guay, pero últimamente no le pasa los datos del color al código que utiliza de RTF… en fin…
Nota adicional sobre el coloreado de Visual Studio
Comenté en el párrafo anterior que Visual Studio no pasa los colores de las clases (verde azulado) y antes lo hacía. ¿Lo habrán quitado?
No, no lo han quitado.
Y es que el que lo haga o no depende de una opción en la configuración del editor de textos de Visual Studio.
Esa opción en español es: Usar clasificación precisa. En inglés es: Use accurate classification.
Y con esos nombres… ¿Quién lo iba a saber?
Para poder cambiar (activar) esa opción lo tienes que hacer en: (ver la captura) Herramientas>Opciones>Editor de textos>Avanzadas En inglés sería: Tools>Options>Text editor>Advanced
Opción para que al copiar el código en Visual Studio coloree también las definiciones de los tipos
Fíjate que también tiene que estar seleccionada la opción Copiar texto enriquecido al copiar o cortar (Copy rich text on copy/cut).
Al pegar el texto coloreado, quedaría así:
'''<summary>
''' Devuelve la versión de la DLL.
''' Si completa es True, se devuelve también el nombre de la DLL:
''' gsColorear v 1.0.7.0 (para .NET Framework 4.7.2 revisión del dd/MMM/yyyy)
'''</summary>
PublicSharedFunction Version(Optional completa AsBoolean = False) AsString
Dim res = ""
Dim ensamblado = System.Reflection.Assembly.GetExecutingAssembly
'Dim m_fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(ensamblado.Location)
'res = $"v {m_fvi.FileVersion}"
Dim versionAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyVersionAttribute), False)
'DirectCast(DirectCast(versionAttr, System.Reflection.AssemblyVersionAttribute())(0), System.Reflection.AssemblyVersionAt
Dim vers = If(versionAttr.Length > 0, (TryCast(versionAttr(0), System.Reflection.AssemblyVersionAttribute)).Version,
"1.0.7.0")
Dim fileVerAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyFileVersionAttribute), False)
Dim versF = If(fileVerAttr.Length > 0, (TryCast(fileVerAttr(0), System.Reflection.AssemblyFileVersionAttribute)).Version,
"1.0.7.1")
res = $"v {vers} ({versF})"
If completa Then
Dim prodAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyProductAttribute), False)
Dim producto = If(prodAttr.Length > 0, (TryCast(prodAttr(0), System.Reflection.AssemblyProductAttribute)).Product,
"gsColorear")
res = $"{producto}{res} (para .NET Framework 4.7.2 revisión del 09/Sep/2020)"
EndIf
Return res
EndFunction
Lo que si hace es usar la coloración de las cadenas con los argumentos de las cadenas interpoladas (las que se usan poniendo un signo dólar delante del inicio de las comillas dobles) que utiliza la coloración de Visual Studio, mientras que si lo haces con el comando Colorear en HTML, todo el contenido de la cadena estaría de color rojo, tal como puedes ver a continuación.
res = $"{producto} {res} (para .NET Framework 4.7.2 revisión del 09/Sep/2020)"EndIfReturn res
EndFunction
Aunque con la utilidad puedes configurar los colores y usar Colorear en HTML y mostrar el código con el look ese que tanto le gusta a «los otros» 😉
''' <summary>''' Devuelve la versión de la DLL.''' Si completa es True, se devuelve también el nombre de la DLL:''' gsColorear v 1.0.7.0 (para .NET Framework 4.7.2 revisión del dd/MMM/yyyy)''' </summary>PublicSharedFunction Version(Optional completa AsBoolean = False) AsStringDim res = ""
Dim ensamblado = System.Reflection.Assembly.GetExecutingAssembly
'Dim m_fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(ensamblado.Location)'res = $"v {m_fvi.FileVersion}"Dim versionAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyVersionAttribute), False)
'DirectCast(DirectCast(versionAttr, System.Reflection.AssemblyVersionAttribute())(0), System.Reflection.AssemblyVersionAtDim vers = If(versionAttr.Length > 0, (TryCast(versionAttr(0), System.Reflection.AssemblyVersionAttribute)).Version,
"1.0.7.0")
Dim fileVerAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyFileVersionAttribute), False)
Dim versF = If(fileVerAttr.Length > 0, (TryCast(fileVerAttr(0), System.Reflection.AssemblyFileVersionAttribute)).Version,
"1.0.7.1")
res = $"v {vers} ({versF})"If completa ThenDim prodAttr = ensamblado.GetCustomAttributes(GetType(System.Reflection.AssemblyProductAttribute), False)
Dim producto = If(prodAttr.Length > 0, (TryCast(prodAttr(0), System.Reflection.AssemblyProductAttribute)).Product,
"gsColorear")
res = $"{producto} {res} (para .NET Framework 4.7.2 revisión del 09/Sep/2020)"EndIfReturn res
EndFunction
Por si te interesa, aquí tienes los colores a usar y el valor de «pre» para conseguir ese coloreado del código:
Tag del formato <pre>: <pre style=»background-color:black; color:#dcdcdc»> Color texto: d69d85 Color comentario: 57a64a Color documentación (XML): 57a64a Color instrucciones: 569cd6
Bueno, no te canso más… espero que te sea de utilidad y la uses si necesitas colorear código para publicar en una sitio web.
El código fuente y el instalador de ClickOnce lo encontrarás en la página que publiqué en elGuille.info.
P.S. Ahora que veo el código publicado… no queda mal el fondo negro con el resto de colores… lo mismo modifico la utilidad de colorear para que al colorear desde RTF utilice esos colores en vez de los «predeterminados», que yo creo que son los que recoge del código RTF de Visual Studio, pero lo mismo es fácil de cambiarlos. Si lo logro, ya te enterarás con una nueva actualización 😉
Pues eso… usando la aplicación que te mostré el otro día (Compilar y ejecutar versión para .NET Core (.NET 5.0)) y después de hacer varias pruebas con otra DLL que compila el código y lo ejecuta sin usar Process.Start, al menos si es una aplicación de consola, (ya que para ejecutar las de Windows Forms, al menos hasta lo que yo he probado, solo puedo lanzarla usando Process.Start); al final me he quedado con la llamada a dotnet para crear el proyecto, compilarlo y ejecutar el código compilado.
Nota: Abajo te dejo un ZIP con el código fuente del proyecto (Compilar y ejecutar) y la utilidad para colorear (gsColorearCore). En la carpeta pruebas del proyecto está el código fuente (de VB y C#) de la aplicación de ejemplo.
Compilar con dotnet (desde la línea de comandos)
En las primeras pruebas (las del código que te puse en el post arriba mencionado, usaba aplicaciones de consola, más que nada porque así se lo decía al usar el comando:
dotnet new console -o "AppDir" -lang c#|vb
Ese código lo que hace es crear una aplicación de consola en el directorio indicado por AppDir (si ya existe, podemos añadir –force al final para que genere el contenido aunque sobreesciba lo que ya hubiese.).
Para crear/compilar una aplicación para Windows Forms tendremos que usar una línea de comandos parecida a la anterior, pero indicando winforms en vez de console. En el siguiente código creamos una aplicación de .NET 5.0 Core usando Visual Basic en el directorio E:\Guille\source\repos\MiAppWinF.
Nota: Si no tienes instalado el .NET 5.0 y tienes al menos el .NET Core 3.0 o 3.1 simplemente usa el lenguaje C# en lugar de Visual Basic, ya que en esas versiones anteriores al 5.0 solo se permiten aplicaciones de Windows Forms o WPF para C#.
dotnet new winforms -o "E:\Guille\source\repos\MiAppWinF" -lang vb
Nota: En realidad poner el directorio entre comillas dobles no es necesario, salvo que se utilice el comando dotnet build.
Una vez hecho esto, solo tendremos que modificar el código generado y si queremos que se ejecute el contenido de ese directorio podemos usa la siguiente línea de comandos:
dotnet run -p E:\Guille\source\repos\MiAppWinF
El código usado en la aplicación Compilar y ejecutar NETCore
En el código de la aplicación compilar y ejecutar para .NET Core 5.0 este último paso me lo salto y lo que hago es crear la aplicación (con –force) sustituyo el código. ya que –force o simplemente al crear con new se generan los ficheros en blanco (sin el código que ya tuviera). En su lugar utilizo build para compilar el código. Es decir, creo la aplicación con new (uso –force por si ya existiera), guardo el código fuente del editor del programa, lo compilo con build y finalmente lo ejecuto usando Process.Start.
El comando build usado es el siguiente:
dotnet build "E:\Guille\source\repos\MiAppWinF"
Las comillas dobles solo son necesarias si el path o el nombre del proyecto contiene espacios.
Y ese comando habrá creado un ejecutable (aparte de la DLL que siempre genera .NET Core) en el directorio: E:\Guille\source\repos\MiAppWinF\bin\Debug\net5.0-windows cuyo nombre será MiAppWinF.exe Fíjate que al ser una aplicación para Windows (las aplicaciones de Windows Forms y las de WPF solo se pueden usar en plataformas Windows, es decir, no se pueden usar ni en Linux ni en MacOS) se crea en un directorio aparte de las aplicaciones de consola, que sería en: bin\Debug\net5.0\
Nota: El directorio de salida puede ser diferente si antes de build (y después de new) cambias la configuración del proyecto.
Un poco de código fuente por favor
El código del método compilar al que se le pasa el código a compilar/ejecutar.
'''<summary>
''' Compilar el código indicado en el parámetro.
'''''' Usando dotnet (.NET Core) se hará lo siguiente:
''' Definir un directorio para VB o C#: MiApp_VB o MiApp_CS
''' Usar el comando:
''' dotnet new console -o dir -lang C#|VB --force
''' Copiar en ese directorio el fichero como Program.vb o .cs
''' Usar el comando (y redirigir la salida):
''' dotnet run -p dir
'''</summary>
PrivateSub compilar(texto AsString, mostrarSoloSalida AsBoolean)
' Compilar usando la línea de comandos
Dim ext = If(optCS.IsChecked, "cs", "vb")
Dim appDir = System.IO.Path.Combine(System.Environment.CurrentDirectory,
$"MiApp_{ext}")
' crear un fichero temporal para compilar
Dim ficProgram = Path.Combine(appDir, $"Program.{ext}")
Dim dotnet = "dotnet"
Dim args = "--version"
txtSalida.Text = $"{dotnet}{args} = {ejecutar(dotnet, args, waitSecs:=5000)}"
' Considero que es aplicación de Windows Forms (07/Sep/20)
' si contiene InitializeComponent
Dim esWF = texto.IndexOf("InitializeComponent()") > -1
If esWF Then
args = $"new winforms -o ""{appDir}"" -lang {If(optCS.IsChecked, "c#", "vb")} --force"
Else
args = $"new console -o ""{appDir}"" -lang {If(optCS.IsChecked, "c#", "vb")} --force"
EndIf
If mostrarSoloSalida Then
ejecutar(dotnet, args, waitSecs:=10000)
Else
txtSalida.Text &= $"{vbCrLf}{vbCrLf}{ejecutar(dotnet, args, waitSecs:=10000)}"
EndIf
' Eliminar todos los ficheros del lenguaje
' (solo quedará el que se guarde)
Dim files = Directory.GetFiles(appDir, $"*.{ext}")
For i = 0 To files.Length - 1
File.Delete(files(i))
Next
' Guardar el código a compilar
Using sw AsNew System.IO.StreamWriter(ficProgram,
False,
System.Text.Encoding.UTF8)
sw.Write(texto)
EndUsing
args = $"build ""{appDir}"""
If mostrarSoloSalida Then
Dim res = ejecutar(dotnet, args, waitSecs:=10000)
Dim hayErrorComp = False
If optVB.IsChecked Then
If res.Contains("error BC") Then
hayErrorComp = True
EndIf
Else
If res.Contains("error CS") Then
hayErrorComp = True
EndIf
EndIf
If hayErrorComp Then
txtSalida.Text &= vbCrLf & res
txtSalida.Text &= $"{vbCrLf}--- FIN DE LA COMPILACIÓN CON ERRORES ---"
Return
EndIf
'txtSalida.Text &= $"{vbCrLf}{vbCrLf}{res}"
Else
txtSalida.Text &= $"{vbCrLf}{vbCrLf}{ejecutar(dotnet, args, waitSecs:=10000)}"
EndIf
Dim exe = System.IO.Path.Combine(appDir, $"bin\Debug\net5.0\MiApp_{ext}.exe")
' Si es aplicación de Windows Forms, usa otro directorio (07/Sep/20)
If esWF Then
'net5.0-windows
exe = System.IO.Path.Combine(appDir, $"bin\Debug\net5.0-windows\MiApp_{ext}.exe")
txtSalida.Text &= $"{vbCrLf}{vbCrLf}Aplicación de Windows"
EndIf
txtSalida.Text &= $"{vbCrLf}{vbCrLf}{ejecutar(exe, esWinF:=esWF)}"
txtSalida.Text &= $"{vbCrLf}--- FIN DE LA COMPILACIÓN ---"
txtSalida.SelectionStart = txtSalida.Text.Length
txtSalida.SelectionLength = 0
EndSub
Del método ejecutar tengo dos versiones, la primera es la que uso para llamar al dotnet y en el que redirijo la salida de la consola para capturarla y mostrarla en la caja de textos txtSalida. Al primero le paso el nombre de la aplicación a ejecutar (dotnet) y los argumentos. Al segundo le paso el nombre del ejecutable y si es o no aplicación de Windows, en cuyo caso se usa ShellExecute y el estilo de la ventana es normal, aparte de no usar Kill para que no se cierre la aplicación al poco de haberse abierto 🙂
PrivateFunction ejecutar(exe AsString, arg AsString,
Optional conKill AsBoolean = False,
Optional waitSecs AsInteger = 10000) AsString
Dim res = ""
Using p AsNew Process
p.StartInfo.FileName = exe
p.StartInfo.Arguments = arg
' Indicamos que queremos redirigir la salida
p.StartInfo.RedirectStandardOutput = True
' Para redirigir la salida, UseShellExecute debe ser falso
p.StartInfo.UseShellExecute = False
p.StartInfo.CreateNoWindow = True
Try
' Iniciamos el proceso
p.Start()
' Esperar a que el proceso finalice
'
' Esperamos waitSecs segundos para que le de tiempo a ejecutarse
' como mínimo esperar 2000 (o 5000 si se usa dotnet)
If waitSecs < 2000 Then waitSecs = 2000
p.WaitForExit(waitSecs)
If conKill Then
p.Kill()
EndIf
res = p.StandardOutput.ReadToEnd()
Catch ex As Exception
res = ex.Message
EndTry
EndUsing
Return res
EndFunction
'''<summary>
''' Ejecutar el código y mostrarlo en la ventana de salida.
'''</summary>
PrivateFunction ejecutar(exe AsString,
Optional waitSecs AsInteger = 2000,
Optional esWinF AsBoolean = False) AsString
Dim p AsNew Process
p.StartInfo.FileName = exe
If esWinF Then
With p.StartInfo
.UseShellExecute = True
.WindowStyle = ProcessWindowStyle.Normal
EndWith
' Iniciamos el proceso
p.Start()
' Esperar a que el proceso finalice
'
' Esperamos 2 segundos para que le de tiempo a ejecutarse
' Como mínimo 2 segundos
If waitSecs < 2000 Then waitSecs = 2000
p.WaitForExit(waitSecs)
Return""
EndIf
' Indicamos que queremos redirigir la salida
p.StartInfo.RedirectStandardOutput = True
' Para redirigir la salida, UseShellExecute debe ser falso
p.StartInfo.UseShellExecute = False
' No usar esto
' salvo que se use p.Kill()
p.StartInfo.CreateNoWindow = True
' Iniciamos el proceso
p.Start()
' Esperar a que el proceso finalice
'
' Esperamos 2 segundos para que le de tiempo a ejecutarse
' Como mínimo 2 segundos
If waitSecs < 2000 Then waitSecs = 2000
p.WaitForExit(waitSecs)
Try
p.Kill()
Catch ex As Exception
Debug.WriteLine(ex.Message)
EndTry
' Convertir la salida usando el código de página 437
' que es la usada en MS-DOS (línea de comandos)
Dim res = p.StandardOutput.ReadToEnd()
Return res
EndFunction
Recomendación para usar código de Windows Forms en la utilidad de Compilar y ejecutar
Por último, comentarte que si quieres compilar una app para Windows Forms desde la utilidad de compilar y ejecutar, el código de esa aplicación debe estar en un solo fichero, en el que te recomiendo que incluyas el método Main, la definición del diseñador de Windows Forms y el código que realmente quieres usar. Esto es así porque el programa/utilidad no está preparado para usar múltiples ficheros.
Te muestro a continuación cómo sería ese código para Visual Basic y para C# y una captura de la salida realizada al compilar desde la utilidad.
Este es el código de Visual Basic del formulario de pruebas.
Imports System
Imports System.Windows.Forms
'' El punto de entrada del programa'FriendModuleProgram
<STAThread()>
FriendSub Main(args AsString())
Application.SetHighDpiMode(HighDpiMode.SystemAware)
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1)
EndSubEndModule'' El diseñador del formulario'
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
PartialClassForm1Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
ProtectedOverridesSub Dispose(ByVal disposing AsBoolean)
TryIf disposing AndAlso components IsNotNothingThen
components.Dispose()
EndIfFinallyMyBase.Dispose(disposing)
EndTryEndSub'Required by the Windows Form DesignerPrivate components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
PrivateSub InitializeComponent()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.Button1 = New System.Windows.Forms.Button()
Me.Label1 = New System.Windows.Forms.Label()
Me.Button2 = New System.Windows.Forms.Button()
Me.SuspendLayout()
''TextBox1'Me.TextBox1.Location = New System.Drawing.Point(12, 12)
Me.TextBox1.Name = "TextBox1"Me.TextBox1.Size = New System.Drawing.Size(182, 23)
Me.TextBox1.TabIndex = 0
''Button1'Me.Button1.Location = New System.Drawing.Point(200, 11)
Me.Button1.Name = "Button1"Me.Button1.Size = New System.Drawing.Size(75, 23)
Me.Button1.TabIndex = 1
Me.Button1.Text = "Button1"Me.Button1.UseVisualStyleBackColor = True''Label1'Me.Label1.Location = New System.Drawing.Point(12, 38)
Me.Label1.Name = "Label1"Me.Label1.Size = New System.Drawing.Size(263, 23)
Me.Label1.TabIndex = 2
Me.Label1.Text = "Label1"''Button2'Me.Button2.Location = New System.Drawing.Point(200, 90)
Me.Button2.Name = "Button2"Me.Button2.Size = New System.Drawing.Size(75, 23)
Me.Button2.TabIndex = 3
Me.Button2.Text = "Cerrar"Me.Button2.UseVisualStyleBackColor = True''Form1'Me.AcceptButton = Me.Button1
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 15.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.CancelButton = Me.Button2
Me.ClientSize = New System.Drawing.Size(287, 125)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.TextBox1)
Me.Name = "Form1"Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "Form1"Me.ResumeLayout(False)
Me.PerformLayout()
EndSubFriendWithEvents TextBox1 As TextBox
FriendWithEvents Button1 As Button
Friend Label1 As Label
Friend Button2 As Button
EndClass'' El código del formulario'PublicClassForm1PrivateSub Form1_Load(sender AsObject, e As EventArgs) HandlesMyBase.Load
TextBox1.Text = "<tu nombre>"'AddHandler Button2.Click, AddressOf Button2_ClickAddHandler Button2.Click, Sub() Me.Close()
EndSubPrivateSub Button1_Click(sender AsObject, e As EventArgs) Handles Button1.Click
Dim str = TextBox1.Text
If str = "<tu nombre>"Then
str = " amigo"EndIf
Label1.Text = $"¡Hola {ToUpperFirst(str)}!"EndSub'''<summary>''' Convierte en mayúsculas el primer carácter de la cadena indicada.'''</summary>PrivateFunction ToUpperFirst(str AsString) AsString'Return str(0).ToString().ToUpper() & str.Substring(1)if str=""then str=" amigo"Return str(0).ToString.ToUpper & str.Substring(1)
EndFunction'Private Sub Button2_Click(sender As Object, e As EventArgs)' Me.Close()'End SubEndClass
Este es el código de C# del formulario de pruebas.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
//// El punto de entrada del programa//staticclassProgram
{
///<summary>/// The main entry point for the application.///</summary>
[STAThread]
staticvoid Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
//// El diseñador del formulario//partialclassForm1
{
///<summary>/// Required designer variable.///</summary>private System.ComponentModel.IContainer components = null;
///<summary>/// Clean up any resources being used.///</summary>///<param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protectedoverridevoid Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///<summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor.///</summary>privatevoid InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
// // textBox1// this.textBox1.Location = new System.Drawing.Point(12, 12);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(182, 23);
this.textBox1.TabIndex = 0;
// // button1// this.button1.Location = new System.Drawing.Point(200, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
// // label1// this.label1.Location = new System.Drawing.Point(12, 38);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(263, 23);
this.label1.TabIndex = 2;
this.label1.Text = "label1";
// // button2// this.button2.Location = new System.Drawing.Point(200, 90);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 3;
this.button2.Text = "Cerrar";
this.button2.UseVisualStyleBackColor = true;
//this.button2.Click += new System.EventHandler(this.button1_Click);// // Form1// this.AcceptButton = this.button1;
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.button2;
this.ClientSize = new System.Drawing.Size(287, 125);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button2);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregionprivate System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button2;
}
//// El código del formulario//publicpartialclassForm1 : Form
{
publicForm1()
{
InitializeComponent();
}
privatevoid Form1_Load(object sender, EventArgs e)
{
textBox1.Text = "<tu nombre>";
//button2.Click += => (object o, EventArgs e) this.Close();//button2.Click += delegate (object sender, EventArgs e) { this.Close(); };
button2.Click += (sender, e) => { this.Close(); };
}
privatevoid button1_Click(object sender, EventArgs e)
{
//label1.Text = $"Hola {ToUpperFirst(textBox1.Text)}!";var str = textBox1.Text;
if( str == "<tu nombre>" ) str = " amigo";
label1.Text = $"Hola {ToUpperFirst(str)}!";
}
///<summary>/// Convierte en mayúsculas el primer carácter de la cadena indicada.///</summary>privatestring ToUpperFirst(string str)
{
if(str=="") str = " amigo";
return str[0].ToString().ToUpper() + str.Substring(1);
}
}
Esta es la salida del código ejecutándose con la utilidad de compilar y ejecutar para NETCore.
Figura 1. El resultado de compilar y ejecutar una aplicación de Windows Forms para .NET Core 5.0.
Y esto es todo… tengo algo más por ahí, para seguir con la compilación y ejecución del código para .NET Core, pero eso será para otra ocasión 🙂
Espero que te haya sido de utilidad… Esa es la idea y ¡eso espero! 🙂