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

Post your working scripts, libraries and tools
User avatar
SKAN
Posts: 850
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:16

elModo7 wrote:
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:
Thank you :)
lexikos
Posts: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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

10 Jul 2020, 23:31

SKAN wrote:, hThread := NumGet(PI,4)
This seems to be incorrect for x64. hThread would be at offset A_PtrSize.
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

11 Jul 2020, 19:07

lexikos wrote:
10 Jul 2020, 23:31
SKAN wrote:, hThread := NumGet(PI,4)
This seems to be incorrect for x64. hThread would be at offset A_PtrSize.
Yes. :oops:
Thank you very much. :) :thumbup:
Code has been fixed.
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

Powershell w/ RunCMD() v0.94

11 Jul 2020, 19:08

If you have Window 7 and never used powershell, you probably have Powershell v2.0 installed.
Some of the following examples would require Powershell v5.1

Check Powershell version

Code: Select all

MsgBox % RunCMD("powershell Get-Host | Select-Object Version")
 
Read n tail lines from a text file.
The following reads last 13 lines from AutoHotkey's license.txt. (I also tested with a local 3GB text file.. works fine)

Code: Select all

MsgBox % RunCMD("powershell Get-Content 'license.txt' -Tail 13", A_AhkPath . "\..\")
 
Create an empty temp file and return fullpath

Code: Select all

MsgBox % RunCMD("powershell (New-TemporaryFile).fullname")
 
Random: Generate a random number for given range / Pick a random name from an object

Code: Select all

MsgBox % RunCMD("powershell Get-Random -Minimum 100 -Maximum 1000")
MsgBox % RunCMD("powershell Get-Random -InputObject 'John','Sean','Naomi','Maura','Neula'")
 
UrlGetText from http

Code: Select all

MsgBox % RunCMD("powershell Invoke-RestMethod -Uri http://expandurl.com/api/v1/?url=ahkscript.org")
 
UrlGetText from https
Note: Multiple commands may be passed provided commands are delimited with a semi-colon

Code: Select all

MsgBox % RunCMD("powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;"
              . "Invoke-RestMethod -Uri 'https://autohotkey.com/download/1.1/version.txt'")
 
UrlEncode / UrlDecode

Code: Select all

MsgBox % RunCMD("powershell Add-Type -AssemblyName System.Web;"
              . "[System.Web.HttpUtility]::UrlEncode('https://www.autohotkey.com/')")

MsgBox % RunCMD("powershell Add-Type -AssemblyName System.Web;"
              . "[System.Web.HttpUtility]::UrlDecode('https%3a%2f%2fwww.autohotkey.com%2f')")
 
Compute foldersize

Code: Select all

MsgBox % RunCMD("powershell (gci '" A_DeskTop "' -Recurse | Measure-Object -Property Length -sum).sum")
 
Compute Hash for a file

Code: Select all

MsgBox % RunCMD("powershell (Get-FileHash '" A_AhkPath "' -Algorithm SHA256).hash")
burque505
Posts: 1396
Joined: 22 Jan 2017, 19:37

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

12 Jul 2020, 08:26

Thanks again, @SKAN! All examples work for me on Win7.
Regards,
burque505
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

12 Jul 2020, 08:31

burque505 wrote:All examples work for me on Win7.
Thanks for the feedback. :) :thumbup:
May I know powershell version?
burque505
Posts: 1396
Joined: 22 Jan 2017, 19:37

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

12 Jul 2020, 09:25

Sure! Win7 SP1 64-bit, AHK 1.1.33.00

Code: Select all

---------------------------
Version: 5.1.14409.1018
Regards,
burque505
gwarble
Posts: 461
Joined: 30 Sep 2013, 15:01

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

13 Jul 2020, 19:10

awesome thanks for sharing

powershell sure adds a lot of bloat, even an empty folder is 10 times slower than robocopy... anyone know how robocopy does this so fast?

Code: Select all

FolderSize(folder) { ;gwarble 2020 - any faster method to get folder size?
Loop, Parse, % RunCMD("robocopy /l /nfl /ndl " folder " . /r:0 /w:0 /e /bytes"), `n, `r
 If InStr(A_LoopField,"Bytes :") ;thanks SKAN for RunCMD()
  For each, z in StrSplit(RegExReplace(A_LoopField, "\s+", " "), " ")
   If (A_Index = 4) ;probably much better ways to parse result
    Return z
}
also thanks to SKAN, FormatBytes() is useful for the results: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=3567
Last edited by gwarble on 14 Jul 2020, 08:57, edited 3 times in total.
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

14 Jul 2020, 03:26

gwarble wrote:
13 Jul 2020, 19:10
awesome thanks for sharing
Thanks for the feedback :)
powershell sure adds a lot of bloat, even an empty folder is 10 times slower than robocopy...
Yes. Powershell is too slow. Nice func.. Thanks for sharing. :)
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

14 Jul 2020, 16:57

@gwarble.

Thanks again. robocopy takes only 9 secs to scan entire C drive. :thumbup:
Spoiler
 
I've added the following version to my AHK lib.
 

Code: Select all

FolderSize(P*) {   ; modified by SKAN    @ autohotkey.com/boards/viewtopic.php?p=341757#p341757 
  If (P.Count()=2) ; Original by gwarble @ autohotkey.com/boards/viewtopic.php?p=341577#p341577
    Return InStr(P[1],"Bytes :") ? StrSplit(Trim(SubStr(P[1], 11, 20))," ").1 : ""
Return RunCMD("robocopy /l /nfl /ndl " P[1] " . /r:0 /w:0 /e /bytes",,, A_ThisFunc)
}
gwarble
Posts: 461
Joined: 30 Sep 2013, 15:01

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

14 Jul 2020, 17:54

you're welcome, I would like to duplicate this speed with some native method, Xtra posted a COM method that is faster when permissions don't halt it...

for me c:\ is 211gb only takes robocopy 13.2 seconds [on old core2 duo 2.4ghz 4gb win7 64]

also in that time you also get more data for free, like the number of folders and number of files, can you turn this into an elegant method like above:

Code: Select all

Loop, Parse, _, `n, `r 
{
 If InStr(A_LoopField,"Dirs :")
  For each, z in StrSplit(RegExReplace(A_LoopField, "\s+", " "), " ")
   If (A_Index = 4)
    Dirs := z - 1 ;just for consistency with explorer properties results
 If InStr(A_LoopField,"Files :")
  For each, z in StrSplit(RegExReplace(A_LoopField, "\s+", " "), " ")
   If (A_Index = 4)
    Files := z
 If InStr(A_LoopField,"Bytes :")
  For each, z in StrSplit(RegExReplace(A_LoopField, "\s+", " "), " ")
   If (A_Index = 4)
    Bytes := z
}

  MsgBox, % "  Dirs: " Dirs "`n Files: " Files "`n   Size: " FormatBytes(Bytes)
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

14 Jul 2020, 19:44

gwarble wrote:you also get more data for free, like the number of folders and number of files
Yes. Definitely an advantage.
I'm not familiar with robocopy command line options. Can I recurse for particular file extension(s)?

Edit: Ok! Figured it out. The dot is destination folder. I was replacing it with wildcards.
gwarble
Posts: 461
Joined: 30 Sep 2013, 15:01

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

14 Jul 2020, 20:08

yes (and there are a ton of useful options for copying as well, just be careful if you remove the /L it will actually do stuff not just report info)

MsgBox, % FolderSize(A_Desktop " *.ahk")

notice the space before the wildcard *, the "file" parameter to robocopy is seperate from the source folder

Edit: yes the dot is the unused destination, was the shortest I could come up with... the example I learned from used \\localhost\c$\nul for some reason I couldn't figure out, and c: might not always exist so I didn't like it
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

15 Jul 2020, 12:27

gwarble wrote:yes (and there are a ton of useful options for copying as well, just be careful if you remove the /L it will actually do stuff not just report info)
Yes. That gives me a plan.
Run first time with /L and get the size
Run it it again with /L and /NFL removed so that it streams fullpath and size.
No we can show a proper progress-bar with a helper function.
gwarble wrote: Edit: yes the dot is the unused destination, was the shortest I could come up with... the example I learned from used \\localhost\c$\nul for some reason I couldn't figure out, and c: might not always exist so I didn't like it
Neat. BTW, \ also seems to work.
User avatar
TheArkive
Posts: 382
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

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

15 Jul 2020, 13:20

@SKAN
I'm dying to know ... how did you get to actually capture a progress bar on the command line ... in that tiny little function? ... that is impressive man
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

15 Jul 2020, 14:17

TheArkive wrote:I'm dying to know ... how did you get to actually capture a progress bar on the command line ... in that tiny little function? ...
I only said That gives me a plan.

It is technically feasible, but I don't have code yet. I should get familiar with robocopy first. I'll try to post a demo.
:)
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

15 Jul 2020, 18:10

Hi @TheArkive

Here is the demo. I'm still not well versed with RoboCopy options. Maybe @gwarble can pitch in.
The following copies all texts files in C:\Program Files to D:\Text_. Change target folder if it already exists.
You need to copy/paste RunCMD() in to the demo or #include it.
Progress' Close button will cancel RunCMD()

Code: Select all

#NoEnv
#SingleInstance, Force

MsgBox % "ExitCode = " . RoboCopyPro("""C:\Program Files"" *.txt ""D:\Text_"" /IS /S")
Return



RoboCopyPro(P*) {
Static TOTAL:=0, FTOTAL:=0, WRITE:=0, FWRITE:=0, VAR, N:=VarSetCapacity(VAR,16,0)
Static SPATH := Format("{:260}",""), F:=0, PROG:=0, LINE:="", TEXT:=""
Global A_Args
  If ( TOTAL ) 
  {
    If ! WinExist("RoboCopy Progress ahk_class AutoHotkey2")
      Return % ("", A_Args.RunCMD.PID:=0)
     
    If ! (F:=StrSplit(P[1], A_Tab, A_Space)).4
      Return

    WRITE += F[4], Prog := Round((WRITE/TOTAL)*100)
    DllCall("shlwapi.dll\PathCompactPathEx", "Str",SPATH, "Str",F[5], "Int",60 )
    FWRITE := DllCall("Shlwapi\StrFormatByteSize64A", "Int64",WRITE, "Str",VAR, "Int",16, "AStr")
    Progress, 4:%Prog%, %FWRITE% out of %FTOTAL% `t`t %PROG%`%, %sPath%, RoboCopy Progress, Segoe UI

    Sleep 100  ; RoboCopy is too fast! Slowing it down to reduce text update flicker!
    Return  
  }

  Progress, 4: M2 C00 zX25 ZY15 ZH20 W480 WM400 WS400 FM10 FS10, 0`%, Calculating size...
          , RoboCopy Progress, Segoe UI

  TEXT := RunCMD("ROBOCOPY " . P[1] . " /R:0 /W:0 /BYTES /NFL /NDL /NJH /L")
  Loop, Parse, TEXT, `n, `r
   If InStr(LINE:=A_LoopField, "Bytes :")
     Break

  If ! (TOTAL := StrSplit(Trim(SubStr(LINE, 11, 20))," ").1)
    Return   

  FTOTAL := DllCall("Shlwapi\StrFormatByteSize64A", "Int64",TOTAL, "Str",VAR, "Int",16, "AStr") 
  Progress, 4:, %FTOTAL%, Calculating size...`n, RoboCopy Progress, Segoe UI

  RunCMD("ROBOCOPY " . P[1] . " /R:0 /W:0 /BYTES /NDL /NJH /NJS",,,A_ThisFunc) 
  TOTAL := 0
  VAR := ErrorLevel
  Sleep 1000
  Progress, 4:Off
Return VAR
}
 
  • 20200716042540.png
    20200716042540.png (6.33 KiB) Viewed 1546 times
 
RoboCopy options
https://social.technet.microsoft.com/wiki/contents/articles/1073.robocopy-and-a-few-examples.aspx
gwarble
Posts: 461
Joined: 30 Sep 2013, 15:01

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

15 Jul 2020, 18:36

beautiful

i’m not an expert on robocopy but the google machine is

while i always prefer native ahk vs using an external program or library, sometimes results are more important and robocopy delivers

its been around since the NT days to so i like to think its as robust (failsafe?) as the name suggests, plus i can’t help thinking about Robotron: 2084 (the best arcade game of all time) when I use it so thats a plus
6084E882-971A-432E-8635-C72F4FCEA83B.jpeg
6084E882-971A-432E-8635-C72F4FCEA83B.jpeg (1.42 MiB) Viewed 1361 times
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
SKAN
Posts: 850
Joined: 29 Sep 2013, 16:58

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

16 Jul 2020, 09:43

@gwarble
beautiful
Thank you :)
while i always prefer native ahk vs using an external program or library, sometimes results are more important and robocopy delivers
True. I'm fascinated by the mirror facility robocopy offers.
its been around since the NT days to so i like to think its as robust (failsafe?) as the name suggests
I think I might have tried it once long time before... I will put it to good use this time.

Thanks. :)

Return to “Scripts and Functions”

Who is online

Users browsing this forum: mcl and 18 guests