AHK Script to connect to a Named Pipe Help

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
prototype_zero
Posts: 16
Joined: 19 Mar 2024, 13:01

AHK Script to connect to a Named Pipe Help

Post by prototype_zero » 29 Mar 2024, 14:50

Hello,

I'm trying to make a AHK simple script that connects to my named pipe python script to retrieve real time data. Here is a sample. The named pipe works. When I create a python script to connect to it and print out the sample data, it works, so I know the named pipe is functioning properly. But when I make an AHK script to connect to it, it always says that it failed to connect to it. Any help would be greatly appreciated. Thanks!

Code: Select all

[code]
import win32pipe
import win32file
import struct
import time

PIPE_NAME = r'\\.\pipe\SamplePipe'

def main():
    # Create named pipe
    pipe = win32pipe.CreateNamedPipe(
        PIPE_NAME,
        win32pipe.PIPE_ACCESS_OUTBOUND,
        win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT,
        1, 65536, 65536,
        300,
        None
    )

    print("Waiting for connection...")
    win32pipe.ConnectNamedPipe(pipe, None)

    print("Connected to pipe.")

    try:
        while True:
            # Sample x, y coordinate data
            x = 10
            y = 20
            
            # Convert data to bytes
            data = struct.pack('ii', x, y)
            
            # Write data to named pipe
            win32file.WriteFile(pipe, data)
            
            print(f"Sent data: x={x}, y={y}")
            time.sleep(1)
    finally:
        win32file.CloseHandle(pipe)

if __name__ == "__main__":
    main()

[/code]

Code: Select all

#Persistent

PIPE_NAME := "\\.\pipe\SamplePipe"
pipe := DllCall("CreateFile", "Str", PIPE_NAME, "UInt", 0xC0000000, "UInt", 3, "Ptr", 0, "UInt", 3, "UInt", 0, "Ptr", 0)

if (pipe = -1) {
    MsgBox, Failed to connect to named pipe.
    ExitApp
} else {
    MsgBox, Connected to named pipe successfully.
}

Loop {
    VarSetCapacity(data, 8)
    bytesRead := DllCall("ReadFile", "Ptr", pipe, "Ptr", &data, "UInt", 8, "Ptr", 0, "UInt", 0)
    if (bytesRead > 0) {
        x := NumGet(data, 0, "Int")
        y := NumGet(data, 4, "Int")
        MsgBox, Data received:`nX: %x%`nY: %y%
    } else if (bytesRead < 0) {
        MsgBox, Error reading from named pipe.
    }
    Sleep, 1000
}


User avatar
lmstearn
Posts: 695
Joined: 11 Aug 2016, 02:32
Contact:

Re: AHK Script to connect to a Named Pipe Help

Post by lmstearn » 31 Mar 2024, 06:02

Hi, have to ask, the bitness matches in both processes, 32bit or 64 bit, and both process are either unicode or ANSI?
To narrow down the issue, catch the value of A_LastError directly after the CF function, also consider Wait and Peek functions for named pipes mentioned in this thread.
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

prototype_zero
Posts: 16
Joined: 19 Mar 2024, 13:01

Re: AHK Script to connect to a Named Pipe Help

Post by prototype_zero » 31 Mar 2024, 11:52

lmstearn wrote:
31 Mar 2024, 06:02
Hi, have to ask, the bitness matches in both processes, 32bit or 64 bit, and both process are either unicode or ANSI?
To narrow down the issue, catch the value of A_LastError directly after the CF function, also consider Wait and Peek functions for named pipes mentioned in this thread.
Hello, thanks for the response. I've verified that my python environment is 64-bit, so used a 64-bit autohotkey launcher. The error level I got was error level 5. I've tried to implement the Wait and Peek functions. It's strange though, when I try to run it normally I get the error code 5 message, but when I try to run it in the 64-bit launcher it gives me syntax errors, which when you fix, persist.

Code: Select all

PIPE_NAME := "\\.\pipe\SamplePipe"
pipe := DllCall("CreateFile", "Str", PIPE_NAME, "UInt", 0xC0000000, "UInt", 3, "Ptr", 0, "UInt", 3, "UInt", 0, "Ptr", 0)

; Check for errors after the CreateFile call
lastError := A_LastError
if (pipe = -1) {
    MsgBox, Failed to connect to named pipe. Error code: %lastError%
    ExitApp
} else {
    MsgBox, Connected to named pipe successfully.
}

Loop {
    VarSetCapacity(data, 8)
    
    ; Check if there is data available in the pipe
    DllCall("PeekNamedPipe", "Ptr", pipe, "Ptr", 0, "UInt", 0, "Ptr", 0, "PtrP", bytesAvailable, "Ptr", 0)
    
    ; Check for errors after the PeekNamedPipe call
    lastError := A_LastError
    if (bytesAvailable > 0) {
        ; Data is available, read from the pipe
        bytesRead := DllCall("ReadFile", "Ptr", pipe, "Ptr", &data, "UInt", 8, "Ptr", 0, "UInt", 0)

        ; Check for errors after the ReadFile call
        lastError := A_LastError
        if (bytesRead > 0) {
            x := NumGet(data, 0, "Int")
            y := NumGet(data, 4, "Int")
            MsgBox, Data received:`nX: %x%`nY: %y%
        } else if (bytesRead < 0) {
            MsgBox, Error reading from named pipe. Error code: %lastError%
        }
    }
    
    Sleep, 1000
}

User avatar
lmstearn
Posts: 695
Joined: 11 Aug 2016, 02:32
Contact:

Re: AHK Script to connect to a Named Pipe Help

Post by lmstearn » 31 Mar 2024, 22:08

Shouldn't be syntax errors with 64bit, might be an issue if you had old ahk v1 +v2. In that case uninstall the lot, re-install v2, then install v1 after.
The Python script uses PIPE_ACCESS_OUTBOUND, make any difference changing to PIPE_ACCESS_DUPLEX?

Code: Select all

PIPE_NAME := "\\.\pipe\SamplePipe"
PIPE_ACCESS_DUPLEX := 3

hPipe_real := DllCall("CreateNamedPipe", "Str", PIPE_NAME, "UInt", PIPE_ACCESS_DUPLEX, "UInt",0, "UInt", 255, "UInt", 0, "UInt", 0, "UInt", 0, "Ptr", 0, "Ptr")
sleep 20

pipe := DllCall("CreateFile", "Str", PIPE_NAME, "UInt", 0xC0000000, "UInt", 3, "Ptr", 0, "UInt", 3, "UInt", 0, "Ptr", 0)

; Check for errors after the CreateFile call
lastError := A_LastError
if (pipe = -1) {
    MsgBox, Failed to connect to named pipe. Error code: %lastError%
    ExitApp
} else {
    MsgBox, Connected to named pipe successfully.
}

Loop {
    VarSetCapacity(data, 8)
    
    ; Check if there is data available in the pipe
    DllCall("PeekNamedPipe", "Ptr", pipe, "Ptr", 0, "UInt", 0, "Ptr", 0, "PtrP", bytesAvailable, "Ptr", 0)
    
    ; Check for errors after the PeekNamedPipe call
    lastError := A_LastError
    if (bytesAvailable > 0) {
        ; Data is available, read from the pipe
        bytesRead := DllCall("ReadFile", "Ptr", pipe, "Ptr", &data, "UInt", 8, "Ptr", 0, "UInt", 0)

        ; Check for errors after the ReadFile call
        lastError := A_LastError
        if (bytesRead > 0) {
            x := NumGet(data, 0, "Int")
            y := NumGet(data, 4, "Int")
            MsgBox, Data received:`nX: %x%`nY: %y%
        } else if (bytesRead < 0) {
            MsgBox, Error reading from named pipe. Error code: %lastError%
        }
    }
    
    Sleep, 1000
}
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

prototype_zero
Posts: 16
Joined: 19 Mar 2024, 13:01

Re: AHK Script to connect to a Named Pipe Help

Post by prototype_zero » 01 Apr 2024, 09:58

lmstearn wrote:
31 Mar 2024, 22:08
Shouldn't be syntax errors with 64bit, might be an issue if you had old ahk v1 +v2. In that case uninstall the lot, re-install v2, then install v1 after.
The Python script uses PIPE_ACCESS_OUTBOUND, make any difference changing to PIPE_ACCESS_DUPLEX?

Code: Select all

PIPE_NAME := "\\.\pipe\SamplePipe"
PIPE_ACCESS_DUPLEX := 3

hPipe_real := DllCall("CreateNamedPipe", "Str", PIPE_NAME, "UInt", PIPE_ACCESS_DUPLEX, "UInt",0, "UInt", 255, "UInt", 0, "UInt", 0, "UInt", 0, "Ptr", 0, "Ptr")
sleep 20

pipe := DllCall("CreateFile", "Str", PIPE_NAME, "UInt", 0xC0000000, "UInt", 3, "Ptr", 0, "UInt", 3, "UInt", 0, "Ptr", 0)

; Check for errors after the CreateFile call
lastError := A_LastError
if (pipe = -1) {
    MsgBox, Failed to connect to named pipe. Error code: %lastError%
    ExitApp
} else {
    MsgBox, Connected to named pipe successfully.
}

Loop {
    VarSetCapacity(data, 8)
    
    ; Check if there is data available in the pipe
    DllCall("PeekNamedPipe", "Ptr", pipe, "Ptr", 0, "UInt", 0, "Ptr", 0, "PtrP", bytesAvailable, "Ptr", 0)
    
    ; Check for errors after the PeekNamedPipe call
    lastError := A_LastError
    if (bytesAvailable > 0) {
        ; Data is available, read from the pipe
        bytesRead := DllCall("ReadFile", "Ptr", pipe, "Ptr", &data, "UInt", 8, "Ptr", 0, "UInt", 0)

        ; Check for errors after the ReadFile call
        lastError := A_LastError
        if (bytesRead > 0) {
            x := NumGet(data, 0, "Int")
            y := NumGet(data, 4, "Int")
            MsgBox, Data received:`nX: %x%`nY: %y%
        } else if (bytesRead < 0) {
            MsgBox, Error reading from named pipe. Error code: %lastError%
        }
    }
    
    Sleep, 1000
}
Thanks for the response. I uninstalled it all and re-installed just v2, but when I tried the script, it says that the script requires v1. When I try the adjusted script with v1, I get error 5, and with v2, I get the syntax error on line 12.

User avatar
lmstearn
Posts: 695
Joined: 11 Aug 2016, 02:32
Contact:

Re: AHK Script to connect to a Named Pipe Help

Post by lmstearn » 01 Apr 2024, 22:18

It's a v1 script, best to continue with debugging that. :)
Regarding the win32pipe.CreateNamedPipe function in the Python script, replace win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT with win32pipe.PIPE_WAIT and increase the timeout from 300 to e.g. 3000, also check win32pipe.PIPE_ACCESS_OUTBOUND was replaced with win32pipe.PIPE_ACCESS_DUPLEX, and run with your second version (not mine) of the AHK script.
If you still get error 5, is one script elevated, and not the other?
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

prototype_zero
Posts: 16
Joined: 19 Mar 2024, 13:01

Re: AHK Script to connect to a Named Pipe Help

Post by prototype_zero » 02 Apr 2024, 13:25

lmstearn wrote:
01 Apr 2024, 22:18
It's a v1 script, best to continue with debugging that. :)
Regarding the win32pipe.CreateNamedPipe function in the Python script, replace win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT with win32pipe.PIPE_WAIT and increase the timeout from 300 to e.g. 3000, also check win32pipe.PIPE_ACCESS_OUTBOUND was replaced with win32pipe.PIPE_ACCESS_DUPLEX, and run with your second version (not mine) of the AHK script.
If you still get error 5, is one script elevated, and not the other?
Wow, that solved it! I ran the AHK script, and it said it was connected, and the data was being read on the message box. It's amazing that you figured it out so easily, thanks so much. If you don't mind me asking, what was the issue and how did your solution solve it?

User avatar
lmstearn
Posts: 695
Joined: 11 Aug 2016, 02:32
Contact:

Re: AHK Script to connect to a Named Pipe Help

Post by lmstearn » 03 Apr 2024, 15:39

The info is all there in the MS article for CreateNamedPipe, the task of matching the settings in the Python client/server scripts to the OP AHK script may relate to just one of the tweaks applied later, but hey it's working and glad to be of help! :)
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

Post Reply

Return to “Ask for Help (v1)”