RunCMD() v0.94 : Capture stdout to variable. Non-blocking version. Pre-process/omit individual lines.

Post your working scripts, libraries and tools
guest3456
Posts: 3123
Joined: 09 Oct 2013, 10:31

Re: RunCMD()

21 Jun 2020, 11:25

hi SKAN

why do you avoid the PeekNamedPipe call that many of the newer iterations of StdOutToVar have used?

https://www.autohotkey.com/boards/viewtopic.php?f=6&t=791

burque505
Posts: 1337
Joined: 22 Jan 2017, 19:37

Re: RunCMD()

21 Jun 2020, 11:36

@garry, this works for wget.

Code: Select all

#SingleInstance, Force
#Include RunCmd.ahk
;varout := StdOutStream("cmd.exe /c %comspec% /c C:\msys64\usr\bin\wget.exe https://wordpress.org/latest.zip") ; prior attempt using stdout2var.ahk
varout := RunCmd("C:\msys64\usr\bin\wget.exe https://wordpress.org/latest.zip")
msgbox %varout%
Thanks again, @SKAN!
User avatar
SKAN
Posts: 667
Joined: 29 Sep 2013, 16:58

Re: RunCMD()

21 Jun 2020, 12:00

guest3456 wrote:
21 Jun 2020, 11:25
why do you avoid the PeekNamedPipe call that many of the newer iterations of StdOutToVar have used?
No, I'm not avoiding.
1) Sean would've used it had he found it to be better. (He was thorough with API functions)
2) I'm yet to find a CLI utility that hangs.. I need a problem to compare and find if PeekNamedPipe() is better.

:)
guest3456
Posts: 3123
Joined: 09 Oct 2013, 10:31

Re: RunCMD()

21 Jun 2020, 12:18

fair enough :thumbsup:

garry
Posts: 2345
Joined: 22 Dec 2013, 12:50

Re: RunCMD()

21 Jun 2020, 12:43

@burque505
@SKAN
thank you very much , works fine ( example with wget.exe )

Code: Select all

;- https://www.autohotkey.com/boards/viewtopic.php?f=6&t=74647&start=60

;- example downloads a mp3-file to folder C:\users\%a_username%\Downloads ( normal downloadfolder ) 
;---------------------
#SingleInstance, Force
#Include RunCmd.ahk
;---------------------
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)                            ;- remove %20 etc in filename
wget1:="D:\M_GARRY\PROGRAMME_SA\WGET\wget.exe"    ;- <<< here is wget.exe
 loop,%wget1%                                     ;- create shortpath
   SP1:=A_loopFileShortPath
folderx2:="C:\Users\" . a_username . "\Downloads" ;- <<< Download_folder        
ifnotexist,%folderx2%
 filecreatedir,%folderx2%
f2  := folderx2 . "\" . name                      ;- File-fullpath
transform,s,chr,34
;--------------
VAR:=sp1 . " --output-document=" . s . f2 . s . " " . f1  ;- wget downloads file to defined folder 
varout:=Runcmd(var)
msgbox %varout%                                   ;- see variable ( wget-finished )
;run,%folderx2%  ;- open folder
;run,%f2%        ;- run file
return
;--------------
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
;============================================================
burque505
Posts: 1337
Joined: 22 Jan 2017, 19:37

Re: RunCMD()

21 Jun 2020, 16:39

@garry, your code works great.
Regards,
burque505
xml123
Posts: 7
Joined: 01 Jun 2020, 18:55

Re: RunCMD()

21 Jun 2020, 20:04

burque505 wrote: I've been trying to figure out where I found this code, cli_stdio.ahk.
Thank you! That solves my problem, but not perfectly. Still a little problem about encoding. Anyway, thanks for your script.
burque505
Posts: 1337
Joined: 22 Jan 2017, 19:37

Re: RunCMD()

22 Jun 2020, 07:22

@xml123, I'm glad it was at least of some help.
Have you tried (pick the correct code page)

Code: Select all

cli_stdout("","65001")
or

Code: Select all

cli_stdin("","65001")
for the encoding problem?
Regards,
burque505
xml123
Posts: 7
Joined: 01 Jun 2020, 18:55

Re: RunCMD()

22 Jun 2020, 09:46

@burque505
It work! Now the scripts works perfectly. Thanks for your generous help.
burque505
Posts: 1337
Joined: 22 Jan 2017, 19:37

Re: RunCMD()

22 Jun 2020, 10:05

@xml123, I'm glad it worked for you. If you are able to share any of your code, I'm sure I could learn from it. I've never coded anything using cli_stdio.ahk myself, I just found it lurking in my file system. :D
Regards,
burque505
xml123
Posts: 7
Joined: 01 Jun 2020, 18:55

Re: RunCMD()

22 Jun 2020, 10:23

@burque505
Just a simple piece of code. Of course I can show it if you don't mind this.
I'm using sublimetext as my text editor. There is a cli version "subl.exe", which can be used like this: "subl [arguments] - Edit stdin". I want to create a shortcut that copy what I'm selecting directly into sublimetext instead of open the editor then copy and paste. Here is my code.

Code: Select all

#include lib/cli_stdio.ahk
!s::
	Send, ^c
	ClipWait
	cli_createprocess("C:\Program Files\SublimeText\subl.exe -")
	cli_stdin(Clipboard,"UTF-8")
	cli_close()
return
burque505
Posts: 1337
Joined: 22 Jan 2017, 19:37

Re: RunCMD()

22 Jun 2020, 10:38

@xml123, thanks, I'll try it. I have Sublime Text available, I think.

EDIT: Thanks, works great! For my system I used this. I had to add a sleep command to wait for the program to load before pasting.

Code: Select all

#include cli_stdio.ahk
!u::
	Send, ^c
	ClipWait
	cli_createprocess("C:\Program Files\Sublime Text 3\subl.exe mytext.txt")
	cli_stdin(Clipboard,"UTF-8")
	sleep 2000
	Send, ^v
	cli_close()
return
Regards,
burque505
Last edited by burque505 on 23 Jun 2020, 07:40, edited 1 time in total.
xml123
Posts: 7
Joined: 01 Jun 2020, 18:55

Re: RunCMD()

22 Jun 2020, 20:01

@burque505
Maybe you misunderstood me. The parameter - is necessary. In your situation the command should be C:\Program Files\Sublime Text 3\subl.exe mytext.exe -. In this case, you needn't sleep or send ctrl+v.

Append:
You are right. The versions of sublime text we use are different. I'm using the beta version 4074. Here is my help.

Code: Select all

Sublime Text build 4074

Usage: subl [arguments] [files]         Edit the given files
   or: subl [arguments] [directories]   Open the given directories
   or: subl [arguments] -- [files]      Edit files that may start with '-'
   or: subl [arguments] -               Edit stdin
   
 ...
It seems that build 3211 doesn't support editing stdin. Therefore the command cli_stdin(Clipboard,"UTF-8") is useless.
Cause it is really off-topic, I shouldn't add more posts about sublime.
Last edited by xml123 on 23 Jun 2020, 10:16, edited 2 times in total.
burque505
Posts: 1337
Joined: 22 Jan 2017, 19:37

Re: RunCMD()

23 Jun 2020, 07:43

@xml123, thanks, I did misunderstand (I also edited my post above to reflect 'mytext.txt', not 'mytext.exe', which was a typo).

However, I just tried it, and it doesn't work with my installation. Rather, it opens two text files ('mytext.txt' and '-') and, without a sleep command and ctrl+v it pastes nothing.

Perhaps the command line options in our respective versions are different?

Here's what they are in mine:

Code: Select all

Sublime Text build 3211

Usage: subl [arguments] [files]         Edit the given files
   or: subl [arguments] [directories]   Open the given directories

Arguments:
  --project <project>: Load the given project
  --command <command>: Run the given command
  -n or --new-window:  Open a new window
  -a or --add:         Add folders to the current window
  -w or --wait:        Wait for the files to be closed before returning
  -b or --background:  Don't activate the application
  -s or --stay:        Keep the application activated after closing the file
  -h or --help:        Show help (this message) and exit
  -v or --version:     Show version and exit

Filenames may be given a :line or :line:column suffix to open at a specific
location.
PS: This is getting pretty far off-topic from the OP. ;)

Regards,
burque505
Sam_
Posts: 125
Joined: 20 Mar 2014, 20:24

Re: RunCMD()

02 Jul 2020, 10:35

This function is awesome! Thank you for sharing it.
SKAN wrote:
23 Apr 2020, 16:55
This is not a streaming version. I didn't write one since no one asked for it.
Will you pretty please also provide a streaming version?
User avatar
SKAN
Posts: 667
Joined: 29 Sep 2013, 16:58

Re: RunCMD()

02 Jul 2020, 17:45

Sam_ wrote:This function is awesome! Thank you for sharing it.
Thank you. :)
Sam_ wrote:Will you pretty please also provide a streaming version?
Quickly written.. not well tested. I will try to post a proper demo later. (streaming to an edit control)

Code: Select all

RunCmd_Stream(CmdLine, WorkingDir:="", Cp:="CP0") {           ; v0.90 by SKAN on D34E/D373  
  Local                                                       ;           @ tiny.cc/runcmd
  Global A_Args

  DllCall("CreatePipe", "PtrP",hPipeR:=0, "PtrP",hPipeW:=0, "Ptr",0, "UInt",0)
, DllCall("SetHandleInformation", "Ptr",hPipeW, "UInt",1, "UInt",1)

, P8 := (A_PtrSize=8),            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),  pWorkingDir := (WorkingDir ? &WorkingDir : 0)               

  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:}", "", ErrorLevel := -1 
          , DllCall("CloseHandle", "Ptr",hPipeW)
          , DllCall("CloseHandle", "Ptr",hPipeR) )
 
  DllCall("CloseHandle", "Ptr",hPipeW), A_Args.RunCMD := {"PID":NumGet(PI,P8?16:8,"UInt")}
  File := FileOpen(hPipeR, "h", Cp), Line := ""

  While (Line := File.ReadLine())
    If not RunCmd_Output(Line, A_Index)
      Break  

  A_Args.RunCMD.PID := 0,  hProcess := NumGet(PI,0),  hThread := NumGet(PI,4)
, DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode:=0)
, DllCall("CloseHandle", "Ptr",hProcess),    DllCall("CloseHandle", "Ptr",hThread)
, DllCall("CloseHandle", "Ptr",hPipeR)
Return ExitCode  
}




; Quick test follows:

#NoEnv
#Warn
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
Process, Priority,,High

RunCmd_Stream(A_Comspec . " /c Dir *.*",  A_AhkPath . "\..\")
SoundBeep
Return                          ; end of auto-execute section

RunCmd_Output(Line, LineNum) {
  Sleep 1
  MsgBox % Line . "#" LineNum
;Return False ; Cancel
Return True  ; Continue 
}
User avatar
SKAN
Posts: 667
Joined: 29 Sep 2013, 16:58

RunCMD() v0.93

08 Jul 2020, 18:40

Code updated:
New non-blocking version with streaming support. Check out the demo in title post.
Image
User avatar
elModo7
Posts: 167
Joined: 01 Sep 2017, 02:38
GitHub: elModo7
Location: Spain
Contact:

Re: RunCMD() v0.93 : Capture stdout to variable. Non-blocking version. Pre-process/omit individual lines.

09 Jul 2020, 10:56

I had used a few methods to run cmds and retrieve their output, your seems the most complete and versatile, also the real time stream ret seems something I will be using for a few projects.
Thank you for your hard work @SKAN it really is well appreciated! :clap:
:beer:
User avatar
SKAN
Posts: 667
Joined: 29 Sep 2013, 16:58

Re: RunCMD() v0.93 : Capture stdout to variable. Non-blocking version. Pre-process/omit individual lines.

09 Jul 2020, 13:15

burque505 wrote:
09 Jul 2020, 07:58
Nice, @SKAN, thank you!! :bravo:
 
:) :thumbup:
Do let me know if documentation needs to be better.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 25 guests