News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Capturing Commandl Line Output

Started by cman, December 13, 2012, 04:19:17 AM

Previous topic - Next topic

cman

What's the best way to run a command line program from a Windows program and display the output of the program to a Windows control ( like an edit control or something ). I want to run a command line program "in the background"  but show the output in "real time" as though it were part of the main Windows program.  An examples of how to do this? Thanks for any information.

Tedd

Create pipes for the std handles you want to deal with - minimally one for stdout+stderr;
Start your sub-process with CreateProcess, with the pipe handles in the STARTUPINFO structure.
The process runs, readfile its output on the pipe(s), do whatever..
Check the process has finished (WaitForSingleObject), close the pipes, clean up.
Potato2

Vortex

Hi cman,

You can check Iczelion's tutorial #21. It provides a nice example demonstrating the capture of command line output.

TouEnMasm

Here is a template to do that:
Quote
;useful to execute dos or windows proc
.data
   SecuAttr SECURITY_ATTRIBUTES <>
   startInfo     STARTUPINFO <>   ;structure API CreateProcess
   processInfo   PROCESS_INFORMATION <> ;structure API   
   hRead dd 0
   hWrite dd 0
   retourligne db 13,10,0
   Pipetampon db 500h dup (0)
   bytesRead dd 0
   Hfile dd 0
   NumberOfBytesWritten dd 0
   dumpbinexe db "\masm32\bin\ml.exe /?",0
;################################################################
CreationPipe PROC
         Local  retour:DWORD
      mov retour,0
   mov SecuAttr.nLength,sizeof SECURITY_ATTRIBUTES
   mov SecuAttr.bInheritHandle,TRUE
   ;lea edx,SecuAttr.lpSecurityDescriptor
   ;invoke InitializeSecurityDescriptor,edx,SECURITY_DESCRIPTOR_REVISION
   invoke CreatePipe,addr hRead,addr hWrite,addr SecuAttr,NULL   
   mov retour,eax
   mov startInfo.cb,sizeof startInfo
   ;retrouve les informations a la creation du prog
   invoke GetStartupInfo,addr startInfo
   xor eax,eax
   mov startInfo.lpReserved,eax      ;null avant d'appeler CreateProcess
   mov eax,hWrite
   mov startInfo.hStdOutput,eax
   mov startInfo.hStdError,eax
   mov startInfo.dwFlags,STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES
   mov startInfo.wShowWindow,SW_SHOW
   ;invoke CloseHandle,hWrite      ;made test here
                ;---------- close it later if not work -------------------------------
FindeCreationPipe:
         mov eax,retour
         ret
CreationPipe endp

;################################################################      

   start:
   ;......
   invoke CreationPipe
   invoke CreateProcess,NULL,addr dumpbinexe,NULL,NULL,TRUE,NULL,NULL,NULL,\
            addr startInfo,addr processInfo
   lecture:
   ; si hread déclaré avec FILE_FLAG_OVERLAPPED,dernière donnée structure
   ;lpSecurityDescriptor de SECURITY_ATTRIBUTES
   invoke ReadFile,hRead,addr Pipetampon,sizeof Pipetampon - 1,addr bytesRead,NULL
   .if eax != 0
      ;invoke WriteFile,Hfile,addr Pipetampon,bytesRead,addr NumberOfBytesWritten,NULL
      jmp lecture
   .endif   
   invoke CloseHandle,hRead
   ;.......
Take care when closing handles


Fa is a musical note to play with CL

TouEnMasm

And here is a sample who read the ml help output and write it in a file:

Quote
.NOLIST         ;signifie: ne rien mettre dans le listing   
   include \masm32\include\masm32rt.inc
   InitInstance PROTO :DWORD   
   
   .const
   .data
   hInstance dd 0
   ;InitCtrls INITCOMMONCONTROLSEX <sizeof INITCOMMONCONTROLSEX,0> ;commctrl.sdk
   ;FindFileData WIN32_FIND_DATA <>
   ;------------------- pipe data ----------------------------------------
   SecuAttr SECURITY_ATTRIBUTES <>
   startInfo     STARTUPINFO <>   ;structure API CreateProcess
   processInfo   PROCESS_INFORMATION <> ;structure API   
   hRead dd 0
   hWrite dd 0
   retourligne db 13,10,0
   Pipetampon db 500h dup (0)
   bytesRead dd 0
   Hfile dd 0
   NumberOfBytesWritten dd 0
   dumpbinexe db "\masm32\bin\ml.exe /?",0   
   Nomfichier db "ML_help.txt",0
   ;------------------- end pipe data --------------------------------------
.code
;################################################################
CreationPipe PROC
         Local  retour:DWORD
      mov retour,0
   mov SecuAttr.nLength,sizeof SECURITY_ATTRIBUTES
   mov SecuAttr.bInheritHandle,TRUE
   ;lea edx,SecuAttr.lpSecurityDescriptor
   ;invoke InitializeSecurityDescriptor,edx,SECURITY_DESCRIPTOR_REVISION
   invoke CreatePipe,addr hRead,addr hWrite,addr SecuAttr,NULL   
   mov retour,eax
   mov startInfo.cb,sizeof startInfo
   ;retrouve les informations a la creation du prog
   invoke GetStartupInfo,addr startInfo
   xor eax,eax
   mov startInfo.lpReserved,eax      ;null avant d'appeler CreateProcess
   mov eax,hWrite
   mov startInfo.hStdOutput,eax
   mov startInfo.hStdError,eax
   mov startInfo.dwFlags,STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES
   mov startInfo.wShowWindow,SW_SHOW
   ;invoke CloseHandle,hWrite      ;inutile
FindeCreationPipe:
         mov eax,retour
         ret
CreationPipe endp

;################################################################      
   start:
   invoke InitInstance,1
   ;---- code here --------
   invoke CreationPipe
   invoke CreateProcess,NULL,addr dumpbinexe,NULL,NULL,TRUE,NULL,NULL,NULL,\
            addr startInfo,addr processInfo
   invoke CloseHandle,hWrite
   lecture:
; if hread declared with FILE_FLAG_OVERLAPPED,last readfile data is a structure
   ;lpSecurityDescriptor de SECURITY_ATTRIBUTES
   invoke ReadFile,hRead,addr Pipetampon,sizeof Pipetampon - 1,addr bytesRead,NULL
   .if eax != 0
      invoke WriteFile,Hfile,addr Pipetampon,bytesRead,addr NumberOfBytesWritten,NULL
      jmp lecture
   .endif   
   ;invoke CloseHandle,hWrite   
   invoke CloseHandle,hRead
      
   invoke InitInstance,0   
   invoke ExitProcess,0
;hInstance dd 0
;InitCtrls INITCOMMONCONTROLSEX <> ;include commctrl.sdk
;init=1,desinit=0
;################################################################

InitInstance PROC  init:DWORD
   Local  retour:DWORD
   mov retour,1
   .if init == 1
      invoke GetModuleHandle,NULL
      mov hInstance,eax   
         invoke CreateFile,addr Nomfichier,GENERIC_WRITE,NULL,\
         NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
      mov Hfile,eax         

   .else
      invoke CloseHandle,Hfile
      
   .endif

FindeInitInstance:
   mov eax,retour
   ret
InitInstance endp

;################################################################
   
   end start
Fa is a musical note to play with CL

jj2007

#5
For the lazy assembly coder:

        Launch "SendStringsToConsole.exe", SW_MINIMIZE, cb:hEdit

P.S.: Under the hood, a slightly modified version of the MSDN example is working. Read the user comments...!

dedndave

i am really lazy, i guess - lol

        INVOKE  AllocConsole

you can left click anywhere in the window to see some console text   :P

my mistake - i misread the original post

cman

Wow , thanks for your input , everyone! :t