Page 2 of 2

Re: [FUNCTION] StdoutToVar with exit code

Posted: 20 Dec 2014, 06:50
by cyruz
Ajdaha wrote:Hi and thanks for this usefull function.

I just want to know is there a way to this function runs process with admin privilages? (I don't want to run my entire script as admin!)

I mean something like this "Run *RunAs ..." happen inside of the function!
(I'm genius and I know it! :v)
It should be possible, but you need to replace the CreateProcess system call with CreateProcessAsUser. You need to create a new token... It's not simple.

Re: [FUNCTION] StdoutToVar with exit code

Posted: 15 Jul 2016, 09:47
by menteith
Does this function work on Windows 10? I tested it on Win 7 x64 and there is no problem but on Windows 10 32bit EN-GB the following script starts and does nothing. There is only freezed icon in the taskbar.

Code: Select all

out := StdoutToVar_CreateProcess("cmd.exe /k dir c:\","CP1")
MsgBox % out
Return

; ----------------------------------------------------------------------------------------------------------------------
; Function .....: StdoutToVar_CreateProcess
; Description ..: Runs a command line program and returns its output.
; Parameters ...: sCmd      - Commandline to execute.
; ..............: sEncoding - Encoding used by the target process. Look at StrGet() for possible values.
; ..............: sDir      - Working directory.
; ..............: nExitCode - Process exit code, receive it as a byref parameter.
; Return .......: Command output as a string on success, empty string on error.
; AHK Version ..: AHK_L x32/64 Unicode/ANSI
; Author .......: Sean (http://goo.gl/o3VCO8), modified by nfl and by Cyruz
; License ......: WTFPL - http://www.wtfpl.net/txt/copying/
; Changelog ....: Feb. 20, 2007 - Sean version.
; ..............: Sep. 21, 2011 - nfl version.
; ..............: Nov. 27, 2013 - Cyruz version (code refactored and exit code).
; ..............: Mar. 09, 2014 - Removed input, doesn't seem reliable. Some code improvements.
; ..............: Mar. 16, 2014 - Added encoding parameter as pointed out by lexikos.
; ..............: Jun. 02, 2014 - Corrected exit code error.
; ----------------------------------------------------------------------------------------------------------------------
StdoutToVar_CreateProcess(sCmd, sEncoding:="CP0", sDir:="", ByRef nExitCode:=0) {
    DllCall( "CreatePipe",           PtrP,hStdOutRd, PtrP,hStdOutWr, Ptr,0, UInt,0 )
    DllCall( "SetHandleInformation", Ptr,hStdOutWr, UInt,1, UInt,1                 )
 
            VarSetCapacity( pi, (A_PtrSize == 4) ? 16 : 24,  0 )
    siSz := VarSetCapacity( si, (A_PtrSize == 4) ? 68 : 104, 0 )
    NumPut( siSz,      si,  0,                          "UInt" )
    NumPut( 0x100,     si,  (A_PtrSize == 4) ? 44 : 60, "UInt" )
    NumPut( hStdInRd,  si,  (A_PtrSize == 4) ? 56 : 80, "Ptr"  )
    NumPut( hStdOutWr, si,  (A_PtrSize == 4) ? 60 : 88, "Ptr"  )
    NumPut( hStdOutWr, si,  (A_PtrSize == 4) ? 64 : 96, "Ptr"  )
 
    If ( !DllCall( "CreateProcess", Ptr,0, Ptr,&sCmd, Ptr,0, Ptr,0, Int,True, UInt,0x08000000
                                  , Ptr,0, Ptr,sDir?&sDir:0, Ptr,&si, Ptr,&pi ) )
        Return ""
      , DllCall( "CloseHandle", Ptr,hStdOutWr )
      , DllCall( "CloseHandle", Ptr,hStdOutRd )
 
    DllCall( "CloseHandle", Ptr,hStdOutWr ) ; The write pipe must be closed before reading the stdout.
    VarSetCapacity(sTemp, 4095)
    While ( DllCall( "ReadFile", Ptr,hStdOutRd, Ptr,&sTemp, UInt,4095, PtrP,nSize, Ptr,0 ) )
        sOutput .= StrGet(&sTemp, nSize, sEncoding)
 
    DllCall( "GetExitCodeProcess", Ptr,NumGet(pi,0), UIntP,nExitCode )
    DllCall( "CloseHandle",        Ptr,NumGet(pi,0)                  )
    DllCall( "CloseHandle",        Ptr,NumGet(pi,A_PtrSize)          )
    DllCall( "CloseHandle",        Ptr,hStdOutRd                     )
    Return sOutput
}

Re: [FUNCTION] StdoutToVar with exit code

Posted: 15 Jul 2016, 12:27
by Joe Glines
It hung for me as well. I'm running 64 bit Win10 and 32-bit AutoHotkey_L.

Re: [FUNCTION] StdoutToVar with exit code

Posted: 16 Jul 2016, 05:16
by qwerty12
menteith wrote:Does this function work on Windows 10?
Well, no, in this case because you're telling cmd to remain present after running dir. This function can't get the exit code until the child process terminates. Use cmd /C.

EDIT: My reasoning probably isn't right, as I wrongly assumed this function waited on the process's termination via waiting on the handle. In any case, leaving cmd behind wouldn't be the right thing to do IMHO.

EDIT: Thank you, cyruz, for the proper explanation and for updating your function. I don't use this, but your TermWait is a god send.

Re: [FUNCTION] StdoutToVar with exit code

Posted: 16 Jul 2016, 05:22
by menteith
It did the trick, thanks. It is quite weird, however, because my initial code "cmd /k" works fine on Win 7.

Re: [FUNCTION] StdoutToVar with exit code

Posted: 02 Nov 2016, 04:00
by cyruz
Hello, this is probably due to the fact that the ReadFile is blocking. It has something to do with how the pipe are managed on Windows 10 i suppose, but it's something hard to debug.

Just for info this code has a problem if the child process does not flush its buffers in a timely manner. The ReadFile will be stuck until there will be some data in the pipe buffer and the autohotkey thread will be frozen (GUIs will be unresponsive). I just updated the function with a new version that checks pipe content first so it avoids any freezings.

Re: [FUNCTION] StdoutToVar with exit code

Posted: 16 Oct 2017, 08:05
by xuezhe
perfect.

Re: [FUNCTION] StdoutToVar with exit code

Posted: 07 May 2018, 18:23
by zhanglei1371
I used the code below,but nothing get,why?

msgbox % StdoutToVar_CreateProcess("dir c:\")
but if I used :
msgbox % StdoutToVar_CreateProcess("ping www.baidu.com"),it works.

Re: [FUNCTION] StdoutToVar with exit code

Posted: 07 May 2018, 19:09
by burque505
Hi zhanglei1371, try this:

Code: Select all

#Include StdOutToVar.ahk
msgbox % StdoutToVar_CreateProcess("cmd.exe /c dir c:\")
This works too:

Code: Select all

msgbox % StdoutToVar_CreateProcess(Comspec " /c dir c:\")
Regards,
burque505

Re: [FUNCTION] StdoutToVar with exit code

Posted: 15 May 2018, 07:35
by zhanglei1371
burque505 wrote:Hi zhanglei1371, try this:

Code: Select all

#Include StdOutToVar.ahk
msgbox % StdoutToVar_CreateProcess("cmd.exe /c dir c:\")
This works too:

Code: Select all

msgbox % StdoutToVar_CreateProcess(Comspec " /c dir c:\")
Regards,
burque505
ManyThx,it works!

Re: [FUNCTION] StdoutToVar with exit code

Posted: 15 May 2018, 07:53
by burque505
:) Glad to hear it!
Regards,
burque505