Saltar al contenido

Historial del chat

ChatGPT

Sora

Explorar GPT

Proyectos

Nuevo proyecto

Hoy

Colorear texto en bat

Insert CMD en PictureBox

Mostrar salida consola VB6

7 días anteriores

Protección EXE VB6

Loader Full Resumen

Reparar entorno tf-gpu

Problema TensorFlow GPU

Chat archivado no se abre

30 días anteriores

IMPORTANTE MORPHING FINAL Phygital+ Hugging Face Espacio

Uso de recursos del sistema

IMPORTANTE MORPHING 6

FFmpeg no encontrado

Eliminar mensajes de log

Falta librería dlib

Máscara para cabello

IMPORTANTE MORPHING 5

IMPORTANTE MORPHING 4

Recuperar chat y transferir

Acceso a espacio personal

Mover chats a Team

Cancelar suscripción Plus

Convert Local Time UTC

abril

CUDA en Stable Diffusion

Remover2 fondo video IA

marzo

Transparencia en PSP 5

Resumen de conversaciones anteriores

Cambio color HTML Flash

Recibir correos en Gmail

Agregar compañeros de equipoInvitar a compañeros de trabajo a ChatGPT

Abrir barra lateral

ChatGPT o4-mini-high

ChatGPT o4-mini-high

Compartir

Dijiste:

Como se podria hacer que al lanzar un cmd desde vb6, la consola se inserte dentro de un picturebox en vb6?

ChatGPT dijo:

¿Podrías aclarar un poco más qué esperas que suceda dentro del PictureBox? Por ejemplo:

¿Quieres mostrar la salida del CMD (como texto) dentro del PictureBox?

¿Quieres embeber toda la consola CMD con su interfaz dentro del PictureBox, como si fuera un control?

¿Estás usando alguna librería externa o controles ActiveX?

Con esos detalles podré orientarte mejor.

Dijiste:

No, quierometer la consola misma denro de un picturebox y que se muestre lo que va haciendo, es la consola...

Si

No de momento

ChatGPT dijo:

Gracias por la aclaración. Investigaré cómo embeber la ventana de la consola CMD directamente dentro de un control PictureBox en una aplicación Visual Basic 6, sin usar librerías externas. Exploraré técnicas como redirección de ventanas mediante APIs de Windows (como SetParent) u otras estrategias compatibles con VB6.

Te informaré en cuanto tenga los resultados.

Research completed in 7m· 15 fuentes· 92 búsquedas

Incrustar Consola CMD en un PictureBox en VB6

Incrustar la consola CMD en un PictureBox de VB6 usando APIs de Windows

Contexto: La consola de comandos (CMD) normalmente se ejecuta en su propia ventana separada. Sin embargo, es posible incrustar visualmente esa ventana de la consola dentro de la interfaz de una aplicación VB6, de modo que aparezca dentro de un control PictureBox. Esto se logra aprovechando funciones de la API de Windows para cambiar la ventana padre (parent window) de la ventana de la consola, haciendo que el PictureBox actúe como su contenedor. En particular, la función SetParent de user32.dll permite reparentizar una ventana existente (cambiar su padre)vbforums.com. En otras palabras, podemos lanzar una instancia de cmd.exe y convertir su ventana en hija del PictureBox del formulario VB6. A continuación se detallan los pasos, seguidos de un ejemplo de código y consideraciones importantes sobre esta técnica.

Pasos para incrustar la ventana de CMD en un PictureBox

Lanzar el proceso de la consola: Use la función Shell de VB6 (o CreateProcess de la API) para ejecutar cmd.exe. Puede iniciarlo oculto (vbHide) inicialmente para que no parpadee una ventana separada.

Asignar un título identificador (recomendado): El título por defecto de la ventana de cmd.exe puede variar según el sistema y contexto (por ejemplo, no siempre será "C:\WINDOWS\system32\cmd.exe" u otro fijo)stackoverflow.com. Por ello, conviene ejecutar CMD con un título único conocido. Por ejemplo, usando el comando interno title:

vb

CopiarEditar

Shell "cmd.exe /K title MiConsolaEmbebida", vbHide

Esto abre la consola manteniéndola (/K) y asignándole el título "MiConsolaEmbebida", que luego podremos buscar de forma confiable.

Obtener el handle de la ventana de la consola: Una vez iniciado el proceso, necesitamos el identificador de ventana (hWnd). Podemos usar FindWindow para buscar la ventana de la consola bien sea por su clase ("ConsoleWindowClass") o por el título único asignado en el paso anterior. Por ejemplo:

vb

CopiarEditar

hWndConsola = FindWindow(vbNullString, "MiConsolaEmbebida")

Este handle será un valor distinto de cero si la ventana fue encontrada.

Reparentizar la ventana al PictureBox: Con el hWnd obtenido, llamamos a SetParent para cambiar el padre de la ventana de la consola. Se debe pasar el handle hijo (la consola) y el handle del PictureBox (Picture1.hWnd en este ejemplo) como nuevo padrevbforums.com. Ejemplo:

vb

CopiarEditar

SetParent hWndConsola, Picture1.hWnd

Después de esta llamada, la ventana de la consola pasará a formar parte del PictureBox (es decir, aparecerá dentro de los límites de Picture1 en el formulario).

Ajustar tamaño y posición: Use MoveWindow (u otra función similar) para posicionar y redimensionar la consola dentro del PictureBox según necesite. Típicamente se coloca en la esquina superior izquierda (0,0) del PictureBox y se ajusta su tamaño a llenar el área disponibleexperts-exchange.com. Por ejemplo:

vb

CopiarEditar

MoveWindow hWndConsola, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, True

Nota: MoveWindow espera dimensiones en píxeles. Si la propiedad ScaleMode del formulario/PictureBox está en twips (por defecto en VB6), habrá que convertir las unidades a píxeles o cambiar ScaleMode a 3-Pixel.

Mostrar la ventana embebida: Si lanzó la consola oculta, llame a ShowWindow(hWndConsola, SW_SHOW) para hacerla visible dentro del PictureBox. En caso contrario, tras SetParent la consola ya debería estar visible (aunque puede estar detrás de otros controles si no se trajo al frente; puede usar SetWindowPos o ShowWindow para asegurarlo).

(Opcional) Quitar bordes y barra de título: Para que la consola se integre de forma más transparente en su interfaz, es común eliminar su barra de título y bordes de ventana. Esto se logra ajustando los estilos de ventana vía SetWindowLong. Por ejemplo, eliminando los estilos WS_CAPTION y WS_THICKFRAME (que quitan la barra de título y borde redimensionable) y asegurando que tenga estilo WS_CHILD en lugar de WS_POPUP. Según la documentación de Windows, al cambiar el parent no se modifican automáticamente estos estilosstackoverflow.com, por lo que es recomendable ajustarlos manualmente. En código, podría ser:

vb

CopiarEditar

style = GetWindowLong(hWndConsola, GWL_STYLE)
style = (style And Not WS_CAPTION And Not WS_THICKFRAME And Not WS_POPUP) Or WS_CHILD
SetWindowLong hWndConsola, GWL_STYLE, style

De esta forma la ventana de la consola aparecerá sin encabezado ni bordes dentro del PictureBox, dando la apariencia de estar totalmente embebida en el formulario.

Ejemplo de código VB6

El siguiente es un ejemplo simplificado que implementa los pasos anteriores utilizando solo VB6 y llamadas a API de Windows. En este ejemplo se asume un formulario con un PictureBox llamado Picture1 y un botón de comando Command1 para activar la incrustación:

vb

CopiarEditar

' --- Declaraciones de funciones API (módulo o sección General del formulario) ---
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hWnd As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

' Constantes para estilos de ventana y showwindow
Private Const GWL_STYLE As Long = -16&
Private Const WS_CHILD As Long = &H40000000
Private Const WS_POPUP As Long = &H80000000
Private Const WS_CAPTION As Long = &HC00000 ' Incluye WS_BORDER (0x800000) y WS_DLGFRAME (0x400000)
Private Const WS_THICKFRAME As Long = &H40000
Private Const SW_SHOW As Long = 5
Private Const SW_HIDE As Long = 0

Private Sub Command1_Click()
Dim hWndConsola As Long
Dim procID As Long
Dim style As Long

' 1. Lanzar CMD.exe con título único y oculto
procID = Shell("cmd.exe /K title CONSOLE_EMBEDDED", vbHide)
Sleep 500 ' Pequeña espera para dar tiempo a que la ventana de la consola se cree

' 2. Obtener el handle de la ventana de la consola buscándola por el título asignado
hWndConsola = FindWindow(vbNullString, "CONSOLE_EMBEDDED")
If hWndConsola = 0 Then
MsgBox "No se encontró la ventana de la consola."
Exit Sub
End If

' 3. Reparentizar la ventana de la consola dentro del PictureBox
SetParent hWndConsola, Picture1.hWnd

' 4. (Opcional) Quitar la barra de título y bordes de la ventana de consola
style = GetWindowLong(hWndConsola, GWL_STYLE)
style = (style And Not WS_CAPTION And Not WS_THICKFRAME And Not WS_POPUP) Or WS_CHILD
SetWindowLong hWndConsola, GWL_STYLE, style

' 5. Mover y redimensionar la consola para llenar el PictureBox
' Nota: MoveWindow usa unidades en píxeles. Si ScaleMode está en twips, convertir dimensiones a píxeles.
MoveWindow hWndConsola, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, True

' 6. Hacer visible la consola embebida (si estaba oculta)
ShowWindow hWndConsola, SW_SHOW
End Sub

Qué hace este código: inicia cmd.exe con el título "CONSOLE_EMBEDDED", obtiene su hWnd una vez lanzado, cambia su padre al PictureBox (Picture1), ajusta los estilos de ventana para quitar la barra de título, lo mueve al área del PictureBox y finalmente lo muestra. Tras ejecutar Command1_Click, la consola aparecerá dentro del PictureBox y podrá usarse allí de forma interactiva.

Consideraciones técnicas y limitaciones

Carácter no convencional: Embedir un proceso externo dentro de una ventana de VB6 mediante SetParent es una técnica no estándar (no fue diseñada originalmente por Microsoft para este propósito). Funciona en muchos casos, pero se considera más bien un truco de integración. Como comentan algunos desarrolladores, “es algo hacky y horrible, pero funciona”stackoverflow.com. En otras palabras, no es la solución más elegante ni robusta, pero cumple su objetivo. Hay que estar consciente de este carácter no oficial al utilizarla.

Identificación confiable de la ventana: Al usar este método, asegúrese de identificar correctamente la ventana de la consola que va a incrustar. No confíe en el título por defecto del CMD, ya que puede cambiar o incluir la ruta actual, el estado (ej. "Administrador: ...") etc.stackoverflow.com. Use la estrategia de darle un título único con title al lanzar el proceso, tal como hicimos en el ejemplo, o bien adopte un método más robusto. Una alternativa robusta es obtener el PID del proceso creado (por ejemplo con CreateProcess o a partir del retorno de Shell) y luego buscar la ventana según ese PID. Esto se logra enumerando todas las ventanas del escritorio y filtrando por las que pertenezcan a ese PID (usando EnumDesktopWindows + GetWindowThreadProcessId)experts-exchange.com. De esta forma se elimina la ambigüedad incluso si hay múltiples consolas abiertas.

Ajuste de estilos y foco: Como se mencionó, Windows no ajusta automáticamente los estilos de la ventana reparentizadastackoverflow.com. Es importante establecer manualmente el estilo WS_CHILD y remover WS_POPUP (además de los estilos de marco si desea ocultarlos) antes o justo después de llamar a SetParent. Si no se hace, la ventana embebida podría seguir teniendo atributos de ventana flotante, lo cual puede ocasionar comportamientos extraños. En cuanto al foco de teclado: la consola embebida recibirá foco cuando el usuario haga clic dentro de ella y entonces podrá escribir comandos normalmente. No suele ser necesario manipular el foco por código, e incluso funciones como SetFocus no funcionan con ventanas de otro proceso (a menos que se usen técnicas avanzadas como AttachThreadInput). En general, basta con dejar que el usuario active la consola con un clic para poder digitar en ella.

Ciclo de vida y cierre: La consola incrustada sigue siendo un proceso independiente (cmd.exe). Esto implica que su ciclo de vida debe manejarse con cuidado: si su aplicación VB6 termina, la consola podría quedar abierta e independiente (Windows probablemente la reparentice de vuelta al escritorio automáticamente). Por ello, es recomendable cerrar la consola embebida al salir de la aplicación. Puede hacerse enviando un comando de salida (SendKeys "exit") o un mensaje de ventana (PostMessage(hWndConsola, WM_CLOSE, 0, 0)) antes de cerrar el formulario principal, o usando la API TerminateProcess en el PID del proceso de cmd (esta última es más forzosa y menos elegante). Del mismo modo, considere qué ocurre si el usuario cierra la consola manualmente (por ejemplo escribiendo "exit" dentro de ella): en ese caso la ventana desaparecerá. Se puede detectar esta situación comprobando periódicamente si FindWindow aún la encuentra o manejando el código de retorno del proceso (si se lanzó con CreateProcess), para así quizá lanzar una nueva consola o al menos notificar al usuario. Un método simple es usar un Timer en el formulario que verifique si IsWindow(hWndConsola) retorna false, indicando que la consola se cerró, y reaccionar acorde (por ejemplo, ofrecer relanzarla o limpiar el PictureBox).

Compatibilidad: La técnica mostrada aprovecha APIs disponibles en Windows desde al menos la era de Windows 2000/XP, por lo que funciona en sistemas operativos modernos como Windows 7, 8, 10, etc. En nuestras pruebas y referencias, SetParent sigue funcionando para consolas en Windows 10 sin problemas. En Windows 11, hay que tener en cuenta la introducción de Windows Terminal como aplicación de consola por defecto. Si el Terminal está configurado como manejador predeterminado de las sesiones de consola, al ejecutar cmd.exe este podría abrirse dentro de una ventana de Windows Terminal (con pestañas), en lugar de la clásica ventana de consola de conhost.exe. En tal caso, no será posible incrustar esa pestaña de Terminal en un PictureBox mediante SetParent (al menos no de forma sencilla), ya que la ventana contenedora ya no es directamente la consola sino el Terminal. La solución sería desactivar el Terminal como consola predeterminada (volver al Windows Console Host clásico) en la configuración de Windows 11, o lanzar la consola de otro modo que fuerce el uso del host legado. Este es un detalle a considerar si su aplicación se ejecutará en entornos Windows 11 recientes.

Opción alternativa – redirección de E/S: Si su objetivo final es mostrar la salida de comandos y enviarles entrada desde la aplicación, una alternativa es no embeber la ventana de la consola en absoluto, sino ejecutar cmd.exe de forma oculta y redirigir sus flujos de salida/entrada mediante tuberías (pipes). Con las funciones adecuadas (por ejemplo usando la API de creación de procesos con CreatePipe y STARTUPINFO para redirigir STDOUT/STDIN), o utilizando componentes COM ya hechos, la aplicación VB6 puede captar todo el texto que la consola imprimiría y mostrarlo en un control (p. ej. un TextBox o RichTextBox), así como enviar comandos simulando la entrada. Este enfoque evita tener una ventana de consola real, a cambio de requerir que la aplicación actúe como "terminal". Algunos desarrolladores lo consideran más elegante y robusto en muchos casos (ya que el usuario nunca ve una consola separada y se tiene control total del texto)experts-exchange.com. No obstante, implementar la redirección e interfaz manual puede ser más complejo que la solución con SetParent. Si lo que se busca es una integración rápida de la consola real con toda su funcionalidad (colores, edición, etc.), incrustar la ventana con SetParent cumple el cometido, aunque con las advertencias mencionadas arriba.

Referencias: Este enfoque ha sido discutido en la comunidad desarrolladora, por ejemplo en foros y páginas de Q&A. Se han proporcionado ejemplos de código que utilizan SetParent para capturar la ventana de cmd.exe y colocarla dentro de un PictureBoxexperts-exchange.comvbforums.com. Asimismo, se señala que encontrar la ventana por título puede ser poco fiable si el título no es fijostackoverflow.com, de ahí la importancia de técnicas como la asignación de un título personalizado o el uso de identificadores de procesoexperts-exchange.com. Varios desarrolladores califican la técnica como un hack útil pero a tener en cuenta con precauciónstackoverflow.com. En resumen, es posible lograr la incrustación usando solo VB6 y API de Windows, pero debe hacerse cuidadosamente considerando las limitaciones de esta solución.

Fuentes

Dijiste:

No va a funcionar porque la consola no solo se llama CONSOLE_EMBEDDED, sino que tiene como nombre Administrador: CONSOLE_EMBEDDED y luego el bat que esta ejecutando

ChatGPT dijo:

Pensado durante 33 segundos

Aquí la clave es no buscar la ventana por su título exacto, sino localizarla a partir del PID del proceso cmd.exe que acabas de lanzar y de su clase de ventana (ConsoleWindowClass). El flujo general es:

Arrancar cmd.exe con CreateProcess, no con Shell, para obtener el dwProcessId.

Enumerar todas las ventanas del escritorio con EnumWindows.

Para cada ventana, usar GetWindowThreadProcessId y quedarnos con aquella que coincida en PID y cuya clase sea ConsoleWindowClass.

Con ese hWnd recién hallado, hacemos el SetParent al Picture1.hWnd, ajustamos estilos y tamaño como antes.

1. Declaraciones de API y estructuras

vb

CopiarEditar

'--- en un módulo estándar (por ejemplo: modConsoleEmbed) ---
Option Explicit

' Para CreateProcess
Private Type SECURITY_ATTRIBUTES
nLength As Long: lpSecurityDescriptor As Long: bInheritHandle As Long
End Type
Private Type STARTUPINFO
cb As Long: lpReserved As String: lpDesktop As String: lpTitle As String
dwX As Long: dwY As Long: dwXSize As Long: dwYSize As Long
dwXCountChars As Long: dwYCountChars As Long: dwFillAttribute As Long
dwFlags As Long: wShowWindow As Integer: cbReserved2 As Integer
lpReserved2 As Long: hStdInput As Long: hStdOutput As Long: hStdError As Long
End Type
Private Type PROCESS_INFORMATION
hProcess As Long: hThread As Long: dwProcessId As Long: dwThreadId As Long
End Type

Private Declare Function CreateProcessA Lib "kernel32" _
(ByVal lpApplicationName As String, ByVal lpCommandLine As String, _
lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long

' Para encontrar la ventana
Private Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetClassNameA Lib "user32" _
(ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

' Para reparentizar y ajustar estilo/tamaño
Private Declare Function SetParent Lib "user32" _
(ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function MoveWindow Lib "user32" _
(ByVal hWnd As Long, ByVal X As Long, ByVal Y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function ShowWindow Lib "user32" _
(ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Const GWL_STYLE As Long = -16
Private Const WS_CHILD As Long = &H40000000
Private Const WS_POPUP As Long = &H80000000
Private Const WS_CAPTION As Long = &HC00000
Private Const WS_THICKFRAME As Long = &H40000
Private Const SW_HIDE As Long = 0
Private Const SW_SHOW As Long = 5

' Variables globales de módulo
Private g_TargetPID As Long
Private g_hWndConsole As Long

2. Callback de EnumWindows

vb

CopiarEditar

' Será llamada para cada ventana; devolvemos 0 para parar cuando la encontremos
Public Function EnumWinProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
Dim pid As Long, cls As String * 256, length As Long

' ¿Pertenece esta ventana al PID de cmd.exe?
GetWindowThreadProcessId hWnd, pid
If pid = g_TargetPID Then
' ¿Es una ventana de consola?
length = GetClassNameA(hWnd, cls, Len(cls))
cls = Left$(cls, InStr(cls, vbNullChar) - 1)
If cls = "ConsoleWindowClass" Then
g_hWndConsole = hWnd
EnumWinProc = 0 ' parar la enumeración
Exit Function
End If
End If
EnumWinProc = 1 ' seguir enumerando
End Function

3. Función para lanzar y capturar el hWnd de la consola

vb

CopiarEditar

Public Function LaunchAndEmbedConsole(pic As PictureBox) As Boolean
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION
Dim success As Long
Dim style As Long

' Preparar STARTUPINFO: iniciamos oculta
si.cb = Len(si)
si.dwFlags = &H1 ' STARTF_USESHOWWINDOW
si.wShowWindow = SW_HIDE

' Crear proceso cmd.exe con título fijo
success = CreateProcessA( _
vbNullString, _
"cmd.exe /K title CONSOLE_EMBEDDED", _
ByVal 0&, ByVal 0&, _
0, 0, 0&, vbNullString, si, pi)
If success = 0 Then Exit Function

g_TargetPID = pi.dwProcessId
Sleep 300 ' dejar que la ventana aparezca

' Enumerar ventanas y extraer la nuestra
g_hWndConsole = 0
EnumWindows AddressOf EnumWinProc, 0
If g_hWndConsole = 0 Then Exit Function

' Cambiar padre al PictureBox
SetParent g_hWndConsole, pic.hWnd

' Ajustar estilos para quitar bordes/título
style = GetWindowLong(g_hWndConsole, GWL_STYLE)
style = (style And Not WS_CAPTION And Not WS_THICKFRAME And Not WS_POPUP) Or WS_CHILD
SetWindowLong g_hWndConsole, GWL_STYLE, style

' Redimensionar para llenar todo el PictureBox
MoveWindow g_hWndConsole, _
0, 0, pic.ScaleWidth, pic.ScaleHeight, True

' Mostrarla
ShowWindow g_hWndConsole, SW_SHOW

LaunchAndEmbedConsole = True
End Function

4. Uso en tu formulario

En el formulario con tu Picture1 y, por ejemplo, un botón Command1:

vb

CopiarEditar

Private Sub Command1_Click()
If Not LaunchAndEmbedConsole(Picture1) Then
MsgBox "No se pudo incrustar la consola."
End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
' (Opcional) cerrar la consola al salir
If g_hWndConsole <> 0 Then ShowWindow g_hWndConsole, SW_HIDE
End Sub

¿Por qué esto ya funciona aunque el título real sea “Administrador: CONSOLE_EMBEDDED …”?

No dependemos del texto de la barra de título, por eso da igual si Windows antepone “Administrador: ” o añade el nombre del .BAT

Buscamos la ventana por PID y por su clase (“ConsoleWindowClass”), garantizando que será la que acaba de arrancar tu propio cmd.exe.

Con esta adaptación robusta, la ventana de la consola se incrustará siempre en tu PictureBox, independientemente de variaciones en el título.

Dijiste:

La consola debe de abrir un bat en su propio app.path que se llama:
morphphy_ori.bat

Y de ahi capturarla y meterla dentro de un picturebox

ChatGPT dijo:

Pensado durante 11 segundos

Para lanzar morphphy_ori.bat desde tu carpeta de aplicación y luego capturar su ventana para embebértela en el PictureBox, basta con:

Usar App.Path como directorio de trabajo al arrancar la consola.

Invocar cmd.exe /K para que ejecute el BAT y no se cierre al terminar.

Como antes, buscar la ventana por PID + clase y reparentizarla.

A continuación tienes el bloque clave modificado. Asume que todo lo demás (declaraciones de API, callback EnumWinProc, constantes, etc.) es idéntico a lo que vimos antes: sólo cambiamos la llamada a CreateProcessA.

vb

CopiarEditar

Public Function LaunchAndEmbedBatch(pic As PictureBox) As Boolean
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION
Dim success As Long
Dim style As Long
Dim cmdLine As String
Dim workDir As String

' 1. Construir la línea de comando y el directorio de trabajo
workDir = App.Path
' Asegúrate de incluir comillas si la ruta tiene espacios
cmdLine = "cmd.exe /K """ & workDir & "\morphphy_ori.bat"""

' 2. Preparar STARTUPINFO: iniciar invisible
si.cb = Len(si)
si.dwFlags = &H1 ' STARTF_USESHOWWINDOW
si.wShowWindow = SW_HIDE ' arrancar oculto

' 3. Crear proceso en App.Path
success = CreateProcessA( _
vbNullString, _ ' lpApplicationName: usamos variable de entorno
cmdLine, _ ' lpCommandLine
ByVal 0&, ByVal 0&, _ ' sin heredar handles
0, 0, ' flags
0&, ' lpEnvironment = nulo → hereda tu entorno
workDir, _ ' lpCurrentDirectory = App.Path
si, pi)

If success = 0 Then
MsgBox "Error al arrancar el BAT."
Exit Function
End If

' 4. Guardamos el PID para identificar la ventana
g_TargetPID = pi.dwProcessId
Sleep 300 ' esperamos que la ventana aparezca

' 5. Enumerar ventanas para obtener el hWnd de la consola
g_hWndConsole = 0
EnumWindows AddressOf EnumWinProc, 0
If g_hWndConsole = 0 Then
MsgBox "No se encontró la ventana de consola para el BAT."
Exit Function
End If

' 6. Cambiar padre al PictureBox
SetParent g_hWndConsole, pic.hWnd

' 7. Ajustar estilos (sin bordes ni barra)
style = GetWindowLong(g_hWndConsole, GWL_STYLE)
style = (style And Not WS_CAPTION And Not WS_THICKFRAME And Not WS_POPUP) Or WS_CHILD
SetWindowLong g_hWndConsole, GWL_STYLE, style

' 8. Redimensionar para llenar todo el PictureBox
MoveWindow g_hWndConsole, 0, 0, pic.ScaleWidth, pic.ScaleHeight, True

' 9. Mostrar la consola embebida
ShowWindow g_hWndConsole, SW_SHOW

LaunchAndEmbedBatch = True
End Function

Y en tu formulario:

vb

CopiarEditar

Private Sub Command1_Click()
If Not LaunchAndEmbedBatch(Picture1) Then
MsgBox "No se pudo incrustar morphphy_ori.bat."
End If
End Sub

Puntos clave

workDir = App.Path asegura que la consola arranque con tu carpeta como directorio de trabajo y localice correctamente morphphy_ori.bat.

cmd.exe /K "<ruta>\morphphy_ori.bat" ejecuta el BAT y mantiene la ventana abierta para que puedas verla.

Como antes, identificamos la ventana por PID y clase en lugar de por título, de modo que da igual si Windows antepone “Administrador: ” o muestra el nombre del BAT.

Con esto, la ventana de tu script morphphy_ori.bat quedará embebida y 100% funcional dentro del PictureBox.

Buscar

Investigar a fondo

Crear imagen

ChatGPT puede cometer errores. OpenAI no utiliza los datos del espacio de trabajo Astrix para entrenar sus modelos.