The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: frktons on September 16, 2010, 01:30:28 PM

Title: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 01:30:28 PM
If a MASM program is running, and at some point it needs to run an
external program and getting back the control when the called prog finishes,
what kind of instructions have I to use?

Let's talk for the moment of a console program calling another external console
program:

Prog1.exe  --- Run ------> Prog2.exe ----> End Prog2.exe ----> Prog1.exe regains control


Thanks

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: dedndave on September 16, 2010, 02:37:46 PM
CreateProcess
Title: Re: Running an external program from an ASM running program [?]
Post by: clive on September 16, 2010, 03:04:38 PM
From the CRT there are also exec,spawn,system functions. Depends what you want to do with command line, environment variables, and return codes.
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 03:07:21 PM
Quote from: dedndave on September 16, 2010, 02:37:46 PM
CreateProcess

Hi Dave, welcome back.  :bg
You are a little bit too verbose. Shouldn't it be enough to write CP?  :lol

Come on, when you feel like, post an addendum to this code, that INVOKE the CreateProcess
to run the selected prog:


;-------------------------------------------------------------------------------
; Call a OpenFileDialog through a MACRO
; Select an EXE file
; Run it
; Displays some stuff when back.
;-------------------------------------------------------------------------------


include \masm32\include\masm32rt.inc

; -------------------------------------------------------------------------

.data

   ConTitle  db "  ----------     **  Example running an external prog  **",
                "----------", 0  


   CaptionText   BYTE  "Open Prog to Run",0

   szFilter      BYTE  "All files *.*",0,"*.*",0,
                       "Executable files *.exe",0,"*.exe",0,    
                       "Text files *.txt",0,"*.txt",0,
                       "Assembly files *.asm",0,"*.asm",0,
                       "Resource files *.rc",0,"*.rc",0,0
                       
; -------------------------------------------------------------------------

.data?

   hFile     HANDLE ?
   cci       CONSOLE_CURSOR_INFO <>        


   wHnd      HANDLE ?
   rHnd      HANDLE ?

   windowSize SMALL_RECT <>
   bufferSize COORD      <>
   startPoint COORD      <>

   howmany dd ?
   buffer  INPUT_RECORD <>    

   PtrFileName   DWORD ?            

.code

start:


; -------------------------------------------------------------------------

Main PROC

   CALL   InitProc

   CALL   ConsoleSize

   print " Press any key and choose the prog to run: ",13,10,13,10

   CALL   AnyKey    

   mov PtrFileName, OpenFileDlg (0,0, addr CaptionText, addr szFilter)  

   print " The chosen prog is: "

   print DWORD PTR PtrFileName, 13,10,13,10

   print " Press a key to run it ", 13,10,13,10

   CALL   AnyKey    
   
; -------------------------------------------------------------------------
; Here we call the selected prog to run
; -------------------------------------------------------------------------


; -------------------------------------------------------------------------

   print " Back from the called prog", 13,10,13,10

   CALL   AnyKey  

   CALL   ShowTheCursor

   INVOKE ExitProcess,0

   ret

Main ENDP

; -------------------------------------------------------------------------  

ConsoleSize PROC

   INVOKE SetConsoleTitle, ADDR ConTitle
 
   CALL   HideTheCursor

   INVOKE SetConsoleWindowInfo, wHnd, TRUE, ADDR windowSize

   INVOKE SetConsoleScreenBufferSize, wHnd, DWORD PTR bufferSize

   ret

ConsoleSize ENDP

; -------------------------------------------------------------------------

ShowTheCursor PROC

   INVOKE GetConsoleCursorInfo,wHnd,addr cci
   mov cci.bVisible,TRUE
   INVOKE SetConsoleCursorInfo,wHnd,addr cci
   ret
   
ShowTheCursor ENDP

; -------------------------------------------------------------------------
   


HideTheCursor PROC

   INVOKE GetConsoleCursorInfo,wHnd,addr cci
   mov cci.bVisible,FALSE
   INVOKE SetConsoleCursorInfo,wHnd,addr cci
   ret
   
HideTheCursor ENDP

; -------------------------------------------------------------------------

InitProc PROC

    INVOKE AllocConsole

   INVOKE GetStdHandle, STD_INPUT_HANDLE
   mov rHnd,eax

   INVOKE GetStdHandle, STD_OUTPUT_HANDLE
   mov wHnd,eax  

   mov windowSize.Left, 0
   mov windowSize.Right, 79
   mov windowSize.Top, 0
   mov windowSize.Bottom, 24
 

   mov bufferSize.x, 80
   mov bufferSize.y, 25

   mov startPoint.x, 0
   mov startPoint.y, 0


   ret

InitProc ENDP


; -------------------------------------------------------------------------
;Returns: key code in buffer.KeyEvent.wVirtualKeyCode WORD size
; -------------------------------------------------------------------------

AnyKey PROC

again:  

   INVOKE ReadConsoleInput,rHnd,offset buffer,1,offset howmany
   cmp buffer.EventType,KEY_EVENT
   jnz again

   cmp buffer.KeyEvent.bKeyDown,0
   jz again

   ret

AnyKey ENDP


; -------------------------------------------------------------------------
 
end start          



Quote from: clive on September 16, 2010, 03:04:38 PM
From the CRT there are also exec,spawn,system functions. Depends what you want to do with command line, environment variables, and return codes.

Any solution is just fine, if you show me the code to do it.  :P

Frank

Title: Re: Running an external program from an ASM running program [?]
Post by: untio on September 16, 2010, 03:48:07 PM
Hi,
When I need to call another process and wait until it is finished I use CreateProcess to create it and I use:
BOOL GetExitCodeProcess(
  HANDLE hProcess,
  LPDWORD lpExitCode
);
to wait until it is finished. The value pointed by lpExitCode is STILL_ACTIVE (259) until the process is finished. What I do is enter into a loop that includes a Sleep(someValue) and a call to GetExitCodeProcess.
But this can bring a big problem if the other process returns 259. I have never encountered this case.
Please forgive my errors.
Title: Re: Running an external program from an ASM running program [?]
Post by: clive on September 16, 2010, 03:53:27 PM
Quote from: frktons
Any solution is just fine, if you show me the code to do it.  :P

Uhm, half the battle is knowing what WIN32 or CRT functions to use, the web is rife with documentation, the examples will probably be in C, but transcribing that to an INVOKE, or manually PUSHing the arguments and CALLing shouldn't be too hard.

Then again there are simple approaches and more complex ones, like for instance whether the EXE is pulled from a specific place, if the PATH is used, if it is a shell function (CD, DIR, etc), what command line parameters need passing, do you want to alter the environment variables. You've indicated you want to regain control after the child app is finished, but you could have it go off on it's own.
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 04:04:24 PM
Quote from: clive on September 16, 2010, 03:53:27 PM
Quote from: frktons
Any solution is just fine, if you show me the code to do it.  :P

Uhm, half the battle is knowing what WIN32 or CRT functions to use, the web is rife with documentation, the examples will probably be in C, but transcribing that to an INVOKE, or manually PUSHing the arguments and CALLing shouldn't be too hard.

Then again there are simple approaches and more complex ones, like for instance whether the EXE is pulled from a specific place, if the PATH is used, if it is a shell function (CD, DIR, etc), what command line parameters need passing, do you want to alter the environment variables. You've indicated you want to regain control after the child app is finished, but you could have it go off on it's own.

Hi clive.

I'm looking for a simple one. If you look at the code I posted above:

http://www.masm32.com/board/index.php?topic=14824.msg120765#msg120765

I simply do:

1) choose the exe to execute
2) run it [missing part]
3) display "I'm back"

So no command line parameters, or anything else for the time being,
only an INVOKE to a CRT function, or CreateProcess API will suffice.
The only thing, I don't know the exact calling parameters for each of
them, or if I have to declare something and in which shape.

So just to start any of them will be fine.

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: Tedd on September 16, 2010, 04:14:04 PM
Quote from: untio on September 16, 2010, 03:48:07 PM
Hi,
When I need to call another process and wait until it is finished I use CreateProcess to create it and I use:
BOOL GetExitCodeProcess(
  HANDLE hProcess,
  LPDWORD lpExitCode
);
to wait until it is finished. The value pointed by lpExitCode is STILL_ACTIVE (259) until the process is finished. What I do is enter into a loop that includes a Sleep(someValue) and a call to GetExitCodeProcess.
But this can bring a big problem if the other process returns 259. I have never encountered this case.
Please forgive my errors.

You should use WaitForSingleObject which will put your process to sleep until the other process exits (or a timeout is reached.) Then you can call GetExitCodeProcess to see whatever it returned (if required.) No polling required :bg
Title: Re: Running an external program from an ASM running program [?]
Post by: Tedd on September 16, 2010, 04:21:25 PM
Once you've got the name of the program you want to run, using CreateProcess is straightforward, as long as you don't want to do anything fancy (just run it!)

You have to fill out a STARTUPINFO struct, but most of that can be zeroed, and then you call CreateProcess passing that struct as one of the parameters, and most of the other parameters can be zeroed :bg
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 04:23:05 PM
Quote from: Tedd on September 16, 2010, 04:21:25 PM
Once you've got the name of the program you want to run, using CreateProcess is straightforward, as long as you don't want to do anything fancy (just run it!)

You have to fill out a STARTUPINFO struct, but most of that can be zeroed, and then you call CreateProcess passing that struct as one of the parameters, and most of the other parameters can be zeroed :bg


As a matter of fact I did this way, and it worked:


; -------------------------------------------------------------------------
; Here we call the selected prog to run
; -------------------------------------------------------------------------


    invoke memfill,ADDR StartUpInfo,SIZEOF StartUpInfo,0 ; fill STARTUPINFO
   
    mov StartUpInfo.cb,SIZEOF StartUpInfo ;

    fn CreateProcess,0,DWORD PTR PtrFileName,0,0,0,0,0,0,ADDR StartUpInfo,ADDR ProcessInfo

; -------------------------------------------------------------------------


Any other solution using CRT functions?

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 04:28:33 PM
The only problem is that after I call the other console app, back from it
I've no more control, the calling prog terminates as well.

::)
Title: Re: Running an external program from an ASM running program [?]
Post by: jj2007 on September 16, 2010, 04:42:22 PM
 :wink
QuoteLaunch
   Launch "Notepad.exe"
   Launch "Notepad.exe MyNewFile.txt"
   Launch "Notepad.exe MyNewFile.txt", SW_MINIMIZE
   Launch "Notepad.exe MyNewFile.txt", SW_MAXIMIZE, 2000   ; cmd, show, timeout in ms
Rem[/color]   returns CreateProcess error code in eax
[/b]
Title: Re: Running an external program from an ASM running program [?]
Post by: Tedd on September 16, 2010, 04:43:02 PM
Prog1.exe:  CreateProcess [Prog2.exe] ==> hProcess
<Prog2.exe created>

Prog1.exe:  WaitForSingleObject [hProcess]
<Prog1.exe waiting>

Prog2.exe: ...do stuff...
<Prog2.exe exit>

Prog1.exe:  ...continue...
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 04:56:31 PM
Quote from: jj2007 on September 16, 2010, 04:42:22 PM
:wink
QuoteLaunch
   Launch "Notepad.exe"
   Launch "Notepad.exe MyNewFile.txt"
   Launch "Notepad.exe MyNewFile.txt", SW_MINIMIZE
   Launch "Notepad.exe MyNewFile.txt", SW_MAXIMIZE, 2000   ; cmd, show, timeout in ms
Rem[/color]   returns CreateProcess error code in eax
[/b]

Hi Jochen. This other one is quite new for me.  ::)

What is it? A MACRO? A function? Or what? Where do I find the documentation?

Thanks.

Quote from: Tedd on September 16, 2010, 04:43:02 PM
Prog1.exe:  CreateProcess [Prog2.exe] ==> hProcess
<Prog2.exe created>

Prog1.exe:  WaitForSingleObject [hProcess]
<Prog1.exe waiting>

Prog2.exe: ...do stuff...
<Prog2.exe exit>

Prog1.exe:  ...continue...


Well an example speaks more than 1000 words.
Here it is the complete prog, so why it closes when back from the
called prog? I surely need some other instructions, like  WaitForSingleObject [hProcess],
how and where I put it in the following code?

;-------------------------------------------------------------------------------
; Call a OpenFileDialog through a MACRO
; Select an EXE file
; Run it
; Displays some stuff when back.
;-------------------------------------------------------------------------------


include \masm32\include\masm32rt.inc

; -------------------------------------------------------------------------

.data

    ConTitle  db "  ----------     **  Example running an external prog  **     ----------", 0   


    CaptionText   BYTE  "Open Prog to Run",0

    szFilter      BYTE  "All files *.*",0,"*.*",0,
                        "Executable files *.exe",0,"*.exe",0,   
                        "Text files *.txt",0,"*.txt",0,
                        "Assembly files *.asm",0,"*.asm",0,
                        "Resource files *.rc",0,"*.rc",0,0
                       
; -------------------------------------------------------------------------

.data?

    hFile     HANDLE ?
    cci       CONSOLE_CURSOR_INFO <>       


    wHnd      HANDLE ?
    rHnd      HANDLE ?

    windowSize SMALL_RECT <>
    bufferSize COORD      <>
    startPoint COORD      <>

    howmany dd ?
    buffer  INPUT_RECORD <>     

    PtrFileName   DWORD ?   

    StartUpInfo STARTUPINFO <>
    ProcessInfo  PROCESS_INFORMATION <>         

.code

start:


; -------------------------------------------------------------------------

Main PROC

    CALL   InitProc

    CALL   ConsoleSize

    print " Press any key and choose the prog to run: ",13,10,13,10

    CALL   AnyKey   

    mov PtrFileName, OpenFileDlg (0,0, addr CaptionText, addr szFilter) 

    print " The chosen prog is: "

    print DWORD PTR PtrFileName, 13,10,13,10

    print " Press a key to run it ", 13,10,13,10

    CALL   AnyKey   
   
; -------------------------------------------------------------------------
; Here we call the selected prog to run
; -------------------------------------------------------------------------


    invoke memfill,ADDR StartUpInfo,SIZEOF StartUpInfo,0 ; fill STARTUPINFO
   
    mov StartUpInfo.cb,SIZEOF StartUpInfo ;

    INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,0,0,0,0,ADDR StartUpInfo,ADDR ProcessInfo
   
; -------------------------------------------------------------------------

    CALL   InitProc

    CALL   ConsoleSize

    CALL   ClearScreen

    print " Back from the called prog", 13,10,13,10

    CALL   AnyKey 

    CALL   ShowTheCursor

    INVOKE ExitProcess,0

    ret

Main ENDP

; -------------------------------------------------------------------------   

ConsoleSize PROC

    INVOKE SetConsoleTitle, ADDR ConTitle
 
    CALL   HideTheCursor

    INVOKE SetConsoleWindowInfo, wHnd, TRUE, ADDR windowSize

    INVOKE SetConsoleScreenBufferSize, wHnd, DWORD PTR bufferSize

    ret

ConsoleSize ENDP

; -------------------------------------------------------------------------

ShowTheCursor PROC

    INVOKE GetConsoleCursorInfo,wHnd,addr cci
    mov cci.bVisible,TRUE
    INVOKE SetConsoleCursorInfo,wHnd,addr cci
    ret
   
ShowTheCursor ENDP

; -------------------------------------------------------------------------
   


HideTheCursor PROC

    INVOKE GetConsoleCursorInfo,wHnd,addr cci
    mov cci.bVisible,FALSE
    INVOKE SetConsoleCursorInfo,wHnd,addr cci
    ret
   
HideTheCursor ENDP

; -------------------------------------------------------------------------

InitProc PROC

    INVOKE AllocConsole

    INVOKE GetStdHandle, STD_INPUT_HANDLE
    mov rHnd,eax

    INVOKE GetStdHandle, STD_OUTPUT_HANDLE
    mov wHnd,eax 

    mov windowSize.Left, 0
    mov windowSize.Right, 79
    mov windowSize.Top, 0
    mov windowSize.Bottom, 24
   

    mov bufferSize.x, 80
    mov bufferSize.y, 25

    mov startPoint.x, 0
    mov startPoint.y, 0


    ret

InitProc ENDP


; -------------------------------------------------------------------------
;Returns: key code in buffer.KeyEvent.wVirtualKeyCode WORD size
; -------------------------------------------------------------------------

AnyKey PROC

again: 

    INVOKE ReadConsoleInput,rHnd,offset buffer,1,offset howmany
    cmp buffer.EventType,KEY_EVENT
    jnz again

    cmp buffer.KeyEvent.bKeyDown,0
    jz again

    ret

AnyKey ENDP


; -------------------------------------------------------------------------

ClearScreen proc

  ; -----------------------------------------------------------
  ; This procedure reads the column and row count, multiplies
  ; them together to get the number of characters that will fit
  ; onto the screen, writes that number of blank spaces to the
  ; screen, set the screen buffer attributes and reposition
  ; the prompt at position 0,0.
  ; -----------------------------------------------------------

    LOCAL hOutPut:DWORD
    LOCAL noc    :DWORD
    LOCAL cnt    :DWORD
    LOCAL sbi    :CONSOLE_SCREEN_BUFFER_INFO

    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov hOutPut, eax

    invoke GetConsoleScreenBufferInfo,hOutPut,ADDR sbi

    mov eax, sbi.dwSize     ; 2 word values returned for screen size

  ; -----------------------------------------------
  ; extract the 2 values and multiply them together
  ; -----------------------------------------------
    mov ecx, eax
    shr eax, 16
    mul cx
    mov cnt, eax

    invoke FillConsoleOutputCharacter, hOutPut, 32, cnt, NULL, ADDR noc

    movzx ecx,sbi.wAttributes
    invoke FillConsoleOutputAttribute, hOutPut, ecx, cnt, NULL, ADDR noc

    invoke SetConsoleCursorPosition, hOutPut, NULL

    ret

ClearScreen endp


; -------------------------------------------------------------------------
 
end start           



Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: ToutEnMasm on September 16, 2010, 05:09:44 PM
Here a sample:
The called program can terminate or not with the end of the caller
Quote
invoke Execute_Independant_Win,NULL,NULL,SADR("notepad")

Quote
;################################################################
;----------------------------------------------------------------------------------------------------
Execute_Independant_Win proc hexeProg:DWORD ,NomProg:DWORD, Param:DWORD ;la ligne parametre addr
   ; processInfo   PROCESS_INFORMATION <> ;structure API
   ;---------- creer le process
   mov startInfo.cb,sizeof STARTUPINFO   
   invoke GetStartupInfo,ADDR startInfo
   invoke CreateProcess,hexeProg,Param,NULL,NULL,FALSE,\
      NORMAL_PRIORITY_CLASS,NULL,NULL,ADDR startInfo,ADDR processInfo
   .if eax == FALSE
   INVOKE     MessageBox, NULL,SADR("Execute_Independant_Win failed"),\
            SADR("CreateProcess Failed"), MB_YESNO
   .else
      ;indépendant
      invoke CloseHandle,processInfo.hProcess
      mov processInfo.hProcess,0
      invoke CloseHandle,processInfo.hThread
      mov processInfo.hThread,0
   .endif
   
FindeExecute_Independant_Win:
   ret
Execute_Independant_Win endp
;#########################################################################
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 05:14:20 PM
Quote from: ToutEnMasm on September 16, 2010, 05:09:44 PM
Here a sample:
The called program can terminate or not with the end of the caller

invoke Execute_Independant_Win,NULL,NULL,SADR("notepad")



Well, thanks ToutEnMasm.

I don't want tha called program terminates the caller, so what have I to do
in order to return back to the caller?

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: ToutEnMasm on September 16, 2010, 05:20:21 PM
The called program is independant.Just close it
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 05:23:24 PM
Quote from: ToutEnMasm on September 16, 2010, 05:20:21 PM
The called program is independant.Just close it


It doesn't work, with the example I've posted. I choose the prog, run it, but when
the called programs ends, the control is not given back to the caller.
Maybe I've done something wrong, or, as I guess, something else is missing.

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: ToutEnMasm on September 16, 2010, 05:28:30 PM

This depend where is the focus of the windows.
You can do that with the mouse (just click on the caller ) or with an API who move the focus on the caller.
Title: Re: Running an external program from an ASM running program [?]
Post by: ToutEnMasm on September 16, 2010, 05:31:24 PM
Two functions can help you:
GetFocus SetFocus
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 05:33:24 PM
Quote from: ToutEnMasm on September 16, 2010, 05:28:30 PM

This depend where is the focus of the windows.
You can do that with the mouse (just click on the caller ) or with an API who move the focus on the caller.


If I call a WIN GUI program, it works, and the control goes back to the caller, no matter
where the focus is. But if I call a console prog, as I want to, the called prog terminates also the caller.

So there is something about the new console process to check, I guess.
 
Title: Re: Running an external program from an ASM running program [?]
Post by: ToutEnMasm on September 16, 2010, 05:53:32 PM

Your program is a console program.It is the normal way for them to close after they have done something.
Have a look on the example console program in the masm32 package.
Your interrogation of the keyboard isn't good.Nothing can be write.
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 06:07:18 PM
Quote from: ToutEnMasm on September 16, 2010, 05:53:32 PM

Your program is a console program.It is the normal way for them to close after they have done something.
Have a look on the example console program in the masm32 package.
Your interrogation of the keyboard isn't good.Nothing can be write.


If you try to open a GUI program, after it finishes, the caller regains control, and
I close it when I want.
The problem is with other console programs, they inherit the same console, even
if I use INVOKE AllocConsole  in the called program.
The interrogation of the keyboard is done this way because I have only to halt
the flow, not getting any key for anything.


Title: Re: Running an external program from an ASM running program [?]
Post by: ToutEnMasm on September 16, 2010, 06:27:51 PM

This time i have found what is wrong.
Just put the ;.data? in comment or delet it and all things must run as you want.
You have a problem with bad init of variables.
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 06:47:51 PM
Quote from: ToutEnMasm on September 16, 2010, 06:27:51 PM

This time i have found what is wrong.
Just put the ;.data? in comment or delet it and all things must run as you want.
You have a problem with bad init of variables.


OK, it works. But what is or are the bad declarations?
In the .data? no variable is initialized.  ::)
Title: Re: Running an external program from an ASM running program [?]
Post by: clive on September 16, 2010, 07:01:08 PM
; ml -coff -Fl -Zi cmdasm.asm -link /SUBSYSTEM:CONSOLE

        .386

.nolist
include \masm32\include\masm32rt.inc
        .list

        .data

cmdfn   db      "notepad cmdasm.asm",0

        .code

_start:

        invoke crt_system, ADDR cmdfn

print str$(eax), 9, "returned by crt_system", 13, 10

        invoke ExitProcess, eax

        ret ; paranoia

        end _start
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 07:46:14 PM
Quote from: clive on September 16, 2010, 07:01:08 PM
; ml -coff -Fl -Zi cmdasm.asm -link /SUBSYSTEM:CONSOLE

        .386

.nolist
include \masm32\include\masm32rt.inc
        .list

        .data

cmdfn   db      "notepad cmdasm.asm",0

        .code

_start:

        invoke crt_system, ADDR cmdfn

print str$(eax), 9, "returned by crt_system", 13, 10

        invoke ExitProcess, eax

        ret ; paranoia

        end _start


Thanks clive. his is good as well.  :U

I'm trying to find out what's wrong with one of these declarations:

    StartUpInfo  STARTUPINFO <>
    ProcessInfo  PROCESS_INFORMATION <>   


because when I added them to call:


    invoke memfill,ADDR StartUpInfo,SIZEOF StartUpInfo,0 ; fill STARTUPINFO
   
    mov StartUpInfo.cb,SIZEOF StartUpInfo ;

    INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,0,0,0,0,ADDR StartUpInfo,ADDR ProcessInfo


the program doesn't return back from calling a console program, but only when
I call a GUI program it works fine.

Do you guess why?

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: jj2007 on September 16, 2010, 08:01:39 PM
Quote from: frktons on September 16, 2010, 04:56:31 PM
Quote from: jj2007 on September 16, 2010, 04:42:22 PM
:wink
QuoteLaunch
   Launch "Notepad.exe"
   Launch "Notepad.exe MyNewFile.txt"
   Launch "Notepad.exe MyNewFile.txt", SW_MINIMIZE
   Launch "Notepad.exe MyNewFile.txt", SW_MAXIMIZE, 2000   ; cmd, show, timeout in ms
Rem[/color]   returns CreateProcess error code in eax
[/b]

Hi Jochen. This other one is quite new for me.  ::)

What is it? A MACRO? A function? Or what? Where do I find the documentation?

It's Basic. Or Masm? Who knows ::)
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 08:23:47 PM
Quote from: jj2007 on September 16, 2010, 08:01:39 PM
It's Basic. Or Masm? Who knows ::)

It is not MASM, it is not BASIC, it is not a MASM32 MACRO.
mmmmmmmhhhhhhhhhh!!!!!
Well it should be Superman  :lol
Title: Re: Running an external program from an ASM running program [?]
Post by: Tedd on September 16, 2010, 08:44:52 PM
Quote from: frktons on September 16, 2010, 04:56:31 PM
Well an example speaks more than 1000 words.
Here it is the complete prog, so why it closes when back from the
called prog? I surely need some other instructions, like  WaitForSingleObject [hProcess],
how and where I put it in the following code?
Checking the API documentation is a useful skill. Things become much clearer when you actually try them out.



INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,TRUE,0,0,0,ADDR StartUpInfo,ADDR ProcessInfo
;return value is a handle to the created process (assuming it succeeds)

mov hProcess,eax   ;save it for future use

INVOKE WaitForSingleObject, hProcess,-1

;your program now waits for the process to finish,
;returning to this point when it has exited

Also, setting bInheritHandles=TRUE means the process uses the parent's console.
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 08:52:47 PM
Quote from: Tedd on September 16, 2010, 08:44:52 PM
Checking the API documentation is a useful skill. Things become much clearer when you actually try them out.

INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,0,0,0,0,ADDR StartUpInfo,ADDR ProcessInfo
;return value is a handle to the created process (assuming it succeeds)

mov hProcess,eax   ;save it for future use

INVOKE WaitForSingleObject, hProcess,-1

;your program now waits for the process to finish,
;returning to this point when it has exited



Well I guess you didn't put this code inside my example and assemble/run it, otherwise you'd have
noticed that nothing has changed adding these instructions.  ::)

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: Tedd on September 16, 2010, 09:05:03 PM
Speaking of checking the documentation.. :dazzled: (The return value isn't hProcess..)


INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,TRUE,0,0,0,ADDR StartUpInfo,ADDR ProcessInfo

mov eax,[ProcessInfo.hProcess]
INVOKE WaitForSingleObject, eax,-1

;your program now waits for the process to finish,
;returning to this point when it has exited

Also, setting bInheritHandles=TRUE means the process uses the parent's console.


Working example attached.
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 09:16:03 PM
Quote from: Tedd on September 16, 2010, 09:05:03 PM
Speaking of checking the documentation.. :dazzled: (The return value isn't hProcess..)


INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,TRUE,0,0,0,ADDR StartUpInfo,ADDR ProcessInfo

mov eax,[ProcessInfo.hProcess]
INVOKE WaitForSingleObject, eax,-1

;your program now waits for the process to finish,
;returning to this point when it has exited

Also, setting bInheritHandles=TRUE means the process uses the parent's console.


This looks far more better  :U

The content of the parent console is cleared by the child process.
If I want to retain the old content what should I set?
bInheritHandles=FALSE ?
But I already pass 0 = FALSE to CreateProcess.

Maybe I should save the content somewhere and restore it when
returning back from the called process?

  ::)
Title: Re: Running an external program from an ASM running program [?]
Post by: jj2007 on September 16, 2010, 09:49:56 PM
Quote from: Tedd on September 16, 2010, 09:05:03 PM
Also, setting bInheritHandles=TRUE means the process uses the parent's console.

What exactly does that mean? I have tried to produce this but can't see a difference:
include \masm32\MasmBasic\MasmBasic.inc ; Press F6 to assemble & link
Init
PrintLine "Ciao daddy"
Exit
end start

include \masm32\MasmBasic\MasmBasic.inc
Init
PrintLine "Ciao baby"
Launch "TheChild.exe", SW_SHOW, 100 ; do not inherit handles
PrintLine "Ciao baby"
Launch "TheChild.exe", SW_SHOW, 101 ; do inherit handles
PrintLine "Ciao baby"
Exit
end start

Output:
Ciao baby
Ciao daddy
Ciao baby
Ciao daddy
Ciao baby


So in both cases the child's output appears in the parent's console window...
::)
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 09:53:44 PM
Probably you have to compile both as /SUBSYSTEM:WINDOW
to see any difference, otherwise the child process inherit the parent's console.

This is my best guess for the time being

And moreover, it works this way  :P

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 10:09:59 PM
This is the complete program that works fine calling GUI programs
and console ones, provided that all the programs involved, caller and called
programs, are assembled and linked with the /SUBSYSTEM:CONSOLE
option.

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: Antariy on September 16, 2010, 10:24:49 PM
As far as I know - we can use CREATE_NEW_CONSOLE flag in dwCreationFlags (6th param of CreateProcess, starting from 1) - to make child with its own console.



Alex
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 10:27:37 PM
Quote from: Antariy on September 16, 2010, 10:24:49 PM
As far as I know - we can use CREATE_NEW_CONSOLE flag in dwCreationFlags (6th param of CreateProcess, starting from 1) - to make child with its own console.
Alex

Hi Alex, nice to see that your english is much better now.  :U

Yoy mean this:

INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,0,1,0,0,ADDR StartUpInfo,ADDR ProcessInfo
?
or something different?

Frank
Title: Re: Running an external program from an ASM running program [?]
Post by: Antariy on September 16, 2010, 10:35:55 PM
Hi, Frank!

No, my English is not good - just when I spent time to phrases construction - they are looks better :)
When I'm online - I hurry - my English is really AWESOME.

I meant this:

INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,0,CREATE_NEW_CONSOLE,0,0,ADDR StartUpInfo,ADDR ProcessInfo


Flags not always is triggers - usually they are set of bits - i.e. set of flags. If some flag have type BOOL - it have only two meanings: true - not null, and false - null. If flag is not BOOL-type - this can mean anything under windows :) Need to read info about API in this case. Try to find win32api.hlp - dowload it from PB site, for example.

EDITED: two mystypeing cam->can and "phrases" :)



Alex
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 16, 2010, 10:43:53 PM
Quote from: Antariy on September 16, 2010, 10:35:55 PM
Hi, Frank!

No, my English is not good - just when I spent time to phares construction - they are looks better :)
When I'm online - I hurry - my English is really AWESOME.

I meant this:

INVOKE CreateProcess,DWORD PTR PtrFileName,0,0,0,0,CREATE_NEW_CONSOLE,0,0,ADDR StartUpInfo,ADDR ProcessInfo


Flags not always is triggers - usually they are set of bits - i.e. set of flags. If some flag have type BOOL - it have only two meanings: true - not null, and false - null. If flag is not BOOL-type - this cam mean anything under windows :) Need to read info about API in this case. Try to find win32api.hlp - dowload it from PB site, for example.

Alex


Good! This flag makes compiling with /SUBSYSTEM:WINDOWS not necessary for called progs.

Much better this way  :U

I did read it into the winapi.hlp, but I didnt know how to use it. Now it is more clear.

Thanks

Frank

Title: Re: Running an external program from an ASM running program [?]
Post by: jj2007 on September 17, 2010, 09:52:01 AM
From my testing, it seems that
- bInheritHandles can be zero
- dwCreationFlags decides on a new console with CREATE_NEW_CONSOLE (so Alex was right :U)
- both parent and child must be created as console apps.
Title: Re: Running an external program from an ASM running program [?]
Post by: frktons on September 17, 2010, 10:15:41 AM
Quote from: jj2007 on September 17, 2010, 09:52:01 AM
From my testing, it seems that
- bInheritHandles can be zero
- dwCreationFlags decides on a new console with CREATE_NEW_CONSOLE (so Alex was right :U)
- both parent and child must be created as console apps.

I agree with the first two, for the third, try again.  :P

My example is compiled with /SUBSYSTEM:WINDOWS and runs an external exe that can be
both Console or GUI mode. They must not be created as console apps, both of them
can be any combination of console/GUI, and work together the same, according to my tests.

Frank