Jump to content

A simple fast IPC based on Windows Messaging


Go to solution Solved by Nine,

Recommended Posts

  • 10 months later...
Posted (edited)

Data property should be in @extended (as a numeric value).

; From the example script
; Modified WaitForResponse to return @extended

...

$sString = WaitForResponse ()
ConsoleWrite (@extended & "/" & $sString & @CRLF)

Func WaitForResponse ()
  Local $sResp
  While _WCD_IsServerAvailable ()
    $sResp = _WCD_Client_GetResponse ()
    If @extended Or $sResp Then Return SetExtended(@extended, $sResp)
    Sleep (100)
  WEnd
EndFunc

 

Edited by Nine
Posted (edited)

I'm using this on server side:

_WCD_SEND($hServer, $hClient, 123, "foo")

and on client side $sResp returns "foo", but @extended always returns 0

NVM, I had another function call before I checked the @extended macro...my bad.

Edited by VAN0
  • 1 year later...
Posted

The latest version of AutoIt requires adding another include to the UDF:

#include <WindowsNotifsConstants.au3>

I am wondering if you could help me with retrieving to strings on the server side, please.

My example script below doesn't work, however, I am hoping that it will give you an idea of what I am trying to do.

Server:

#include <Constants.au3>
#include <GUIConstants.au3>
#include "WCD_IPC.au3"

Opt ("MustDeclareVars", 1)

Local $hServer = _WCD_CreateServer()
Local $aReq, $iData

While True
    If _WCD_Server_IsRequestAvail() Then
        $aReq = _WCD_Server_GetRequest()
        $iData = @extended
        Switch $iData
            Case 1
                If $sString = "enable" Then ; run another function to enable
                If $sString = "disable" Then ; run another function to disable
            Case 2
                If $sString = "enable" Then ; run another function to enable
                If $sString = "disable" Then ; run another function to disable
        EndSwitch
    EndIf
    Sleep (1000)
WEnd

Client:

#include <Constants.au3>
#include <GUIConstants.au3>
#include "WCD_IPC.au3"

Opt ("MustDeclareVars", 1)

Global $hWnd = _WCD_CreateClient("Test WCD Client")
Global $hWndServer = _WCD_GetServerHandle()

_WCD_Send($hWnd, $hWndServer, 1, "enable")
_WCD_Send($hWnd, $hWndServer, 1, "disable")

_WCD_Send($hWnd, $hWndServer, 2, "enable")
_WCD_Send($hWnd, $hWndServer, 2, "disable")

The problem is that I have no idea how to obtain the string that is sent to the server. I can see the strings get sent in the log. Thank you.

Posted
4 hours ago, WildByDesign said:

The latest version of AutoIt requires adding another include to the UDF

Thank you.  Yes last AutoIt version messed up with the #include.  Many of my scripts are breaking because of it.  I'll update this one tomorrow.

Anyway, the string is located in $aReq[1], as described in example.

 

Posted (edited)
On 4/30/2020 at 6:02 PM, Nine said:
_WCD_Send($hWnd, $hWndServer, 2, "5") ; adding text to a more complex request
$sString = WaitForResponse ()
ConsoleWrite ($sString & @CRLF)

It seems that the script crashes 100% of the time on this part here. Actually it seems that any attempt to send a string through it crashes the server script. Sending the initial numbers through without the string part works perfectly. I spent a few hours on this last night and again this morning. I've narrowed the problem down to this part of the example script.

EDIT: Following the log file, it appears that there is never a response from the server for the times when the client sends a string. Even with the given example.

Edited by WildByDesign
Posted (edited)

It looks like what is happening is that the string part never gets sent until the user clicks on the tray icon. So the first _WCD_Send($hWnd, $hWndServer, 1) gets sent and received. Then nothing happens. I can let it sit for 5 minutes. Then click on the tray icon, and that is when the _WCD_Send($hWnd, $hWndServer, 2, "5") gets sent but never received.

By the way, this is on Windows 11 25H2 which is essentially the same kernel and everything as 24H2.

EDIT: Actually its not specific to the strings. It seems to be any subsequent request. Any second request never goes through until the tray icon is clicked, no matter how long.

Edited by WildByDesign
Posted
43 minutes ago, Nine said:

I tested my example both on Win10 22h2 (au3 3.3.16.0) and Win11 25h2 (au3 3.3.18.0).  All works well. 

I took me a few hours unfortunately, but I figured it out. The UDF does not support AutoIt 64-bit for some reason.

  • The server was never receiving the strings. I was able to confirm that.
  • None of the ConsoleWrites were working on server or client script at all.

I switched to 32-bit AutoIt, strings are going as was intended and ConsoleWrites and all.

So I guess that leaves the question. Is it possible to support 64-bit AutoIt?

Thank you for your time with this, by the way. I thought I was completely losing my mind for a bit there. :)

  • Solution
Posted
5 minutes ago, Nine said:

New version available. :)

Thank you for the quick fix. Everything that I have tested so far on x64 works beautifully. Very fast server responses as well.

Posted (edited)

I've got an interesting situation. Leave it to me to always find interesting and unusual situations. :)

First of all, your WCD_IPC is working so incredibly well and I've been able to do great things with it already. And performs fast and efficient.

There are times where I need to restart the server process. And, as expected, it breaks the IPC and hangs the GUI process that has the client IPC included.

So my question is: What is the best way that I can handle this situation?

If I could keep my main GUI process running still but simply pause (or delete) the hidden GUI that is used by WCP_IPC, that would be ideal. That way it can wait for the server process to restart and grab the new server handle.

Eg. GUIDelete($hClientIPC)

If I did it that way, I could wait for the server to come back up and recreate the client IPC with _WCD_CreateClient($sWindowTitle = "").

But is there a better method that I should use?

I know that GUIRegisterMsg is critical here but I don't know as much in that area. I'm not sure if there is a way to simply unregister that GUI Msg function or if GUIDelete would do that anyway.

Edited by WildByDesign
Posted
7 hours ago, WildByDesign said:

But is there a better method that I should use?

What about _WCD_IsServerAvailable() ?  Maybe I'm mistaken but I see no reason why your client GUI would hang if you do not send anything while the server is down. 

Posted
2 hours ago, Nine said:

What about _WCD_IsServerAvailable() ?

That's a good suggestion. I should be able to make good use of that function.

2 hours ago, Nine said:

Maybe I'm mistaken but I see no reason why your client GUI would hang if you do not send anything while the server is down. 

It took me a little while to figure out where I went wrong. The GUI wasn't technically hung because all of the combos and buttons were working but the none of the functions associated with them were firing.

The engine is multi-process and there are about 5 or 6 processes that spawn from the same script depending on what the user has configured. There were two instances where I forgot that I needed to call $hWndServer = _WCD_GetServerHandle() which explains why those functions were technically going nowhere. Especially during the times when the server process needed to be restarted.

All is well now. Thank you. :)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...