Page 10 of 13

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

Posted: 26 Feb 2022, 13:59
by SKAN
BoBo wrote:
26 Feb 2022, 13:56
It's not using com.exe but diskpart.exe and its command set within its own shell, similar to a power-shell client.
Ah! In which case you could run a script?.. but that will defeat the purpose of RunCMD(). :roll:

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

Posted: 26 Feb 2022, 14:59
by BoBo
There's no way to get its stdout transferred into a variable without using a file. Kind of desperate attempt :lolno: :roll:
I've no idea why MS isn't allowing to use ' | Clip' but is restricting it to a file.

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

Posted: 26 Feb 2022, 15:13
by SKAN
BoBo wrote:
26 Feb 2022, 14:59
There's no way to get its stdout transferred into a variable without using a file.
I see.
So if there is no single "command" to Run and capture StdOut, then RunCMD() isn't a candidate, IMO.

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

Posted: 26 Feb 2022, 15:50
by BoBo
Nevermind :wave:

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

Posted: 28 Feb 2022, 23:34
by Finallf
HotKeyIt wrote:
14 Apr 2020, 15:36
Nice :thumbup: and v2 compatible :D
I'm trying to use it and I have this error, I think it's not compatible with v2 beta3 :(

@SKAN
Do you know if it is possible to use it with v2 beta3?

I receive the following message:
Spoiler

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

Posted: 01 Mar 2022, 01:49
by thqby
viewtopic.php?f=83&t=93944

This is V2 version.@Finallf

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

Posted: 01 Mar 2022, 06:01
by SKAN
Finallf wrote:
28 Feb 2022, 23:34
@SKAN
Do you know if it is possible to use it with v2 beta3?
This function cannot be ported to V2 owing to a change done to FileObj.ReadLine()
viewtopic.php?f=13&t=100656
thqby wrote:
01 Mar 2022, 01:49
viewtopic.php?f=83&t=93944

This is V2 version.@Finallf
Misinformation.
That isn't RunCMD() and wouldn't work correctly.

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

Posted: 01 Mar 2022, 08:20
by neogna2
SKAN wrote:
01 Mar 2022, 06:01
This function cannot be ported to V2 owing to a change done to FileObj.ReadLine()
I've used RunTerminal (the v2 clone of your RunCMD) for a few things without noticing any issue, but due to luck and/or not paying enough attention it now seems. Do you have a short example script that shows how something goes wrong with RunTerminal() because of the v2 ReadLine() issue?

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

Posted: 01 Mar 2022, 09:02
by SKAN
neogna2 wrote:
01 Mar 2022, 08:20
Do you have a short example script that shows how something goes wrong with RunTerminal() because of the v2 ReadLine() issue?
I didn't try the other code, but

There will be no lines in the output.
or
Output is a single line.

Manually adding CRLF will be error prone.

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

Posted: 01 Mar 2022, 09:52
by neogna2
SKAN wrote:
01 Mar 2022, 09:02
There will be no lines in the output.
or
Output is a single line.

Manually adding CRLF will be error prone.
Ok, yeah no linebreak chars. For example running this (which adds linebreak in the outside function)

Code: Select all

RunTerminal("ping 8.8.8.8 -n 20", , "UTF-8", PingToolTip)

PingToolTip(Line, LineNum, &PID) {
  static Lines := ""
  ToolTip(Lines .= Line "`n")
}
with the non-global RunTerminal version I get tooltip output that looks like this.
tooltip.png
tooltip.png (10.54 KiB) Viewed 4682 times
The irregularity in if TTL gets on a separate line or not here illustrates the issue I suppose.

Use cases that don't care about linebreaks, for example parsing the stream until some string pattern appears, would still work ok.

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

Posted: 01 Mar 2022, 09:54
by SKAN
RunTerminal is off-topic here. Ask its "author" for explanation.

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

Posted: 01 Mar 2022, 10:04
by neogna2
SKAN wrote:
01 Mar 2022, 09:54
RunTerminal is off-topic here. Ask its "author" for explanation.
You're right, I'm sorry. Please delete my post above. I moved it to the RunTerminal thread instead.

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

Posted: 01 Mar 2022, 10:09
by SKAN
neogna2 wrote:
01 Mar 2022, 10:04
You're right, I'm sorry. Please delete my post above.
Not a problem.
I wouldn't even replied if it wasn't you. :thumbup:

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

Posted: 01 Mar 2022, 10:25
by neogna2
:)
It seems v2 method .Read() doesn't omit linebreak chars. So could a workaround be to change from File.ReadLine() to e.g. File.Read(2) and leave it to the outside function to merge data into lines if needed. But maybe that has other issues?

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

Posted: 01 Mar 2022, 10:48
by SKAN
neogna2 wrote:
01 Mar 2022, 10:25
So could a workaround be to change from File.ReadLine() to e.g. File.Read(2) and leave it to the outside function to merge data into lines if needed.
Yes, but a kludge.
I prefer to wait for lexikos' reply.
viewtopic.php?f=13&t=100656

RunCMD() v0.99 for ah2

Posted: 01 Mar 2022, 17:38
by SKAN
@Finallf
@neogna2

Here is a temp version for V2 (Updated: 13-July-2023)

Code: Select all

RunCMD(P_CmdLine, P_WorkingDir := "", P_Codepage := "CP0", P_Func := 0, P_Slow := 1)
{
;  RunCMD Temp_v0.99 for ah2 By SKAN on D532/D67D @ autohotkey.com/r/?p=448912

    Global G_RunCMD

    If  Not IsSet(G_RunCMD)
        G_RunCMD := {}

    G_RunCMD                     :=  {PID: 0, ExitCode: ""}

    Local  CRLF                  :=  Chr(13) Chr(10)
        ,  hPipeR                :=  0
        ,  hPipeW                :=  0
        ,  PIPE_NOWAIT           :=  1
        ,  HANDLE_FLAG_INHERIT   :=  1
        ,  dwMask                :=  HANDLE_FLAG_INHERIT
        ,  dwFlags               :=  HANDLE_FLAG_INHERIT

    DllCall("Kernel32\CreatePipe", "ptrp",&hPipeR, "ptrp",&hPipeW, "ptr",0, "int",0)
  , DllCall("Kernel32\SetHandleInformation", "ptr",hPipeW, "int",dwMask, "int",dwFlags)
  , DllCall("Kernel32\SetNamedPipeHandleState", "ptr",hPipeR, "uintp",PIPE_NOWAIT, "ptr",0, "ptr",0)

    Local  B_OK                  :=  0
        ,  P8                    :=  A_PtrSize=8
        ,  STARTF_USESTDHANDLES  :=  0x100
        ,  STARTUPINFO
        ,  PROCESS_INFORMATION

    PROCESS_INFORMATION          :=  Buffer(P8 ?  24 : 16, 0)                  ;  PROCESS_INFORMATION
  , STARTUPINFO                  :=  Buffer(P8 ? 104 : 68, 0)                  ;  STARTUPINFO

  , NumPut("uint", P8 ? 104 : 68, STARTUPINFO)                                 ;  STARTUPINFO.cb
  , NumPut("uint", STARTF_USESTDHANDLES, STARTUPINFO, P8 ? 60 : 44)            ;  STARTUPINFO.dwFlags
  , NumPut("ptr",  hPipeW, STARTUPINFO, P8 ? 88 : 60)                          ;  STARTUPINFO.hStdOutput
  , NumPut("ptr",  hPipeW, STARTUPINFO, P8 ? 96 : 64)                          ;  STARTUPINFO.hStdError

    Local  CREATE_NO_WINDOW      :=  0x08000000
        ,  PRIORITY_CLASS        :=  DllCall("Kernel32\GetPriorityClass", "ptr",-1, "uint")

    B_OK :=  DllCall( "Kernel32\CreateProcessW"
                    , "ptr", 0                                                 ;  lpApplicationName
                    , "ptr", StrPtr(P_CmdLine)                                 ;  lpCommandLine
                    , "ptr", 0                                                 ;  lpProcessAttributes
                    , "ptr", 0                                                 ;  lpThreadAttributes
                    , "int", True                                              ;  bInheritHandles
                    , "int", CREATE_NO_WINDOW | PRIORITY_CLASS                 ;  dwCreationFlags
                    , "int", 0                                                 ;  lpEnvironment
                    , "ptr", DirExist(P_WorkingDir) ? StrPtr(P_WorkingDir) : 0 ;  lpCurrentDirectory
                    , "ptr", STARTUPINFO                                       ;  lpStartupInfo
                    , "ptr", PROCESS_INFORMATION                               ;  lpProcessInformation
                    , "uint"
                    )

    DllCall("Kernel32\CloseHandle", "ptr",hPipeW)

    If  Not B_OK
        Return ( DllCall("Kernel32\CloseHandle", "ptr",hPipeR), "" )

    G_RunCMD.PID := NumGet(PROCESS_INFORMATION, P8 ? 16 : 8, "uint")

    Local  FileObj
        ,  Line                  :=  ""
        ,  LineNum               :=  1
        ,  sOutput               :=  ""
        ,  ExitCode              :=  0

    FileObj  :=  FileOpen(hPipeR, "h", P_Codepage)
  , P_Slow   :=  !! P_Slow

    Sleep_() =>  (Sleep(P_Slow), G_RunCMD.PID)

    While   DllCall("Kernel32\PeekNamedPipe", "ptr",hPipeR, "ptr",0, "int",0, "ptr",0, "ptr",0, "ptr",0)
      and   Sleep_()
            While  G_RunCMD.PID and not FileObj.AtEOF
                   Line           :=  FileObj.ReadLine()
                ,  sOutput        .=  StrLen(Line)=0 and FileObj.Pos=0
                                   ?  ""
                                   :  (
                                         P_Func
                                      ?  P_Func.Call(Line CRLF, LineNum++)
                                      :  Line CRLF
                                      )

    hProcess                     :=  NumGet(PROCESS_INFORMATION, 0, "ptr")
  , hThread                      :=  NumGet(PROCESS_INFORMATION, A_PtrSize, "ptr")

  , DllCall("Kernel32\GetExitCodeProcess", "ptr",hProcess, "ptrp",&ExitCode)
  , DllCall("Kernel32\CloseHandle", "ptr",hProcess)
  , DllCall("Kernel32\CloseHandle", "ptr",hThread)
  , DllCall("Kernel32\CloseHandle", "ptr",hPipeR)
  , G_RunCMD := {PID: 0, ExitCode: ExitCode}

    Return RTrim(sOutput, CRLF)
}

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

Posted: 02 Mar 2022, 06:49
by neogna2
SKAN wrote:
01 Mar 2022, 17:38
Here is a temp version for V2
Thank you.

The pipe object code does FileObj.Pos=0 but https://lexikos.github.io/v2/docs/commands/FileOpen.htm#Flags says
h ... Indicates that Filename is a file handle to wrap in an object ... Note that Seek, Pos and Length should not be used if Filename is a handle to a nonseeking device such as a pipe or a communications device.
Is that an issue?

And, since kludge is my middle name :lol:, I tried this modification. Worked in a quick test, but don't know if generally ok or performant.

Code: Select all

While  Glob.RunCMD.PID and not FileObj.AtEOF
      Sleep(-1)
   ,   Chunks        .=  FileObj.Read(2)
   ,  sOutput        .=   ( SubStr(Chunks,-1)="`n" && ( (Line := Chunks) && (Chunks := "") || 1) ) ; short-circuits
                      ? (
                                P_Func
                            ?  P_Func.Call(Line, LineNum++)
                            :  Line
                         )
                      : ""

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

Posted: 02 Mar 2022, 07:28
by SKAN
neogna2 wrote:
02 Mar 2022, 06:49
The pipe object code does FileObj.Pos=0 but https://lexikos.github.io/v2/docs/commands/FileOpen.htm#Flags says
h ... Indicates that Filename is a file handle to wrap in an object ... Note that Seek, Pos and Length should not be used if Filename is a handle to a nonseeking device such as a pipe or a communications device.
Is that an issue?
I don't know. Doc also advises not to use FileObj.AtEOF with a pipe.
That is why I made the "wish" to restore the original behavior to FileObj.ReadLine().

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

Posted: 02 Mar 2022, 08:14
by thqby
SKAN wrote:
01 Mar 2022, 17:38
@Finallf
@neogna2

Here is a temp version for V2

Code: Select all

code removed by SKAN
In my tests, this will return right results when removing SetNamedPipeHandleState and adding `n. Invalid empty lines will not be read.

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

Posted: 06 Mar 2022, 15:54
by pond_pop
wow great~! :bravo:

but, i'm try to use this

Code: Select all

cmd = vspipe --y4m "C:\i.vpy" - | ffmpeg -i pipe: -c:v libx264 -crf 19 "G:\o.mkv"
MsgBox, % RunCMD(cmd)
and.. get this

Code: Select all

Unknown argument: |

have any hope?