RunCMD() v0.97 : Capture stdout to variable. Non-blocking version. Pre-process/omit individual lines.
Re: RunCMD()
@SKAN Ah, I'm sorry, I misunderstood: you were approaching the issue systematically. Thanks again.
Re: RunCMD()
Perfect! I'm really looking forward to the next version now! Hoping Lexikos will find the time to approve of your addition soon (I'm assuming he has to).
Re: RunCMD()
For what it's worth, I compiled AHK_L on Win10 with @HotKeyIt's fix, and ran a test on Win7 after copying over the executable.
Code:
Result:
Success, apparently.
Thank you very much for fixing this issue, @HotKeyIt, I hope your pull request gets incorporated!
Regards,
burque505
Code:
Code: Select all
#Include RunCmd.ahk
msgbox % RunCmd("AutoHotkey-U64-10.exe /iLib NUL /ErrorStdOut " . "eurotest.ahk" . " 2>&1 |more", "", "UTF-8")
Code: Select all
C:\Users\burque505\Desktop\AHK\Command Prompt\Cerberus\eurotest.ahk (1) : ==> This line does not contain a recognized action.
Specifically: €msgbox, This is a test of UTF-8 in error messages
Thank you very much for fixing this issue, @HotKeyIt, I hope your pull request gets incorporated!
Regards,
burque505
Re: RunCMD()
@burque505
Excellent, thank you for testing.
Excellent, thank you for testing.
Re: RunCMD()
Thanks Skan you have updated a useful function that I have used too much.
Re: RunCMD()
@hasantr
Just rename the function name in your working example. It should work.
Just rename the function name in your working example. It should work.
Code: Select all
data := RunCMD("7za.exe e -so " chr(34) A_LoopFileFullPath chr(34) " content.xml")
Re: RunCMD()
It works now. Thanks.SKAN wrote: ↑23 Apr 2020, 12:29@hasantr
Just rename the function name in your working example. It should work.
Code: Select all
data := RunCMD("7za.exe e -so " chr(34) A_LoopFileFullPath chr(34) " content.xml")
Re: RunCMD()
example with wget.exe , downloads a small mp3 file / script creates a folder >>> a_desktop . "\Downloads"
I can't see streaming in Edit (Ed1) , I see when finished
what is the differend between :
-Runwait,%var%
-RunCMD(var)
I can't see streaming in Edit (Ed1) , I see when finished
what is the differend between :
-Runwait,%var%
-RunCMD(var)
Code: Select all
#warn
#Noenv
setworkingdir,%a_scriptdir%
Gui,2:default
Gui,2: -DPIScale
Gui,2:color,black,black
Gui,2:Font,s12 cYellow,Lucida Console
setbatchlines,-1
DetectHiddenWindows On
wa:=A_screenwidth
ha:=A_screenHeight
xx:=100
;-------------------- test for WGET.exe --------------------------------
f1:="http://74.136.132.35/MUSIC/RHAPSODY/J/Johnny%20Horton/American%20Originals/02%20-%20North%20To%20Alaska.mp3"
SplitPath,f1, name, dir, ext, name_no_ext, drive
name:= URLdecode(name)
wget1 =%a_scriptdir%\wget.exe
loop,%wget1% ;- create shortpath
SP1= %A_loopFileShortPath%
folderx2:= a_desktop . "\Downloads"
ifnotexist,%folderx2%
filecreatedir,%folderx2%
f2 := folderx2 . "\" . name ;- where file
VAR =%sp1% --output-document="%f2%" %f1%
;Runwait,%comspec% /k %var%
;exitapp
;----------------------------------------------------------------------
x:=(wa*1)/xx,y:=(ha*1)/xx,h:=(ha*3)/xx,w:=(wa*70)/xx
Gui,2:Add, Edit , x%x% y%y% h%h% w%w% vVAR ,%VAR%
x:=(wa*72)/xx,y:=(ha*1)/xx,h:=(ha*2.5)/xx,w:=(wa*5)/xx
Gui,2:Add, Button, x%x% y%y% w%w% h%h% gSTART1,Start
x:=(wa*1)/xx,y:=(ha*6)/xx,h:=(ha*50)/xx,w:=(wa*70)/xx
Gui,2:Add,Edit, x%x% y%y% h%h% w%w% vED1 cYellow,
Gui,2:add,Text,x0 y0 w0 h0 vTT
x:=(wa*.1)/xx,y:=(ha*.1)/xx,h:=(ha*70)/xx,w:=(wa*80)/xx
Gui,2:Show, x%x% y%y% w%w% h%h% ,SendToDOS & Copy
GuiControl,2:Focus,TT
return
;----------------------------------------------
2Guiescape:
2Guiclose:
xx=wget.exe
process,exist,%xx%
pps:=errorlevel
if pps<>0
Process, Close, %pid2%
exitapp
;----------------------------------------------
start1:
gui,2:submit,nohide
GuiControl,2:,ED1,
settimer,aa,on
;Runwait,%sp1% --output-document="%f2%" %f1% -o logfile.txt ,,hide,pid2
;Runwait,%var%,,hide,pid2
data:=""
data .= RunCMD(var) ;- <<<<<<<<<<<< SKAN OK
;settimer,aa,off
;GuiControl,2:,ED1,ENDED`nNow Start file = %name%
;try
;run,%f2%
return
;----------------------------------------------
aa:
gui,2:submit,nohide
;---------------------------------------------
;WinActivate ahk_pid %PID2%
;ClipBoard =
;send,^a{Enter} ;- <<< copy hidden DOS Windows-10 ( Runwait,%var%,,hide,pid2 )
;ClipWait
;GuiControl,2:,ED1,%Clipboard%
;sleep,100
;---------------------------------------------
; GuiControl,2: Focus,ed1
; sleep,100
; GuiControl,2:,ED1,%data% ;<<< don't see streaming data
; ControlSetText,edit2,%data%,ahk_class AutoHotkeyGUI
xx=wget.exe
process,exist,%xx%
pps:=errorlevel
if (pps=0)
{
GuiControl,2: Focus,ed1
sleep,100
GuiControl,2:,ED1,%data%`n----------------- ENDED -------------`n
sleep,100
send, ^{end}
settimer,aa,off
data:=""
try
run,%f2%
}
return
;------------------------- SKAN ------------------------------------------------------------------
;-https://www.autohotkey.com/boards/viewtopic.php?f=6&t=74647
RunCmd(CmdLine, WorkingDir:="", Cp:="CP0") { ; Thanks Sean! SKAN on D34E @ tiny.cc/runcmd
Local P8 := (A_PtrSize=8), pWorkingDir := (WorkingDir ? &WorkingDir : 0)
Local SI, PI, hPipeR:=0, hPipeW:=0, Buff, sOutput:="", ExitCode:=0, hProcess, hThread
DllCall("CreatePipe", "PtrP",hPipeR, "PtrP",hPipeW, "Ptr",0, "UInt",0)
, DllCall("SetHandleInformation", "Ptr",hPipeW, "UInt",1, "UInt",1)
VarSetCapacity(SI, P8? 104:68,0), NumPut(P8? 104:68, SI)
, NumPut(0x100, SI, P8? 60:44,"UInt"), NumPut(hPipeW, SI, P8? 88:60)
, NumPut(hPipeW, SI, P8? 96:64)
, VarSetCapacity(PI, P8? 24:16)
If not DllCall("CreateProcess", "Ptr",0, "Str",CmdLine, "Ptr",0, "UInt",0, "UInt",True
, "UInt",0x08000000 | DllCall("GetPriorityClass", "Ptr",-1,"UInt"), "UInt",0
, "Ptr",pWorkingDir, "Ptr",&SI, "Ptr",&PI )
Return Format( "{1:}", ""
, DllCall("CloseHandle", "Ptr",hPipeW)
, DllCall("CloseHandle", "Ptr",hPipeR)
, ErrorLevel := -1 )
DllCall( "CloseHandle", "Ptr",hPipeW)
, VarSetCapacity(Buff, 4096, 0), nSz:=0
While DllCall("ReadFile", "Ptr",hPipeR, "Ptr",&Buff, "UInt",4094, "PtrP",nSz, "UInt",0)
sOutput .= StrGet(&Buff, nSz, Cp)
hProcess := NumGet(PI, 0), hThread := NumGet(PI,4)
, DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode)
, DllCall("CloseHandle", "Ptr",hProcess), DllCall("CloseHandle", "Ptr",hThread)
, DllCall("CloseHandle", "Ptr",hPipeR), ErrorLevel := ExitCode
Return sOutput
}
URLdecode(str) {
Loop
If RegExMatch(str, "i)(?<=%)[\da-f]{1,2}", hex)
StringReplace, str, str, `%%hex%, % Chr("0x" . hex), All
Else Break
Return, str
}
return
;======================== END SCRIPT wget.exe TEST ==========================
Re: RunCMD()
This is not a streaming version. I didn't write one since no one asked for it.garry wrote:I can't see streaming in Edit (Ed1) , I see when finished
Also: I don't remember how wget displays.. If it displays download progress on the same line
it isn't possible to capture with this function.
With RunWait console program outputs to stdout which can be redirected to a text file and read from it.what is the differend between :
-Runwait,%var%
-RunCMD(var)
With RunCMD you get the text directly into a var avoiding a temp file creation.
Also, RunCMD can start the console utility with High process priority.
CPU intensive console apps like ffmpeg might benefit
Re: RunCMD()
@SKAN, thank you for explanation , short summarized : not streaming version , see result when finished in a variable and it's better for CPU intensive programs ....
Re: RunCMD()
@garry, I get the feeling from your example you might like TheArkive's CliSAK (CLI Swiss Army Knife) for it. It has a callback function that _may_ work with wget.exe, although I haven't tested it. The examples on the posting page are pretty comprehensive.
Regards,
burque505
Regards,
burque505
Re: RunCMD()
@burque505, thank you , I'll try CliSAK , at the moment was playing with a dos-help script and RunCMD()
Re: RunCMD()
How can I interrupt after starting my work. If the process takes too long, I would like to be able to cancel it.
Re: RunCMD()
@hasantr & @SKAN: This
seems to work…, however it will slow down the function a bit.
Code: Select all
While !GetKeyState("Pause", "P") && DllCall("ReadFile", "Ptr",hPipeR, "Ptr",&Buff, "UInt",4094, "PtrP",nSz, "UInt",0)
sOutput .= StrGet(&Buff, nSz, Cp)
RunCMD() - Code updated
Thanks.rommmcek wrote:GetKeyState("Pause", "P")
Works well.. but I feel uncomfortable to use it. I've updated the code to use the global A_Args array instead.
A_Args.RunCMD.PID will now contain the PID of the console process.
I'm not sure whether it will create a problem in a race condition.
@hasantr
Function updated.
You may call A_Args.RunCMD.PID := 0 from a hotkey or routine to exit gracefully... or
call Process, Close, % A_Args.RunCMD.PID to terminate.
If anyone needs a long running process to test the updated function, try this: MsgBox % RunCmd(A_Comspec . " /c Dir *.* /s", "C:")
Re: RunCMD()
Great! Purely theoretically, this would perform more efficient:
But piping by itself might be slower then additional condition check...
I'll probably do the test in days to come.
Code: Select all
While A_Args.RunCMD.PID
* DllCall("ReadFile", "Ptr",hPipeR, "Ptr",&Buff, "UInt",4094, "PtrP",nSz, "UInt",0)
I'll probably do the test in days to come.
Re: RunCMD()
Very nice! I like it. . I might use it in my personal version.rommmcek wrote:Great! Purely theoretically, this would perform more efficient:Code: Select all
While A_Args.RunCMD.PID * DllCall("ReadFile", "Ptr",hPipeR, "Ptr",&Buff, "UInt",4094, "PtrP",nSz, "UInt",0)
Please do. Thanks for your valuable feedback!rommmcek wrote:But piping by itself might be slower then additional condition check...
I'll probably do the test in days to come.