Ir al contenido


Foto

Utilizar funcion WinExecAndWait32 en ejecutables de linea de comando y capturar en Panel1

WinExecAndWait32 Panel1

  • Por favor identifícate para responder
9 respuestas en este tema

#1 seba_13680

seba_13680

    Member

  • Miembros
  • PipPip
  • 27 mensajes

Escrito 06 marzo 2017 - 12:28

Buenas noches a todos¡

Los molesto con unas consultas ...

Estoy desarrollando una aplicacion que utiliza la funcion WinExecAndWait32 para ejecutar tres comandos

Los ejecuta sin problemas, el tema es que abre la ventanda de linea de comandos (cmd.exe) fuera del formulario

La idea por el momento es poder "capturar" la ventana con sus respectivos comandos y poder verlos en un Panel

Me refiero a poder ver la ventana cmd en el panel ya que dos comandos necesitan el ingreso de datos

 

La funcion que utilizo es la siguiente :


delphi
  1. function WinExecAndWait32(Path: PChar; Visibility: Word;
  2. Timeout : DWORD): integer;
  3.  
  4. function WinExecAndWait32(Path: PChar; Visibility: Word;
  5. Timeout : DWORD): integer;
  6. var
  7. WaitResult : integer;
  8. StartupInfo: TStartupInfo;
  9. ProcessInfo: TProcessInformation;
  10. //iResult : integer;
  11. begin
  12. FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  13. with StartupInfo do
  14. begin
  15. cb := SizeOf(TStartupInfo);
  16. dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  17. { you could pass sw_show or sw_hide as parameter: }
  18. wShowWindow := visibility;
  19. end;
  20. if CreateProcess(nil,path,nil, nil, False,
  21. NORMAL_PRIORITY_CLASS, nil, nil,
  22. StartupInfo, ProcessInfo) then
  23. begin
  24. WaitResult := WaitForSingleObject(ProcessInfo.hProcess, timeout);
  25. { timeout is in miliseconds or INFINITE if
  26. you want to wait forever }
  27. result := WaitResult;
  28. end
  29. else
  30. { error occurs during CreateProcess see help for details }
  31. result:=GetLastError;
  32. end;
  33.  

y para ejecutar los comandos por el momento me manejo con este codigo


delphi
  1. var
  2. ComandoUno: string;
  3. ComandoDos: string;
  4. ComandoTres: string;
  5. begin
  6. ComandoUno:=('ping localhost');
  7. WinExecAndWait32(pchar(ComandoUno),SW_SHOW,INFINITE);
  8. ComandoDos:=('dir c:');
  9. WinExecAndWait32(pchar(ComandoDos),SW_SHOW,INFINITE);
  10. ComandoTres:=('netstat -a');
  11. WinExecAndWait32(pchar(ComandoTres),SW_SHOW,INFINITE);
  12. end; 

Desde ya muchas gracias por las respuestas u orientacion al respecto

Saludos¡ 

 

 

 

 

 

 

 

 

 

 


  • 0

#2 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 06 marzo 2017 - 05:45

Revisa este tema: Capturar la salida de consola: DosCommand y este otro que parte del anterior y lo completa: Ayuda con automatización de Procesos

 

Saludos.


  • 0

#3 seba_13680

seba_13680

    Member

  • Miembros
  • PipPip
  • 27 mensajes

Escrito 07 marzo 2017 - 06:02

Buen dia Escafandra¡

Y gracias por las respuesta¡

Con respecto a http://delphiaccess....ola-doscommand/lo estuve investigando

pero como decia Edson, necesito interactuar desde la linea de comando en la salida de la funcion WinExecAndWait32 por que algunos

parametros son ingresados luego de ejecutar el comando desde la misma linea de comandos y bueno la idea es que esten en el mismo formulario.

Estoy investigando al respecto y me parece que el tema va por "capturar el parent" en el Formulario pero me es muy avanzado para mì

y bueno luego poder combinarlos con la funcion WinExecAndWait32 ..

Por ahora lo mas cercano que encontrè en el siguiente codigo

Cualquier respuesta, consejo, comentario serà bienvenido, saludos¡


delphi
  1. unit ufrmMain;
  2. interface
  3. uses
  4. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5. Dialogs, StdCtrls, Menus, ExtCtrls;
  6. function WinExecAndWait32(Path: PChar; Visibility: Word;
  7. Timeout : DWORD): integer;
  8. type
  9. TForm1 = class(TForm)
  10. MainMenu1: TMainMenu;
  11. mnuNotepad: TMenuItem;
  12. Panel1: TPanel;
  13. procedure mnuNotepadClick(Sender: TObject);
  14. private
  15. { Private declarations }
  16. public
  17. { Public declarations }
  18. end;
  19. var
  20. Form1: TForm1;
  21. implementation
  22. {$R *.dfm}
  23. type
  24. TWindowRec = record
  25. Handle: THandle;
  26. ProcessId: Cardinal;
  27. WindowName: PChar;
  28. end;
  29. PWindowRec = ^TWindowRec;
  30. function EnumWindowsProc(Handle: Thandle; lParam: LPARAM): BOOL; stdcall;
  31. var
  32. ProcessId: Cardinal;
  33. Buffer: PChar;
  34. Size: Integer;
  35. begin
  36. Result:= TRUE;
  37. ProcessId:= 0;
  38. GetWindowThreadProcessId(Handle, ProcessId);
  39. if ProcessId = PWindowRec(lParam).ProcessId then
  40. begin
  41. if PWindowRec(lParam).WindowName <> nil then
  42. begin
  43. Size:= GetWindowTextLength(Handle) + 1;
  44. GetMem(Buffer,Size);
  45. try
  46. GetWindowText(Handle,Buffer,Size);
  47. if StrIcomp(PWindowRec(lParam).WindowName, Buffer) = 0 then
  48. begin
  49. PWindowRec(lParam).Handle:= Handle;
  50. Result:= FALSE;
  51. end;
  52. finally
  53. Freemem(Buffer);
  54. end;
  55. end else
  56. begin
  57. PWindowRec(lParam).Handle:= Handle;
  58. Result:= FALSE;
  59. end;
  60. end;
  61. end;
  62. function GetWindowFromProcessId(ProcessId: Cardinal; WindowName: PChar): THandle;
  63. var
  64. WindowRec: TWindowRec;
  65. begin
  66. FillChar(WindowRec,Sizeof(WindowRec),0);
  67. WindowRec.ProcessId:= ProcessId;
  68. WindowRec.WindowName:= WindowName;
  69. EnumWindows(@EnumWindowsProc, LPARAM(@WindowRec));
  70. Result:= WindowRec.Handle;
  71. end;
  72. function Ejecutar(Cmd: string; WindowName: PChar; Timeout: Cardinal): THandle;
  73. var
  74. StartupInfo: TStartupInfo;
  75. ProcessInfo: TProcessInformation;
  76. Ticks: Cardinal;
  77. begin
  78. Result:= 0;
  79. FillChar(StartupInfo,Sizeof(StartupInfo),0);
  80. StartupInfo.wShowWindow:= SW_SHOW;
  81. Ticks:= GetTickCount;
  82. if CreateProcess(nil,PChar(Cmd),nil,nil, FALSE, CREATE_NEW_CONSOLE or
  83. NORMAL_PRIORITY_CLASS,nil,nil,StartupInfo, ProcessInfo) then
  84. while (Result = 0) and (GetTickCount - Ticks < TimeOut) do
  85. begin
  86. Result:= GetWindowFromProcessId(ProcessInfo.dwProcessId, WindowName);
  87. //if Result = 0 then Sleep(0);
  88. if Result = 0 then Sleep(0);
  89. end;
  90. end;
  91. function WinExecAndWait32(Path: PChar; Visibility: Word;
  92. Timeout : DWORD): integer;
  93. var
  94. WaitResult : integer;
  95. StartupInfo: TStartupInfo;
  96. ProcessInfo: TProcessInformation;
  97. //iResult : integer;
  98. begin
  99. FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  100. with StartupInfo do
  101. begin
  102. cb := SizeOf(TStartupInfo);
  103. dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  104. { you could pass sw_show or sw_hide as parameter: }
  105. wShowWindow := visibility;
  106. end;
  107. if CreateProcess(nil,path,nil, nil, False,
  108. NORMAL_PRIORITY_CLASS, nil, nil,
  109. StartupInfo, ProcessInfo) then
  110. begin
  111. WaitResult := WaitForSingleObject(ProcessInfo.hProcess, timeout);
  112. { timeout is in miliseconds or INFINITE if
  113. you want to wait forever }
  114. result := WaitResult;
  115. end
  116. else
  117. { error occurs during CreateProcess see help for details }
  118. result:=GetLastError;
  119. end;
  120.  
  121. procedure TForm1.mnuNotepadClick(Sender: TObject);
  122. var
  123. H: THandle;
  124. I: THandle;
  125. ComandoUno: string;
  126. ComandoDos: string;
  127. begin
  128. ComandoUno:=('ping -t localhost');
  129.  
  130. //WinExecAndWait32(pchar(ComandoCinco),SW_SHOW,INFINITE);
  131. //WinExecAndWait32(pchar(ComandoCinco),SW_SHOW,INFINITE
  132. //ShowMessage(ComandoUno);
  133.  
  134. H:= Ejecutar('ping -t localhost',nil,5000);
  135.  
  136. // Esta funcion trabaja directamente con el comando completo, necesito conbinarla con
  137. // WinExecAndWait32 por que de los contrario ejecuta todos los comandos de una sola vez
  138.  
  139.  
  140. //H:= Ejecutar('ping -t localhost',nil,5000);
  141. //H:= Ejecutar('cmd.exe',nil,5000);
  142.  
  143. Windows.SetParent(H, Panel1.Handle);
  144. SetWindowPos(H, 0, 0, 0, ClientWidth, ClientHeight, SWP_ASYNCWINDOWPOS);
  145. end;
  146.  
  147. end.


  • 0

#4 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 07 marzo 2017 - 10:32

Una cosa es ejecutar una consola en un TPanel y otra capturar su contenido. Para capturar la salida de consola e interactuar con ella, ya de dejé los enlaces, especialmente el segundo: Ayuda con automatización de Procesos.
 
Para ejecutar una consola dentro de un TPanel, sin más, te dejo este sencillo código:

delphi
  1. procedure CmdWithParent(Parent: HWND);
  2. var
  3. StartupInfo: TStartupInfo;
  4. ProcessInfo: TProcessInformation;
  5. Wnd: HWND;
  6. begin
  7. ZeroMemory(@StartupInfo, sizeof(TStartupInfo));
  8. StartupInfo.dwFlags:= STARTF_USESHOWWINDOW;
  9. StartupInfo.wShowWindow:= SW_HIDE;
  10. if CreateProcess(nil, 'cmd.exe', nil, nil, FALSE, 0, nil, nil, StartupInfo, ProcessInfo) then
  11. begin
  12. Wnd:= 0;
  13. repeat Wnd:= FindWindow('ConsoleWindowClass', nil); until Wnd <> 0;
  14. Windows.SetParent(Wnd, Parent);
  15. SetWindowPos(Wnd, 0,0,0,0,0,SWP_NOSIZE or SWP_SHOWWINDOW);
  16. end;
  17. end;

Y esta sería una forma de usarlo:

delphi
  1. CmdWithParent(Panel1.Handle);

3b321e92ca1278f5da6c2eefe692460ao.gif
Probado con Delphi7 en Win10

Saludos.
  • 0

#5 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 07 marzo 2017 - 04:49

Si buscamos un efecto en el que la consola quede más integrada en el TPanel, podemos añadir una línea al código:

delphi
  1. procedure CmdWithParent(Parent: HWND);
  2. var
  3. StartupInfo: TStartupInfoA;
  4. ProcessInfo: TProcessInformation;
  5. Wnd: HWND;
  6. begin
  7. ZeroMemory(@StartupInfo, sizeof(TStartupInfoA));
  8. StartupInfo.dwFlags:= STARTF_USESHOWWINDOW;
  9. StartupInfo.wShowWindow:= SW_HIDE;
  10. if CreateProcessA(nil, 'cmd.exe', nil, nil, FALSE, 0, nil, nil, StartupInfo, ProcessInfo) then
  11. begin
  12. Wnd:= 0;
  13. repeat Wnd:= FindWindow('ConsoleWindowClass', nil); until Wnd <> 0;
  14. Winapi.Windows.SetParent(Wnd, Parent);
  15. SetWindowLong(Wnd, GWL_STYLE, 0);
  16. SetWindowPos(Wnd, 0,0,0,0,0,SWP_NOSIZE or SWP_SHOWWINDOW);
  17. end;
  18. end;

Aprovecho para probar en Berlin y adaptarlo. Probado en Win 8.1 y 10.
 
0ab1b61a2b9f429568c8ea0649b7d22bo.gif
 
Saludos.
  • 1

#6 seba_13680

seba_13680

    Member

  • Miembros
  • PipPip
  • 27 mensajes

Escrito 14 marzo 2017 - 01:27

Buenas tardes¡ y gracias por las respuestas Escafandra¡ sigo investigando y estudiando para ver si puedo evitar el paso de tener que ingresar los datos por consola

ya que es un tema que aun no manejo y se me hace muy complejo, estoy adaptando los script remotos para que reciban los datos y tener que evitar cargarlos en los clientes, de todos modos se va aprendiendo sobre la marcha 

Saludos y gracias por las respuestas ...


  • 0

#7 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 14 marzo 2017 - 01:58

Buenas tardes¡ y gracias por las respuestas Escafandra¡ sigo investigando y estudiando para ver si puedo evitar el paso de tener que ingresar los datos por consola

 
Lo primero que tienes que tener claro es lo que quieres y lo que estás preguntando.
 

La idea por el momento es poder "capturar" la ventana con sus respectivos comandos y poder verlos en un Panel
Me refiero a poder ver la ventana cmd en el panel ya que dos comandos necesitan el ingreso de datos


Primero interpreté que querías ejecutar comandos sin visualizar una consola y te di la respuesta de como hacerlo, incluso interactuando con los resultados que, además, se capturan. Pero no te pareció bien argumentando que querías una consola dentro de un TPanel, Entonces pensé que te interpreté mal:
 

Me refiero a poder ver la ventana cmd en el panel ya que dos comandos necesitan el ingreso de datos


Entonces me dije: "Ah, lo que quiere es simplemente meter la consola en un TPanel" y te metí la consola en un TPanel.

Ahora no es eso lo que quieres y parece que vuelves a querer sólo la primera interpretación.

sigo investigando y estudiando para ver si puedo evitar el paso de tener que ingresar los datos por consola

No se si has leído realmente los enlaces que te dejé, porque si lo hubieras hecho te hubieses dado cuenta que estabas respondido desde la primera respuesta que te di en este tema.
 
 
Saludos.
  • 0

#8 seba_13680

seba_13680

    Member

  • Miembros
  • PipPip
  • 27 mensajes

Escrito 14 marzo 2017 - 07:10

Buenas noches Escafandra
Necesitaba, digo necesitaba por que aun para mì que recien comienzo con Delphi se me hace aun muy complejo algunos temas, y quizas aun me cuesta formular las preguntas relacionadas al desarrollo,  y bueno estoy volviendo pasos atras para ver si puedo ingresar los comandos y evitar el tema de la ventana cmd, el tema basicamente era una consola con la cual poder interactuar en un Panel dentro del Formulario.
Es un tema estetico ya que las ventanas cmd que genera la funcion WinExecAndWait32 (ejecutando comandos de consola), se ejecutan al igual que la ventana
en cualquier lugar de la pantalla.
 
Tu primer respuesta fue: Revisa este tema: Capturar la salida de consola: DosCommand y este otro que parte del anterior y lo completa: Ayuda con automatización de Procesos
 
Por ese lado no iba el tema ya que necesitaba ingresar los datos desde la consola misma o sea poder ver la consola de manera interactiva desde el mismo
Formulario
 
Edson -Holas. Deseo abrir un proceso de consola (como el CMD o el FTP), de forma interactiva, de modo que pueda enviar comandos y leer la respuesta.
Tu respuesta: Prueba esto y lee esto: Capturar la salida de consola: DosCommand
Edson -Gracias escafandra. Precisamente, lo que deseo, es interactuar con el FTP, desde mi aplicación.
Tu respuesta: Quizás puedas usar la API para FTP Sessions y te olvidas de la consola.
Edson -Gracias por el enlace, escafandra. Pero mi requerimiento es que necesito ejecutar de forma interactiva el FTP, que viene por defecto en Windows (en general cualquier aplicación de consola).
Mi problema no se remite solo al FTP, sino a cualquier aplicación de consola
Luego el tema sigue en cuestiones de compatibilidad en distintas arquitecturas
o sea me parece que es un tema de interpretacion, luego de todo el tema se vuelve al primer link explicado anteriormente
 
Segui investigando y leyendo respecto al tema, asi que no pudo continuar por ese lado, vuelvo hacia atras y voy a intentar traer los parametros
para poder ingresar directamente sin necesidad de que se ingresen manualmente
En el circuito estan Gnu/Linux Debian 8.7, terminales Windows y sus respectivas llaves cifradas, comandos en bash interactuando con una ventana
"flotante" en cmd que generada una aplicacion, aun verde, en Delphi, continuo investigando y estudiando asi no te vuelvo a molestar ya que 
desde mi Talent msx dpc 200 solo hice 7 preguntas en foros especializados, Saludos y buenas noches¡ y viva Delphi ¡ 

  • 0

#9 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 15 marzo 2017 - 10:00

 

...Edson -Gracias por el enlace, escafandra. Pero mi requerimiento es que necesito ejecutar de forma interactiva el FTP, que viene por defecto en Windows (en general cualquier aplicación de consola).
Mi problema no se remite solo al FTP, sino a cualquier aplicación de consola
Luego el tema sigue en cuestiones de compatibilidad en distintas arquitecturas
o sea me parece que es un tema de interpretacion,...

 

Te equivocas. Luego no son cuestiones de compatibilidad. Luego viene el mensaje 8 donde escribo una función para Delphi 7 que hace lo que Edson quería conseguir y lo que parece que tu quieres, es decir, ejecutar comandos de consola sin ver la consola y capturar los resultados para seguir trabajando de forma interactiva. Es decir, existe una consola oculta y los mensajes de usuario y consola se vuelcan en un TMemo o donde una quiera. En dicho mensaje aparece un enlace con una aplicación de ejemplo.

 

El resto del hilo es una discusión para adaptar el código que escribí a Lazarus 64 bits.

 

Insisto porque te veo muy verde y es posible que te pasen cosas inadvertidas al leerlas. Cuando leas un hilo, no busques el código mágico que resuelva tu duda, seguramente te pierdas por el camino. Se trata de asimilar lo que se comenta y tratar de entender el código que se publique, copiarlo sin comprender te llevará a frustraciones y de poco te servirá.

 

No acometas proyectos fuera de tu alcance, ve poco a poco, asimila y crea por ti mismo.

 

 

Saludos.


  • 0

#10 seba_13680

seba_13680

    Member

  • Miembros
  • PipPip
  • 27 mensajes

Escrito 15 marzo 2017 - 11:56

Te equivocas. Luego no son cuestiones de compatibilidad. Luego viene el mensaje 8 donde escribo una función para Delphi 7 que hace lo que Edson quería conseguir y lo que parece que tu quieres, es decir, ejecutar comandos de consola sin ver la consola y capturar los resultados para seguir trabajando de forma interactiva. Es decir, existe una consola oculta y los mensajes de usuario y consola se vuelcan en un TMemo o donde una quiera. En dicho mensaje aparece un enlace con una aplicación de ejemplo.

 

El resto del hilo es una discusión para adaptar el código que escribí a Lazarus 64 bits.

 

Insisto porque te veo muy verde y es posible que te pasen cosas inadvertidas al leerlas. Cuando leas un hilo, no busques el código mágico que resuelva tu duda, seguramente te pierdas por el camino. Se trata de asimilar lo que se comenta y tratar de entender el código que se publique, copiarlo sin comprender te llevará a frustraciones y de poco te servirá.

 

No acometas proyectos fuera de tu alcance, ve poco a poco, asimila y crea por ti mismo.

 

 

Saludos.

 

Gracias y si tiene toda la razon, estoy muy emocionado con este proyecto que me estoy apurando demasiado, por eso llegaba al final y no podia continuar, luego volvia dos pasos y seguia por otro lado, recien estoy comenzando con Delphi, voy a seguir los consejos al pie de la letra, lamento haber comenzado de esta manera, continuare estudiando para poder formular mejor las preguntas ya que es todo nuevo en Delphi para mì, envio saludos y exitos por allà¡ 


  • 0




IP.Board spam blocked by CleanTalk.