Some time fail to create process Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
PEMessage
Posts: 3
Joined: 04 Jun 2020, 23:32

Some time fail to create process

Post by PEMessage » 03 Jun 2023, 08:10

Background :
HI, I rewite a ahk_v1 script from below

(Title: Hide command console when using RunWaitOne() example) @teadrinker :
viewtopic.php?style=2&f=76&t=84266&p=369467#p369467

The origin scipt allow you run cmd and get the std output to a var,
and hidden the window of terminal unlike official example

Problem:

The origin work fine, But come to my rewrite version.
sometime work, sometime it will throw(quite offen :( !) error like this
image.png
image.png (15.37 KiB) Viewed 498 times
The official DllCall page mention this error code
Error: The function was called but it aborted with a fatal exception. Exception.Extra contains the exception code. For example, 0xC0000005 means "access violation". In such cases, the thread is aborted (if try is not used), but any asterisk variables are still updated. An example of a fatal exception is dereferencing an invalid pointer such as NULL (0). Since a Cdecl function never produces the error described in the next paragraph, it may generate an exception when too few arguments are passed to it.
But I have no idea how to fix it. I'm not familiar with win32api or ahkv2 or ahkv1,
I just do it stumbly do it by comparing api difference between ahkv1 and ahkv2
Please help me if i make any mistake

My code is at bottom, you could compare it to orgin one
They are basicly same one, but doesn't work well

Code: Select all

CmdRet(sCmd, callBackFuncObj := "", encoding := "CP0")
{
   static HANDLE_FLAG_INHERIT := 0x00000001, flags := HANDLE_FLAG_INHERIT
       , STARTF_USESTDHANDLES := 0x100, CREATE_NO_WINDOW := 0x08000000
    hPipeRead := {Ptr : 0}
    hPipeWrite := {Ptr : 0}

   DllCall("CreatePipe", "PtrP", hPipeRead, "PtrP", hPipeWrite, "Ptr", 0, "UInt", 0)
   DllCall("SetHandleInformation", "Ptr", hPipeWrite, "UInt", flags, "UInt", HANDLE_FLAG_INHERIT)

   ;    VarSetCapacity(STARTUPINFO , siSize :=    A_PtrSize*4 + 4*8 + A_PtrSize*5, 0)
   siSize := A_PtrSize * 4 + 4 * 8 + A_PtrSize * 5
   STARTUPINFO := Buffer(siSize)
   NumPut("UPtr", siSize, STARTUPINFO)
   NumPut("UPtr", STARTF_USESTDHANDLES, STARTUPINFO, A_PtrSize * 4 + 4 * 7)
   NumPut("UPtr", hPipeWrite.Ptr, STARTUPINFO, A_PtrSize * 4 + 4 * 8 + A_PtrSize * 3)
   NumPut("UPtr", hPipeWrite.Ptr, STARTUPINFO, A_PtrSize * 4 + 4 * 8 + A_PtrSize * 4)
   
   PROCESS_INFORMATION := Buffer(A_PtrSize*2 + 4*2, 0) 


 
   try {
      DllCall("CreateProcess", "Ptr", 0, "Str", sCmd, "Ptr", 0, "Ptr", 0, "UInt", true, "UInt", CREATE_NO_WINDOW
                              , "Ptr", 0, "Ptr", 0, "Ptr", STARTUPINFO, "Ptr", PROCESS_INFORMATION )
   } catch OSError as err {
      DllCall("CloseHandle", "Ptr", hPipeRead)
      DllCall("CloseHandle", "Ptr", hPipeWrite)
      throw err
   }
   DllCall("CloseHandle", "Ptr", hPipeWrite)
;    VarSetCapacity(sTemp, 4096)
   sTemp := Buffer(4096)
   nSize := 0
   while( DllCall("ReadFile", "Ptr", hPipeRead, "Ptr", sTemp, "UInt", 4096, "UIntP", &nSize, "UInt", 0) ){
      

      sOutput .= stdOut := StrGet(sTemp, nSize, encoding)

      ( callBackFuncObj && callBackFuncObj.Call(stdOut) )
   }
   DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION,0,"UPtr"))
   DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION, A_PtrSize,"UPtr"))
   DllCall("CloseHandle", "Ptr", hPipeRead)
   ; if(sOutput) {
      Return sOutput
   ; } else {
   ;    throw Error("Fail GetValue")
   ; }
}

F1::{
   MsgBox(CmdRet("cmd /c help"))
}



PEMessage
Posts: 3
Joined: 04 Jun 2020, 23:32

Re: Some time fail to create process

Post by PEMessage » 03 Jun 2023, 08:18

I'm ok to use other script,
as long as provide same feature

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Some time fail to create process  Topic is solved

Post by teadrinker » 03 Jun 2023, 12:04

This should work:

Code: Select all

MsgBox CmdRet("cmd /c help")

CmdRet(sCmd, callBackFunc := '', encoding := '') {
    static flags := [HANDLE_FLAG_INHERIT := 0x1, CREATE_NO_WINDOW := 0x8000000], STARTF_USESTDHANDLES := 0x100

    (encoding = '' && encoding := 'cp' . DllCall('GetOEMCP', 'UInt'))
    DllCall('CreatePipe', 'PtrP', &hPipeRead := 0, 'PtrP', &hPipeWrite := 0, 'Ptr', 0, 'UInt', 0)
    DllCall('SetHandleInformation', 'Ptr', hPipeWrite, 'UInt', flags[1], 'UInt', flags[1])

    STARTUPINFO := Buffer(size := A_PtrSize*9 + 4*8, 0)
    NumPut('UInt', size, STARTUPINFO)
    NumPut('UInt', STARTF_USESTDHANDLES, STARTUPINFO, A_PtrSize*4 + 4*7)
    NumPut('Ptr', hPipeWrite, 'Ptr', hPipeWrite, STARTUPINFO, size - A_PtrSize*2)

    PROCESS_INFORMATION := Buffer(A_PtrSize*2 + 4*2, 0)
    if !DllCall('CreateProcess', 'Ptr', 0, 'Str', sCmd, 'Ptr', 0, 'Ptr', 0, 'UInt', true, 'UInt', flags[2]
                               , 'Ptr', 0, 'Ptr', 0, 'Ptr', STARTUPINFO, 'Ptr', PROCESS_INFORMATION)
    {
        DllCall('CloseHandle', 'Ptr', hPipeRead)
        DllCall('CloseHandle', 'Ptr', hPipeWrite)
        throw OSError('CreateProcess is failed')
    }
    DllCall('CloseHandle', 'Ptr', hPipeWrite)
    temp := Buffer(4096, 0), output := ''
    while DllCall('ReadFile', 'Ptr', hPipeRead, 'Ptr', temp, 'UInt', 4096, 'UIntP', &size := 0, 'UInt', 0) {
        output .= stdOut := StrGet(temp, size, encoding)
        ( callBackFunc && callBackFunc(stdOut) )
    }
    DllCall('CloseHandle', 'Ptr', NumGet(PROCESS_INFORMATION, 'Ptr'))
    DllCall('CloseHandle', 'Ptr', NumGet(PROCESS_INFORMATION, A_PtrSize, 'Ptr'))
    DllCall('CloseHandle', 'Ptr', hPipeRead)
    return output
}

PEMessage
Posts: 3
Joined: 04 Jun 2020, 23:32

Re: Some time fail to create process

Post by PEMessage » 04 Jun 2023, 10:11

@teadrinker
Thank you for the continuous working! This script is import that allow me comblie cli-program with ahkv2, Thanks!

Post Reply

Return to “Ask for Help (v2)”