Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Eleкtro

#981
Scripting / Re: Batch
10 Mayo 2018, 23:32 PM
No merece la pena hacer esto en Batch, de hecho no merece la pena usar Batch para casi ninguna cosa, pero respondiendo a tu pregunta aquí tienes:

#982
Cita de: #!drvy en  9 Mayo 2018, 20:02 PM33 años después de ser creado

Qué bien. Solo faltan otros 33 años (número bastante Illuminati, por cierto) para que Microsoft abra los ojos y rectifique la horrible decisión de funcionalidad que tiene Notepad y todos sus productos (empezando por Windows, y seguido por Office) que usan atajos del teclado dependientes del idioma. Por ejemplo esto afecta al Notepad en Español al querer buscar texto usando la combinación de teclas más conocida o "universal": CTRL+F (de "Find"), que es lo más cómodo e intuitivo/familiar para todos, pero no, eso no podemos hacerlo por que en nuestro idioma el atajo es CTRL+B (de "Buscar")... con dos cojones. En serio, es un comportamiento tan asqueroso, poco universal, anti-intuitivo y antiproductivo...     lo odio.

#983
Es la primera vez que entro al foro de Piriform, que conste, pero a simple vista el servicio de soporte me parece una completa basura incompetente, ya que desde el día 23 de abril que fue cuando salió la v5.42 hasta el día de hoy, hay un montón de gente reportando el mismo problema:


...pero los de Piriform no aclaran ni resuelven nada (de hecho no tienen ni idea de cual es el problema, ellos mismos lo han dicho en uno de los posts de esos dos threads), solo se limitan a hacer comentarios absurdos y proponer soluciones estúpidas del tipo: "desactivar el AV", como si los usuarios fuesen burros informáticos con media neurona que no lo hubiesen probado ya con el AV desactivado...

en fin, solo era por comentarlo. :P un saludo.
#984
No es Skynet, pero poca broma con la nueva tecnología de inteligencia artificial de Google: Google Duplex capaz de realizar llamadas a hoteles, peluquerias, restaurantes y etc para pedir cita usando tu nombre, entre otras cosas...


No se hasta que punto la conversación que han mostrado será real, me refiero, la que coje el teléfono podría ser una actriz que además podría saber que palabras exactas debe usar para perfeccionar el tipo de respuestas y preguntas de la I.A, pero eso es lo de menos... lo importante aquí es que se trata de una especie de asistente personal en el móvil capaz de hacernos "recados" basados en voz (según estuve leyendo, el asistente de Google podía hacer tareas basadas en texto, pero creo que hasta ahora no podía usar una voz), como lo que pueden ver en el siguiente video, y es curioso que la conversación sea tan fluida y realista, es practicamente imposible sospechar ni distinguir en una conversación que se trata de una inteligencia artificial que usa una voz TTS...

[youtube=640,360]https://www.youtube.com/watch?v=pKVppdt_-B4[/youtube]

#985
Este tipo de temas son simplemente una verguenza. Para empezar, no puedes publicar un tema utilizando unas palabras tan genéricas como: "necesitaria con urgencia un 2048" que son de interpretación libre para mucha gente, sin tan siquiera pararte a explicar a lo que te refieres con eso de "2048", cosa que debería hacer cualquier persona simplemente por cuestión de respeto para no hacerle perder el tiempo a los usuarios interesados en leer tu tema y ayudarte, ni tampoco puedes pedir ni exigir que te hagan el juego de "2048" todito desde cero y te lo entreguen envuelto en papel de regalo y con un lazo. En el foro está prohibido pedir tareas, y también duplicar temas.

Por favor, lee las reglas del foro de programación antes de continuar publicando temas, y la próxima vez intenta seguir unas reglas de redacción que sean... mínimas.

Tema Cerrado.
#986
Casi siempre es en vano por más que lo intenten, cuando alguien viene pidiendo tareas... y no vuelve a aparecer por el foro.

Tema Cerrado.
#987
Cita de: NEBIRE en  9 Mayo 2018, 01:47 AMUna búsqeuda rápida me ofrece este pdf, que puede servirte... (no lo he descargado).
https://www.vmware.com/support/developer/vix-api/vix170_vmrun_command.pdf

Gracias @NEBIRE, pero te puedes imaginar que yo también estuve buscando y encontré el mismo PDF en Google :P, lamentablemente no me ayudó.

Gracias de nuevo.




TL;DR (Too Long; Didn't Don't Read):

Por cierto, quiero aclarar que no suelo apoyar nunca el hecho de depender en el uso de aplicaciones command-line, considero que el auténtico reto sería crear un wrapper de la librería nativa vix.dll en .NET, pero a ver quien tiene los c@jones de hacerlo... con la inmensa cantidad de miembros y funciones exportadas a implementar que tiene, y teniendo en cuenta que en cada release de VMWare modifican cosas y quedan algunos miembros obsoletos y otros nuevos, o que reemplacen la librería por una nueva donde la anterior queda completamente inservible (como sucedió con vixcom.dll). Sería un trabajo en vano, una absurda pérdida de tiempo.

Nah, mucho más viable, seguro y estable es recurrir al uso del programita/wrapper vmrun.exe, que aunque inevitablemente sea bastante más lento en términos de tiempo de ejecución (puesto que es un executable), al menos su estructura "no cambia" con el tiempo, por que ya se encargan los de VMWare de adaptar el programa para que funcione (obvio) con los nuevos cambios que introduzcan a la librería vix.dll, y nosotros como usuarios o programadores en el peor de los casos solo necesitariamos hacer un par de adaptaciones en la sintaxis de los argumentos a enviar a vmrun.exe y todo listo para funcionar con nuevas releases de VMWare.

Claro que, para los que puedan programar diréctamente en C/C++ ya sería otro cantar... aunque seguiría siendo bastante tedioso usar la librería (no hay más que mirar los samples de código que provee VMWare en el directorios de la API de VIX, 200 lineas de código solo para ejecutar una operación de encendido y/o apagado de la VM), pero bueno, programando en C/C++ supongo que sería más aceptable usar la librería vix.dll en lugar de usar vmrun.exe, supongo.

saludos!
#988
@AXCESS

Yo no estoy en contra de creencias como el ateismo, de hecho yo tengo mis propias creencias, y creo que (bueh, estoy completamente seguro) de que existe un "algo" indescriptible al que podemos referirnos como: El Creador de El Universo, el cual no se si tiene cuerpo o no, pero existe.

Pero si estoy totálmente en contra de creencias ocultistas y estúpidas como los males de ojo, gatos negros o espejos rotos, demonios, espíritus, posesiones infernales y etcétera, por que ese tipo de creencias son negativas y creo que eso no aporta ningún punto de vista beneficioso ni reflexión positiva para el creyente, a diferencia de otro tipo de creencias (ej. la reencarnación, la ley de atracción, y cosas así) que, ya sean ciertas o no (personálmente algunas creencias espirituales me resultan igual de estúpidas que creer en poder matar a alguien con la mente) al menos aportan algo positivo por que te ayudan a considerar la posibilidad de nuevas "verdades" a varios enigmas de La Vida y El Universo ofreciendo un punto de vista alternativo, y eso es experiencia que te sirve para mejorar como persona... pero creer en maldiciones o poder hacer el mal con la mente, creer en cosas negativas y dañinas... ya me dirás que le puede aportar eso a una persona, creer en ese tipo de cosas solo sirve para que la mente se evada de la realidad y busque respuestas en la mágia cuando le suceda algo bueno o algo malo... vamos, son creencias que vuelve tontas a las personas que creen.

Saludos
#989
¿Cómo interoperar entre el sistema operativo huésped de una máquina virtual de VMWare, y el sistema operativo anfitrión?.

Me encargaron un trabajo que consistia en diseñar una GUI para monitorizar máquinas virtuales de VMWare y realizar ciertas cosas dentro de cada sistema operativo huésped, y... bueno, aunque ni por asomo tenía la obligación de currármelo tanto como vereis a continuacion, pero ya sabeis que siempre que me gusta una idea intento implementarla de forma sofisticada (dentro de mis capacidades) y reutilizable para el futuro, me gusta hacer las cosas lo mejor posible (repito, dentro de mis capacidades), y esto es lo que acabé haciendo...

Este sistema o implementación depende del programa command-line vmrun.exe de VMWare, de otra forma sería practicamente inviable hacer esto ya sea en .NET o en un lenguaje de bajo nivel sin pasar meses o años de dedicación en el estudio e investigación; vmrun nos facilitará por completo la tarea de identificar las máquinas virtuales de VMWare que están en ejecución en el sistema operativo anfitrión, y realizar operaciones de I/O en las mismas, como copiar archivos del S.O. anfitrión al huésped o viceversa, enviar pulsaciones del teclado (o mejor dicho enviar cadenas de texto), o ejecutar programas y scripts, tomar capturas de pantalla, o administrar las carpetas compartidas y las imágenes (snapshots) de la VM, entre otras cosas. Implementé casi todas las funcionalidades de vmrun.

Como único inconveniente debo aclarar que este sistema no soporta máquinas virtuales compartidas (esas que podemos colocar en el directorio del usuario público como recurso compartido de red), y esta limitación es simplemente por pura ignorancia, ya que no he logrado averiguar la sintaxis correcta de vmrun para indicarle que el host es LOCALHOST, siempre que lo intento (ej. vmrun.exe -T ws-shared -h LOCALHOST ... ) el programa me dice que no ha logrado conectar con el servidor xD, así que si alguien sabe cual es la sintaxis le agradecería que me lo dijese para poder adaptar y mejorar este código.

Aquí lo tenen todo:

GuestOsCredential.vb
Código (vbnet) [Seleccionar]
''' <summary>
''' Represents the username/password login data for the running guest operating system of a VMWare's virtual machine.
''' </summary>
Public NotInheritable Class GuestOsCredential

#Region " Properties "

   ''' <summary>
   ''' Gets or sets the account username.
   ''' </summary>
   Public Property Username As String

   ''' <summary>
   ''' Gets or sets the account password.
   ''' </summary>
   Public Property Password As String

#End Region

#Region " Constructors "

   ''' <summary>
   ''' Initializes a new instance of the <see cref="GuestOsCredential"/> class.
   ''' </summary>
   Public Sub New()
   End Sub

#End Region

End Class


VmRunProgramFlags.vb
Código (vbnet) [Seleccionar]
''' <summary>
''' Specifies the behavior of a program that is executed by VMWare's vmrun.exe application.
''' </summary>
<Flags>
Public Enum VmRunProgramFlags

   ''' <summary>
   ''' Run the program using the default behavior.
   ''' </summary>
   None = 1

   ''' <summary>
   ''' Returns a prompt immediately after the program starts in the guest operating system, rather than waiting for it to finish.
   ''' <para></para>
   ''' This option is useful for interactive programs.
   ''' </summary>
   NoWait = 2

   ''' <summary>
   ''' Ensures that the program window is visible, not minimized, in the guest operating system.
   ''' <para></para>
   ''' This option has no effect on Linux.
   ''' </summary>
   ActiveWindow = 4

   ''' <summary>
   ''' Forces interactive guest login.
   ''' <para></para>
   ''' This option is useful for Windows VISTA guests to make the program visible in he console window.
   ''' </summary>
   Interactive = 8

End Enum


VmRunException.vb
Código (vbnet) [Seleccionar]
''' <summary>
''' The exception that Is thrown When a call to VMWare's vmrun.exe application exits with an error.
''' </summary>
<Serializable>
<XmlRoot(NameOf(VmRunException))>
<ImmutableObject(True)>
Public NotInheritable Class VmRunException : Inherits Exception

#Region " Properties "

   ''' <summary>
   ''' Gets the exit code of VMWare's vmrun.exe application.
   ''' </summary>
   Public ReadOnly Property ExitCode As Integer

#End Region

#Region " Constructors "

   ''' <summary>
   ''' Prevents a default instance of the <see cref="VmRunException"/> class from being created.
   ''' </summary>
   Private Sub New()
   End Sub

   ''' <summary>
   ''' Initializes a new instance of the System.Exception class with a specified error message.
   ''' </summary>
   ''' <param name="message">
   ''' The message that describes the error.
   ''' </param>
   <DebuggerNonUserCode>
   <EditorBrowsable(EditorBrowsableState.Never)>
   Private Sub New(ByVal message As String)
       MyBase.New(message)
   End Sub

   ''' <summary>
   ''' Initializes a new instance of the System.Exception class with a specified error message
   ''' and a reference to the inner exception that is the cause of this exception.
   ''' </summary>
   ''' <param name="message">
   ''' The message that describes the error.
   ''' </param>
   '''
   ''' <param name="innerException">
   ''' The exception that is the cause of the current exception,
   ''' or <see langword="Nothing"/> if no inner exception is specified.
   ''' </param>
   <DebuggerNonUserCode>
   <EditorBrowsable(EditorBrowsableState.Never)>
   Private Sub New(ByVal message As String, ByVal innerException As Exception)
       MyBase.New(message, innerException)
   End Sub

   ''' <summary>
   ''' Initializes a new instance of the System.Exception class with a specified error message and exit code.
   ''' </summary>
   ''' <param name="message">
   ''' The error message thrown by VMWare's vmrun.exe application.
   ''' </param>
   '''
   ''' <param name="exitCode">
   ''' The exit code of VMWare's vmrun.exe application
   ''' </param>
   Public Sub New(ByVal message As String, ByVal exitCode As Integer)
       MyBase.New(message)
       Me.ExitCode = exitCode
   End Sub

#End Region

End Class


VmSharedFolderInfo.vb
Código (vbnet) [Seleccionar]
''' <summary>
''' Represents a shared folder of a VMWare's virtual machine.
''' </summary>
Public NotInheritable Class VmSharedFolderInfo

#Region " Properties "

   ''' <summary>
   ''' Gets or sets the share name.
   ''' </summary>
   Public Property Name As String

   ''' <summary>
   ''' Gets or sets the shared directory on host operating system.
   ''' </summary>
   Public Property HostDirectory As DirectoryInfo

   ''' <summary>
   ''' Gets or sets a value that determine whether this shared folder is enabled.
   ''' </summary>
   Public Property Enabled As Boolean

   ''' <summary>
   ''' Gets or sets a value that determine whether this shared folder allows read access.
   ''' </summary>
   Public Property ReadAccess As Boolean

   ''' <summary>
   ''' Gets or sets a value that determine whether this shared folder allows write access.
   ''' </summary>
   Public Property WriteAccess As Boolean

   ''' <summary>
   ''' Gets or sets the expiration time of this shared folder.
   ''' </summary>
   Public Property Expiration As String

#End Region

#Region " Constructors "

   ''' <summary>
   ''' Initializes a new instance of the <see cref="VmSharedFolderInfo"/> class.
   ''' </summary>
   Public Sub New()
   End Sub

#End Region

End Class


VMWareVirtualMachine.vb
Código (vbnet) [Seleccionar]

''' <summary>
''' Represents a VMWare Virtual Machine.
''' </summary>
Public NotInheritable Class VMWareVirtualMachine

#Region " Properties "

   ''' <summary>
   ''' Gets .vmx file of this VM.
   ''' </summary>
   Public ReadOnly Property VmxFile As FileInfo

   ''' <summary>
   ''' Gets or sets the username and password of the running user-account in the guest operating system of this VM.
   ''' <para></para>
   ''' The credential is required to perform some I/O operations with VMWare's vmrun.exe program.
   ''' So you must set this credential before using vmrun.exe.
   ''' </summary>
   Public Property GuestOsCredential As GuestOsCredential

   ''' <summary>
   ''' Gets a value that determine whether this VM is a shared VM.
   ''' </summary>
   Public ReadOnly Property IsSharedVm As Boolean

   ''' <summary>
   ''' Gets the display name of this VM.
   ''' </summary>
   Public ReadOnly Property DisplayName As String
       Get
           Return Me.displayNameB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the display name of this VM.
   ''' </summary>
   Private displayNameB As String

   ''' <summary>
   ''' Gets the version of the guest operating system of this VM.
   ''' </summary>
   Public ReadOnly Property OsVersion As String
       Get
           Return Me.osVersionB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the version of the guest operating system of this VM.
   ''' </summary>
   Private osVersionB As String

   ''' <summary>
   ''' Gets the firmware type of this VM. It can be: BIOS, or UEFI.
   ''' </summary>
   Public ReadOnly Property Firmware As String
       Get
           Return Me.firmwareB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the firmware type of this VM. It can be: BIOS, or UEFI.
   ''' </summary>
   Private firmwareB As String

   ''' <summary>
   ''' Gets a value that determine whether secureboot is enabled for UEFI firmware mode.
   ''' </summary>
   Public ReadOnly Property SecureBootEnabled As Boolean
       Get
           Return Me.secureBootEnabledB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets a value that determine whether secureboot is enabled for UEFI firmware mode.
   ''' </summary>
   Private secureBootEnabledB As Boolean

   ''' <summary>
   ''' Gets the hardware version of this VM.
   ''' </summary>
   ''' <remarks>
   ''' See for more info about virtual machine hardware versions: <see href="https://kb.vmware.com/s/article/1003746"/>
   ''' </remarks>
   Public ReadOnly Property VmHardwareVersion As Integer
       Get
           Return Me.vmHardwareVersionB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the hardware version of this VM.
   ''' </summary>
   Private vmHardwareVersionB As Integer

   ''' <summary>
   ''' Gets the total memory size of this VM, in megabytes.
   ''' </summary>
   Public ReadOnly Property MemorySize As Integer
       Get
           Return Me.memorySizeB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the total memory size of this VM, in megabytes.
   ''' </summary>
   Private memorySizeB As Integer

   ''' <summary>
   ''' Gets the total graphics memory size of this VM, in megabytes.
   ''' </summary>
   Public ReadOnly Property GraphicsMemorySize As Integer
       Get
           Return Me.graphicsMemorySizeB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the total graphics memory size of this VM, in megabytes.
   ''' </summary>
   Private graphicsMemorySizeB As Integer

   ''' <summary>
   ''' Gets a value that determine whether 3D graphics hardware acceleration is enabled in this VM.
   ''' </summary>
   Public ReadOnly Property GraphicsHardwareAccelerationEnabled As Boolean
       Get
           Return Me.graphicsHardwareAccelerationEnabledB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets a value that determine whether 3D graphics hardware acceleration is enabled in this VM.
   ''' </summary>
   Private graphicsHardwareAccelerationEnabledB As Boolean

   ''' <summary>
   ''' Gets the amount of processor cores of this VM.
   ''' </summary>
   Public ReadOnly Property TotalProcessorCores As Integer
       Get
           Return Me.totalProcessorCoresB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the amount of processor cores of this VM.
   ''' </summary>
   Private totalProcessorCoresB As Integer

   ''' <summary>
   ''' Gets the amount of cores per processor of this VM.
   ''' </summary>
   Public ReadOnly Property CoresPerProcessor As Integer
       Get
           Return Me.coresPerProcessorB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the amount of cores per processor of this VM.
   ''' </summary>
   Private coresPerProcessorB As Integer

   ''' <summary>
   ''' Gets the amount of processors of this VM.
   ''' <para></para>
   ''' The resulting value is the division between <see cref="VMWareVirtualMachine.TotalProcessorCores"/> \ <see cref="VMWareVirtualMachine.CoresPerProcessor"/>.
   ''' </summary>
   Public ReadOnly Property ProcessorCount As Integer
       Get
           Return (Me.TotalProcessorCores \ Me.CoresPerProcessor)
       End Get
   End Property

   ''' <summary>
   ''' Gets the shared folders of this VM.
   ''' </summary>
   Public ReadOnly Property SharedFolders As ReadOnlyCollection(Of VmSharedFolderInfo)
       Get
           Return Me.sharedFoldersB
       End Get
   End Property
   ''' <summary>
   ''' ( Backing Fields )
   ''' <para></para>
   ''' Gets the shared folders of this VM.
   ''' </summary>
   Private sharedFoldersB As ReadOnlyCollection(Of VmSharedFolderInfo)


#End Region

#Region " Constructors "

   ''' <summary>
   ''' Prevents a default instance of the <see cref="VMWareVirtualMachine"/> class from being created.
   ''' </summary>
   Private Sub New()
   End Sub

   ''' <summary>
   ''' Initializes a new instance of the <see cref="VMWareVirtualMachine"/> class.
   ''' </summary>
   ''' <param name="vmxFilePath">
   ''' The full path to the .vmx file.
   ''' </param>
   '''
   ''' <param name="isSharedVm">
   ''' A value that determine whether the VM is a shared VM.
   ''' </param>
   Public Sub New(ByVal vmxFilePath As String, ByVal isSharedVm As Boolean)
       Me.VmxFile = New FileInfo(vmxFilePath)
       Me.IsSharedVm = isSharedVm
       Me.GuestOsCredential = New GuestOsCredential()

       Me.Refresh()
   End Sub

#End Region

#Region " Public Methods "

   ''' <summary>
   ''' Refresh the state (the properties) of this <see cref="VMWareVirtualMachine"/>.
   ''' </summary>
   ''' <exception cref="FileNotFoundException">
   ''' .vmx file not found.
   ''' </exception>
   Public Sub Refresh()
       If Not (Me.VmxFile.Exists) Then
           Throw New FileNotFoundException(".vmx file not found.", Me.VmxFile.FullName)
       End If

       Me.VmxFile.Refresh()

       Dim sharedFoldersDict As New Dictionary(Of String, VmSharedFolderInfo)

       Using sr As StreamReader = Me.VmxFile.OpenText()

           Dim line As String
           Do Until sr.EndOfStream
               line = sr.ReadLine().Trim()

               Select Case True

                   Case line.ToLower().StartsWith("displayname")
                       Me.displayNameB = line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote})

                   Case line.ToLower().StartsWith("firmware")
                       Me.firmwareB = line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote})

                   Case line.ToLower().StartsWith("guestos")
                       Me.osVersionB = line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote})

                   Case line.ToLower().StartsWith("memsize")
                       Me.memorySizeB = CInt(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

                   Case line.ToLower().StartsWith("numvcpus")
                       Me.totalProcessorCoresB = CInt(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

                   Case line.ToLower().StartsWith("cpuid.corespersocket")
                       Me.coresPerProcessorB = CInt(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

                   Case line.ToLower().StartsWith("svga.graphicsmemorykb")
                       Me.graphicsMemorySizeB = (CInt(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote})) \ 1000)

                   Case line.ToLower().StartsWith("virtualhw.version")
                       Me.vmHardwareVersionB = CInt(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

                   Case line.ToLower().StartsWith("uefi.secureboot.enabled")
                       Me.secureBootEnabledB = Boolean.Parse(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

                   Case line.ToLower().StartsWith("mks.enable3d")
                       Me.graphicsHardwareAccelerationEnabledB = Boolean.Parse(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

                   Case line.ToLower() Like "sharedfolder#*.?*"
                       Me.ParseSharedFolderLine(line, sharedFoldersDict)

               End Select

           Loop

       End Using

       Me.sharedFoldersB = New ReadOnlyCollection(Of VmSharedFolderInfo)(sharedFoldersDict.Values.ToArray())
       sharedFoldersDict.Clear()
   End Sub

#End Region

#Region " Private Methods "

   ''' <summary>
   ''' Parses a line of the .vmx file that contains a shared folder field and value.
   ''' </summary>
   ''' <param name="line">
   ''' The line to parse.
   ''' </param>
   '''
   ''' <param name="refSharedFoldersDict">
   ''' A <see cref="Dictionary(Of String, SharedFolderInfo)"/> that will be used to set the corresponding <see cref="VmSharedFolderInfo"/> member.
   ''' </param>
   Private Sub ParseSharedFolderLine(ByVal line As String, ByRef refSharedFoldersDict As Dictionary(Of String, VmSharedFolderInfo))

       Dim key As String = line.ToLower().Substring(0, line.IndexOf("."c))
       If Not refSharedFoldersDict.ContainsKey(key) Then
           refSharedFoldersDict.Add(key, New VmSharedFolderInfo())
       End If

       Select Case True

           Case line.ToLower() Like "sharedfolder#*.enabled*"
               refSharedFoldersDict(key).Enabled = Boolean.Parse(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

           Case line.ToLower() Like "sharedfolder#*.expiration*"
               refSharedFoldersDict(key).Expiration = line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote})

           Case line.ToLower() Like "sharedfolder#*.guestname*"
               refSharedFoldersDict(key).Name = line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote})

           Case line.ToLower() Like "sharedfolder#*.hostpath*"
               refSharedFoldersDict(key).HostDirectory = New DirectoryInfo(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

           Case line.ToLower() Like "sharedfolder#*.readaccess*"
               refSharedFoldersDict(key).ReadAccess = Boolean.Parse(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

           Case line.ToLower() Like "sharedfolder#*.writeaccess*"
               refSharedFoldersDict(key).WriteAccess = Boolean.Parse(line.Substring(line.IndexOf("="c) + 1).Trim({" "c, ControlChars.Quote}))

       End Select

   End Sub

#End Region

End Class


VMRunWrapper.vb

El código es demasiado largo como para poder insertarlo en este post, así que les dejo un enlace a pastebin...

https://pastebin.com/AWieMiSG

Código mejorado con funciones asincrónicas:
https://pastebin.com/EXS0MQRR

Un pequeño fallo de formato de sintaxis ha sido corregido en el método "InstallVmWareTools":




Un ejemplo de uso cualquiera:

Código (vbnet) [Seleccionar]
'***********************************************************************************************************************************
'
'This is a code example that demonstrates how to get the running virtual machines, then run a program on each guest operating system.
'
'***********************************************************************************************************************************

Private vmRun As VmRunWrapper

Private Async Sub Test()

   Me.vmRun = New VmRunWrapper("C:\Program Files (x86)\VMWare\VMware VIX\vmrun.exe")

   Dim vmCount As Integer = Await Me.vmRun.GetRunningVmCountAsync()
   If (vmCount > 0) Then

       Dim vms As ReadOnlyCollection(Of VMWareVirtualMachine) = Await Me.vmRun.GetRunningVmsAsync()

       For Each vm As VMWareVirtualMachine In vms

           ' Check whether VMWare-Tools are installed in the VM.
           ' The VmWare-Tools are required by some of the functionalities of vmrun.exe program.
           Dim isVMWareToolsInstalled As Boolean = Await Me.vmRun.IsVmWareToolsInstalledAsync(vm)
           Console.WriteLine("VM Name: {0}; IsVMWareToolsInstalled: {1}'", vm.DisplayName, isVMWareToolsInstalled)

           If Not isVMWareToolsInstalled Then
               Me.vmRun.InstallVmWareTools(vm)
               Continue For
           End If

           ' A valid guest username and password (if any) is required in order to use some of the functionalities of vmrun.exe program.
           vm.GuestOsCredential.Username = "guest username"
           vm.GuestOsCredential.Password = "guest password"

           Try
               ' Run a random program on the guest operating system.
               Me.vmRun.ProcessRun(vm, "C:\program.exe", VmRunProgramFlags.NoWait Or VmRunProgramFlags.ActiveWindow Or VmRunProgramFlags.Interactive, "")

           Catch ex As VmRunException
               Throw

           Catch ex As Exception
               Throw

           End Try

       Next

   End If

End Sub
#990
Por un lado está lo que podriamos denominar el sistema de captcha tradicional, y luego el sistema de captcha patentado por Google que conocemos por el nombre de reCaptcha.

Existen varias implementaciones del captcha como ya has comentado, un captcha con letras, o con figuras, o puzzles, pero a todos se les llama captcha, tal cual, sin distinción, puesto que eso es lo que son.

Saludos.