PsaltyDS Posted December 15, 2007 Share Posted December 15, 2007 (edited) Saw another topic on _NamedPipes* functions and wanted to learn a new thing. Did some reading is MSDN and the help file (where there are, distressingly, NO examples of use).So I tried to code a two-script example for myself. A server side would create the named pipe and connect to it, the client side would then connect to the other end. For a simple demo, the client would write a number to the pipe, the server would read the number, take the cube root, and write it back to the pipe, where the client would read and display it.Haven't even tried to code the client yet, because the server script crashes hard:Unhelpful Windows Error message: Slightly more helpful details (kernel32.dll error): Here's the unfinished script that causes the error. When run click "Create Pipe" button, then click "Connect To Pipe". Warning: Bad things happen (see errors above).expandcollapse popup#include <GuiConstants.au3> #Include <NamedPipes.au3> #include <array.au3> Opt("MustDeclareVars", 1) Opt("GuiOnEventMode", 1) Global $hNamedPipe = 0, $avPipeData[4] Global $sNamedPipe = "\\.\pipe\MyNamedPipe" Global $fSvrConn = False ; Create GUI for server side. Global $hSvrGUI = GUICreate("Named Pipe SERVER", 600, 360, 50, 50) GUISetOnEvent($GUI_EVENT_CLOSE, "_ShutDownSvr") GUICtrlCreateLabel("Purpose of SERVER: Return the cube root of a number via named pipe", 10, 10, 580, 20, $SS_CENTER) Global $SvrReadEdit = GUICtrlCreateEdit("", 10, 40, 285, 200) Global $SvrWriteEdit = GUICtrlCreateEdit("", 305, 40, 285, 200) GUICtrlCreateLabel("Pipe Status:", 10, 265, 150, 20, $SS_RIGHT) Global $SvrPipeStatus = GUICtrlCreateInput("No pipe created", 170, 265, 150, 20, $SS_LEFT, $ES_READONLY) GUICtrlCreateButton("Create Pipe", 330, 260, 100, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") GUICtrlCreateLabel("Connection Status:", 10, 315, 150, 20, $SS_RIGHT) Global $SvrConnStatus = GUICtrlCreateInput("No connection to pipe", 170, 315, 150, 20, $SS_LEFT, $ES_READONLY) GUICtrlCreateButton("Connect To Pipe", 330, 310, 100, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") GUICtrlCreateButton("Pipe Handle State", 465, 285, 100, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") GUISetState(@SW_SHOW, $hSvrGUI) While 1 Sleep(20) WEnd Func _ShutDownSvr() Exit EndFunc ;==>_ShutDownSvr Func _ButtonHit() Local $hGUI_WinHandle = @GUI_WinHandle, $hGUI_CtrlHandle = @GUI_CtrlHandle, $iGUI_CtrlId = @GUI_CtrlId Local $sButtonTxt = ControlGetText($hGUI_WinHandle, "", $iGUI_CtrlId) ConsoleWrite("Debug: _ButtonHit: Button clicked = " & $sButtonTxt) Switch $sButtonTxt Case "Create Pipe" $hNamedPipe = _NamedPipes_CreateNamedPipe($sNamedPipe) If $hNamedPipe <> -1 Then ControlSetText($hGUI_WinHandle, "", $SvrPipeStatus, "Pipe successfully created") ControlSetText($hGUI_WinHandle, "", $iGUI_CtrlId, "Delete Pipe") Else ControlSetText($hGUI_WinHandle, "", $SvrPipeStatus, "Error creating pipe") ControlSetText($hGUI_WinHandle, "", $iGUI_CtrlId, "Create Pipe") EndIf Case "Delete Pipe" FileClose($hNamedPipe) $hNamedPipe = 0 ControlSetText($hGUI_WinHandle, "", $SvrPipeStatus, "Pipe handle closed") ControlSetText($hGUI_WinHandle, "", $iGUI_CtrlId, "Create Pipe") Case "Connect To Pipe" If _NamedPipes_ConnectNamedPipe($hNamedPipe, 1) Then ControlSetText($hSvrGUI, "", $SvrConnStatus, "Connected to pipe") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Disconnect From Pipe") $fSvrConn = True Else $fSvrConn = False ControlSetText($hSvrGUI, "", $SvrConnStatus, "Error connecting to pipe") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Connect To Pipe") EndIf Case "Disconnect From Pipe" If _NamedPipes_DisconnectNamedPipe($hNamedPipe) Then $fSvrConn = False ControlSetText($hSvrGUI, "", $SvrConnStatus, "Pipe disconnected") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Connect To Pipe") Else ControlSetText($hSvrGUI, "", $SvrConnStatus, "Error disconnecting from pipe") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Disconnect From Pipe") $fSvrConn = True EndIf Case "Pipe Handle State" _ArrayDisplay(_NamedPipes_GetNamedPipeHandleState($hNamedPipe), "Pipe Handle State") Case Else MsgBox(16, "Error", "Error! Function _ButtonHit() unhandled case $sButtonTxt = " & $sButtonTxt) EndSwitch EndFunc ;==>_ButtonHitAs a first attempt, I'm not surprised my script doesn't work, but I didn't expect full crashes. Are there good demo/example scripts for using named pipes out there that I'm not finding? Edited December 15, 2007 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
martin Posted December 15, 2007 Share Posted December 15, 2007 Saw another topic on _NamedPipes* functions and wanted to learn a new thing. Did some reading is MSDN and the help file (where there are, distressingly, NO examples of use). So I tried to code a two-script example for myself. A server side would create the named pipe and connect to it, the client side would then connect to the other end. For a simple demo, the client would write a number to the pipe, the server would read the number, take the cube root, and write it back to the pipe, where the client would read and display it. Haven't even tried to code the client yet, because the server script crashes hard: Unhelpful Windows Error message: Slightly more helpful details (kernel32.dll error): Here's the unfinished script that causes the error. When run click "Create Pipe" button, then click "Connect To Pipe". Warning: Bad things happen (see errors above). expandcollapse popup#include <GuiConstants.au3> #Include <NamedPipes.au3> #include <array.au3> Opt("MustDeclareVars", 1) Opt("GuiOnEventMode", 1) Global $hNamedPipe = 0, $avPipeData[4] Global $sNamedPipe = "\\.\pipe\MyNamedPipe" Global $fSvrConn = False ; Create GUI for server side. Global $hSvrGUI = GUICreate("Named Pipe SERVER", 600, 360, 50, 50) GUISetOnEvent($GUI_EVENT_CLOSE, "_ShutDownSvr") GUICtrlCreateLabel("Purpose of SERVER: Return the cube root of a number via named pipe", 10, 10, 580, 20, $SS_CENTER) Global $SvrReadEdit = GUICtrlCreateEdit("", 10, 40, 285, 200) Global $SvrWriteEdit = GUICtrlCreateEdit("", 305, 40, 285, 200) GUICtrlCreateLabel("Pipe Status:", 10, 265, 150, 20, $SS_RIGHT) Global $SvrPipeStatus = GUICtrlCreateInput("No pipe created", 170, 265, 150, 20, $SS_LEFT, $ES_READONLY) GUICtrlCreateButton("Create Pipe", 330, 260, 100, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") GUICtrlCreateLabel("Connection Status:", 10, 315, 150, 20, $SS_RIGHT) Global $SvrConnStatus = GUICtrlCreateInput("No connection to pipe", 170, 315, 150, 20, $SS_LEFT, $ES_READONLY) GUICtrlCreateButton("Connect To Pipe", 330, 310, 100, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") GUICtrlCreateButton("Pipe Handle State", 465, 285, 100, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") GUISetState(@SW_SHOW, $hSvrGUI) While 1 Sleep(20) WEnd Func _ShutDownSvr() Exit EndFunc ;==>_ShutDownSvr Func _ButtonHit() Local $hGUI_WinHandle = @GUI_WinHandle, $hGUI_CtrlHandle = @GUI_CtrlHandle, $iGUI_CtrlId = @GUI_CtrlId Local $sButtonTxt = ControlGetText($hGUI_WinHandle, "", $iGUI_CtrlId) ConsoleWrite("Debug: _ButtonHit: Button clicked = " & $sButtonTxt) Switch $sButtonTxt Case "Create Pipe" $hNamedPipe = _NamedPipes_CreateNamedPipe($sNamedPipe) If $hNamedPipe <> -1 Then ControlSetText($hGUI_WinHandle, "", $SvrPipeStatus, "Pipe successfully created") ControlSetText($hGUI_WinHandle, "", $iGUI_CtrlId, "Delete Pipe") Else ControlSetText($hGUI_WinHandle, "", $SvrPipeStatus, "Error creating pipe") ControlSetText($hGUI_WinHandle, "", $iGUI_CtrlId, "Create Pipe") EndIf Case "Delete Pipe" FileClose($hNamedPipe) $hNamedPipe = 0 ControlSetText($hGUI_WinHandle, "", $SvrPipeStatus, "Pipe handle closed") ControlSetText($hGUI_WinHandle, "", $iGUI_CtrlId, "Create Pipe") Case "Connect To Pipe" If _NamedPipes_ConnectNamedPipe($hNamedPipe, 1) Then ControlSetText($hSvrGUI, "", $SvrConnStatus, "Connected to pipe") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Disconnect From Pipe") $fSvrConn = True Else $fSvrConn = False ControlSetText($hSvrGUI, "", $SvrConnStatus, "Error connecting to pipe") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Connect To Pipe") EndIf Case "Disconnect From Pipe" If _NamedPipes_DisconnectNamedPipe($hNamedPipe) Then $fSvrConn = False ControlSetText($hSvrGUI, "", $SvrConnStatus, "Pipe disconnected") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Connect To Pipe") Else ControlSetText($hSvrGUI, "", $SvrConnStatus, "Error disconnecting from pipe") ControlSetText($hSvrGUI, "", $iGUI_CtrlId, "Disconnect From Pipe") $fSvrConn = True EndIf Case "Pipe Handle State" _ArrayDisplay(_NamedPipes_GetNamedPipeHandleState($hNamedPipe), "Pipe Handle State") Case Else MsgBox(16, "Error", "Error! Function _ButtonHit() unhandled case $sButtonTxt = " & $sButtonTxt) EndSwitch EndFunc ;==>_ButtonHit As a first attempt, I'm not surprised my script doesn't work, but I didn't expect full crashes. Are there good demo/example scripts for using named pipes out there that I'm not finding? I know nothing about pipes I'm afraid, but did you know there is a client/server example in the @ProgramFiles\AutoIt3\Auto3Lib\Pipes? Also some explanation in the UDF help file. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
GaryFrost Posted December 15, 2007 Share Posted December 15, 2007 Client and Server Converted, not tested, too much going on my system at this time to test. SciTE for AutoItDirections for Submitting Standard UDFs  Don't argue with an idiot; people watching may not be able to tell the difference.  Link to comment Share on other sites More sharing options...
PsaltyDS Posted December 15, 2007 Author Share Posted December 15, 2007 I know nothing about pipes I'm afraid, but did you know there is a client/server example in the @ProgramFiles\AutoIt3\Auto3Lib\Pipes? Also some explanation in the UDF help file. Didn't realize that demo was there. I did read the function headers and scan the code in the UDF. Pretty dense stuff (or pretty dense reader). But I'm trying to absorb it. Client and Server Converted, not tested, too much going on my system at this time to test. Those demos work fine. Thanks Gary. All I have to do now is understand it all! Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
namingexception Posted January 23, 2008 Share Posted January 23, 2008 I'm having a hard time getting named pipes, which are perfect for a project that I'm working on, to work properly. Unfortunately, the attachments with examples are no longer attached, and the demo referenced in the auto3lib directory no longer comes with an installation. Also I downloaded some archived versions of AutoIt3 and can't find it in those, either. I tried to follow along with an example in C, but it didn't work for me. So, anyone have a quick named pipe client/server example they can share? I would appreciate it very much! Thanks, Kevin Link to comment Share on other sites More sharing options...
PsaltyDS Posted January 23, 2008 Author Share Posted January 23, 2008 The demos are part of PaulIA's original AU3 Library functions, not part of the AutoIt distribution. The original topic is here: Auto3Lib, A library of functions for AutoIt The files are not attached and the topic is closed because Paul isn't around anymore and doesn't support it. The standardization of Global CONST variables across the UDFs has broken a lot of that code, so you won't get support either from Paul or the AutoIt devs for the old versions. Here are the original examples if you want to play with them: Here is the readme file Pipes.txt: Special thanks to Yoan Roblet (Arcker) for his help in developing the Pipes module for Auto3Lib. Yoan provided the ground work for the development of the pipe UDFs and was instrumental in providing help and support during the debug phase. Console.au3 ----------- This demo shows how to execute a console command and read the output of the command using a one way pipe. Client.au3 ----------- This is the client part of the client/server pipe demo. It allows you to execute console commands on a local or remote computer and view the output. If you run the server part on a remote machine, you must have established network credentials on the remote machine. Server.au3 ----------- This is the server part of the client/server pipe demo. You must run this part of the demo on a local or remote machine BEFORE using the client part. Here is Console.au3: CODE#include <A3LPipes.au3> #include <A3LWinAPI.au3> Opt("MustDeclareVars", 1) ; ==================================================================================================== =========================== ; Description ...: Shows how to use pipe functions to read the output from a console operation ; Author ........: Paul Campbell (PaulIA) ; Notes .........: This script MUST be run in SciTE in order to see the results ; ==================================================================================================== =========================== ; ==================================================================================================== =========================== ; Main ; ==================================================================================================== =========================== ExecuteCmd("cmd.exe /c dir c:\windows") ;ExecuteCmd("ping www.autoit.com") ; ==================================================================================================== =========================== ; Execute a command and display the results ; ==================================================================================================== =========================== Func ExecuteCmd($sCmd) Local $iBytes, $sData, $hReadPipe, $hWritePipe, $tBuffer, $tProcess, $tSecurity, $tStartup ; Set up security attributes $tSecurity = DllStructCreate($tagSECURITY_ATTRIBUTES) DllStructSetData($tSecurity, "Length", DllStructGetSize($tSecurity)) DllStructSetData($tSecurity, "InheritHandle", True) ; Create a pipe for the child process's STDOUT _Pipe_CreatePipe($hReadPipe, $hWritePipe, $tSecurity) ; Create child process $tProcess = DllStructCreate($tagPROCESS_INFORMATION) $tStartup = DllStructCreate($tagSTARTUPINFO) DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup)) DllStructSetData($tStartup, "Flags", BitOR($STARTF_USESTDHANDLES, $STARTF_USESHOWWINDOW)) DllStructSetData($tStartup, "StdOutput", $hWritePipe) DllStructSetData($tStartup, "StdError", $hWritePipe) _API_CreateProcess("", $sCmd, 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) _API_CloseHandle(DllStructGetData($tProcess, "hProcess")) _API_CloseHandle(DllStructGetData($tProcess, "hThread")) ; Close the write end of the pipe before reading from the read end of the pipe _API_CloseHandle($hWritePipe) ; Read data from the child process $tBuffer = DllStructCreate("char Text[4096]") While 1 _API_ReadFile($hReadPipe, DllStructGetPtr($tBuffer), 4096, $iBytes) If $iBytes = 0 Then ExitLoop $sData = StringLeft(DllStructGetData($tBuffer, "Text"), $iBytes) $sData = StringReplace($sData, @CR & @CR, @CR) ConsoleWrite($sData) WEnd EndFunc ;==>ExecuteCmd Here is Client.au3: CODE#include <A3LPipes.au3> Opt("MustDeclareVars", 1) ; ==================================================================================================== =========================== ; Description ...: This is the client side of the pipe demo ; Author ........: Paul Campbell (PaulIA) ; Notes .........: ; ==================================================================================================== =========================== ; ==================================================================================================== =========================== ; Global constants ; ==================================================================================================== =========================== Global Const $BUFSIZE = 4096 Global Const $DEFCMD = "cmd.exe /c dir c:\windows /s" Global Const $PIPE_NAME = "\\$\\pipe\\Auto3Lib" ; ==================================================================================================== =========================== ; Global variables ; ==================================================================================================== =========================== Global $iEdit, $iMemo, $iSend, $iServer, $hPipe ; ==================================================================================================== =========================== ; Main ; ==================================================================================================== =========================== CreateGUI() MsgLoop() ; ==================================================================================================== =========================== ; Creates a GUI for the client ; ==================================================================================================== =========================== Func CreateGUI() Local $hGUI, $iLabel1, $iLabel2 $hGUI = GUICreate("Pipe Client", 500, 400, -1, -1, $WS_SIZEBOX) $iLabel1 = GUICtrlCreateLabel("Server:", 2, 14, 52, 20, $SS_RIGHT) $iServer = GUICtrlCreateEdit("<local>", 56, 10, 200, 20, $SS_LEFT) $iLabel2 = GUICtrlCreateLabel("Command:", 2, 36, 52, 20, $SS_RIGHT) $iEdit = GUICtrlCreateEdit($DEFCMD, 56, 32, 370, 20, $SS_LEFT) $iSend = GUICtrlCreateButton("Send", 430, 32, 60, 20) $iMemo = GUICtrlCreateEdit("", 0, 62, _API_GetClientWidth($hGUI), 332) GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New") GUISetState() EndFunc ;==>CreateGUI ; ==================================================================================================== =========================== ; Logs an error message to the display ; ==================================================================================================== =========================== Func LogError($sMessage) $sMessage &= " (" & _API_GetLastErrorMessage() & ")" GUICtrlSetData($iMemo, GUICtrlRead($iMemo) & $sMessage & @CRLF) EndFunc ;==>LogError ; ==================================================================================================== =========================== ; Logs a message to the display ; ==================================================================================================== =========================== Func LogMsg($sMessage) GUICtrlSetData($iMemo, GUICtrlRead($iMemo) & $sMessage & @CRLF) EndFunc ;==>LogMsg ; ==================================================================================================== =========================== ; MsgLoop ; ==================================================================================================== =========================== Func MsgLoop() While True Switch GUIGetMsg() Case $iSend SendCmd() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd EndFunc ;==>MsgLoop ; ==================================================================================================== =========================== ; This function opens a pipe to the server ; ==================================================================================================== =========================== Func OpenPipe() Local $sName, $sPipe ; Get pipe handle $sName = GUICtrlRead($iServer) If $sName = "<local>" Then $sName = "." $sPipe = StringReplace($PIPE_NAME, "$", $sName) $hPipe = _API_CreateFile($sPipe, 2, 6) If $hPipe <> -1 Then Return True LogError("OpenPipe failed") Return False EndFunc ;==>OpenPipe ; ==================================================================================================== =========================== ; This function reads a message from the pipe ; ==================================================================================================== =========================== Func ReadMsg() Local $bSuccess, $iRead, $pBuffer, $tBuffer $tBuffer = DllStructCreate("char Text[4096]") $pBuffer = DllStructGetPtr($tBuffer) GUICtrlSetData($iMemo, "") While 1 $bSuccess = _API_ReadFile($hPipe, $pBuffer, $BUFSIZE, $iRead, 0) If $iRead = 0 Then ExitLoop If Not $bSuccess Or (@error = $ERROR_MORE_DATA) Then ExitLoop GUICtrlSetData($iMemo, StringLeft(DllStructGetData($tBuffer, "Text"), $iRead), 1) WEnd EndFunc ;==>ReadMsg ; ==================================================================================================== =========================== ; This function sends a command to the server ; ==================================================================================================== =========================== Func SendCmd() If OpenPipe() Then SetReadMode() WriteMsg(GUICtrlRead($iEdit)) ReadMsg() _API_CloseHandle($hPipe) EndIf EndFunc ;==>SendCmd ; ==================================================================================================== =========================== ; This function sets the pipe read mode ; ==================================================================================================== =========================== Func SetReadMode() If Not _Pipe_SetNamedPipeHandleState($hPipe, 1, 0, 0, 0) Then LogError("SetReadMode: _Pipe_SetNamedPipeHandleState failed") EndIf EndFunc ;==>SetReadMode ; ==================================================================================================== =========================== ; This function writes a message to the pipe ; ==================================================================================================== =========================== Func WriteMsg($sMessage) Local $iWritten, $iBuffer, $pBuffer, $tBuffer $iBuffer = StringLen($sMessage) + 1 $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tBuffer, "Text", $sMessage) If Not _API_WriteFile($hPipe, $pBuffer, $iBuffer, $iWritten, 0) Then LogError("WriteMsg: _API_WriteFile failed") EndIf EndFunc ;==>WriteMsg Here is Server.au3: CODE#include <A3LPipes.au3> Opt("MustDeclareVars", 1) ; ==================================================================================================== =========================== ; Description ...: This is the server side of the pipe demo ; Author ........: Paul Campbell (PaulIA) ; Notes .........: ; ==================================================================================================== =========================== ; ==================================================================================================== =========================== ; Global constants ; ==================================================================================================== =========================== Global Const $DEBUGGING = False Global Const $BUFSIZE = 4096 Global Const $PIPE_NAME = "\\.\\pipe\\Auto3Lib" Global Const $TIMEOUT = 5000 ; ==================================================================================================== =========================== ; Global variables ; ==================================================================================================== =========================== Global $hEvent, $iMemo, $pOverlap, $tOverlap, $hPipe, $hReadPipe, $iState, $iToWrite ; ==================================================================================================== =========================== ; Main ; ==================================================================================================== =========================== CreateGUI() InitPipe() MsgLoop() ; ==================================================================================================== =========================== ; Creates a GUI for the server ; ==================================================================================================== =========================== Func CreateGUI() Local $hGUI $hGUI = GUICreate("Pipe Server", 500, 400, -1, -1, $WS_SIZEBOX) $iMemo = GUICtrlCreateEdit("", 0, 0, _API_GetClientWidth($hGUI), _API_GetClientHeight($hGUI)) GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New") GUISetState() EndFunc ;==>CreateGUI ; ==================================================================================================== =========================== ; This function creates an instance of a named pipe ; ==================================================================================================== =========================== Func InitPipe() ; Create an event object for the instance $tOverlap = DllStructCreate($tagOVERLAPPED) $pOverlap = DllStructGetPtr($tOverlap) $hEvent = _API_CreateEvent() If $hEvent = 0 Then LogError("InitPipe ..........: API_CreateEvent failed") Return EndIf DllStructSetData($tOverlap, "hEvent", $hEvent) ; Create a named pipe $hPipe = _Pipe_CreateNamedPipe($PIPE_NAME, _ ; Pipe name 2, _ ; The pipe is bi-directional 2, _ ; Overlapped mode is enabled 0, _ ; No security ACL flags 1, _ ; Data is written to the pipe as a stream of messages 1, _ ; Data is read from the pipe as a stream of messages 0, _ ; Blocking mode is enabled 1, _ ; Maximum number of instances $BUFSIZE, _ ; Output buffer size $BUFSIZE, _ ; Input buffer size $TIMEOUT, _ ; Client time out 0) ; Default security attributes If $hPipe = -1 Then LogError("InitPipe ..........: _Pipe_CreateNamedPipe failed") Else ; Connect pipe instance to client ConnectClient() EndIf EndFunc ;==>InitPipe ; ==================================================================================================== =========================== ; This function loops waiting for a connection event or the GUI to close ; ==================================================================================================== =========================== Func MsgLoop() Local $iEvent Do $iEvent = _API_WaitForSingleObject($hEvent, 0) If $iEvent < 0 Then LogError("MsgLoop ...........: _API_WaitForSingleObject failed") Exit EndIf If $iEvent = $WAIT_TIMEOUT Then ContinueLoop Debug("MsgLoop ...........: Instance signaled") Switch $iState Case 0 CheckConnect() Case 1 ReadRequest() Case 2 CheckPending() Case 3 RelayOutput() EndSwitch Until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc ;==>MsgLoop ; ==================================================================================================== =========================== ; Checks to see if the pending client connection has finished ; ==================================================================================================== =========================== Func CheckConnect() Local $iBytes ; Was the operation successful? If Not _API_GetOverlappedResult($hPipe, $pOverlap, $iBytes, False) Then LogError("CheckConnect ......: Connection failed") ReconnectClient() Else LogMsg("CheckConnect ......: Connected") $iState = 1 EndIf EndFunc ;==>CheckConnect ; ==================================================================================================== =========================== ; This function reads a request message from the client ; ==================================================================================================== =========================== Func ReadRequest() Local $pBuffer, $tBuffer, $iRead, $bSuccess, $iToWrite $tBuffer = DllStructCreate("char Text[" & $BUFSIZE & "]") $pBuffer = DllStructGetPtr($tBuffer) $bSuccess = _API_ReadFile($hPipe, $pBuffer, $BUFSIZE, $iRead, $pOverlap) If $bSuccess And ($iRead <> 0) Then ; The read operation completed successfully Debug("ReadRequest .......: Read success") Else ; Wait for read Buffer to complete If Not _API_GetOverlappedResult($hPipe, $pOverlap, $iRead, True) Then LogError("ReadRequest .......: _API_GetOverlappedResult failed") ReconnectClient() Return Else ; Read the command from the pipe $bSuccess = _API_ReadFile($hPipe, $pBuffer, $BUFSIZE, $iRead, $pOverlap) If Not $bSuccess Or ($iRead = 0) Then LogError("ReadRequest .......: _API_ReadFile failed") ReconnectClient() Return EndIf EndIf EndIf ; Execute the console command If Not ExecuteCmd(DllStructGetData($tBuffer, "Text")) Then ReconnectClient() Return EndIf ; Relay console output back to the client $iState = 3 EndFunc ;==>ReadRequest ; ==================================================================================================== =========================== ; This function relays the console output back to the client ; ==================================================================================================== =========================== Func CheckPending() Local $bSuccess, $iWritten $bSuccess = _API_GetOverlappedResult($hPipe, $pOverlap, $iWritten, False) If Not $bSuccess Or ($iWritten <> $iToWrite) Then Debug("CheckPending ......: Write reconnecting") ReconnectClient() Else Debug("CheckPending ......: Write complete") $iState = 3 EndIf EndFunc ;==>CheckPending ; ==================================================================================================== =========================== ; This function relays the console output back to the client ; ==================================================================================================== =========================== Func RelayOutput() Local $pBuffer, $tBuffer, $sLine, $iRead, $bSuccess, $iWritten $tBuffer = DllStructCreate("char Text[" & $BUFSIZE & "]") $pBuffer = DllStructGetPtr($tBuffer) ; Read data from console pipe _API_ReadFile($hReadPipe, $pBuffer, $BUFSIZE, $iRead) If $iRead = 0 Then LogMsg("RelayOutput .......: Write done") _API_CloseHandle($hReadPipe) _API_FlushFileBuffers($hPipe) ReconnectClient() Return EndIf ; Get the data and strip out the extra carriage returns $sLine = StringLeft(DllStructGetData($tBuffer, "Text"), $iRead) $sLine = StringReplace($sLine, @CR & @CR, @CR) $iToWrite = StringLen($sLine) DllStructSetData($tBuffer, "Text", $sLine) ; Relay the data back to the client $bSuccess = _API_WriteFile($hPipe, $pBuffer, $iToWrite, $iWritten, $pOverlap) If $bSuccess And ($iWritten = $iToWrite) Then Debug("RelayOutput .......: Write success") Else If Not $bSuccess And (@error = $ERROR_IO_PENDING) Then Debug("RelayOutput .......: Write pending") $iState = 2 Else ; An error occurred, disconnect from the client LogError("RelayOutput .......: Write failed") ReconnectClient() EndIf EndIf EndFunc ;==>RelayOutput ; ==================================================================================================== =========================== ; This function is called to start an overlapped connection operation ; ==================================================================================================== =========================== Func ConnectClient() $iState = 0 ; Start an overlapped connection If _Pipe_ConnectNamedPipe($hPipe, $pOverlap) Then LogError("ConnectClient .....: ConnectNamedPipe 1 failed") Else Switch @error ; The overlapped connection is in progress Case $ERROR_IO_PENDING Debug("ConnectClient .....: Pending") ; Client is already connected, so signal an event Case $ERROR_PIPE_CONNECTED LogMsg("ConnectClient .....: Connected") $iState = 1 If Not _API_SetEvent(DllStructGetData($tOverlap, "hEvent")) Then LogError("ConnectClient .....: SetEvent failed") EndIf ; Error occurred during the connection event Case Else LogError("ConnectClient .....: ConnectNamedPipe 2 failed") EndSwitch EndIf EndFunc ;==>ConnectClient ; ==================================================================================================== =========================== ; Dumps debug information to the screen ; ==================================================================================================== =========================== Func Debug($sMessage) If $DEBUGGING Then LogMsg($sMessage) EndFunc ;==>Debug ; ==================================================================================================== =========================== ; Executes a command and returns the results ; ==================================================================================================== =========================== Func ExecuteCmd($sCmd) Local $tProcess, $tSecurity, $tStartup, $hWritePipe ; Set up security attributes $tSecurity = DllStructCreate($tagSECURITY_ATTRIBUTES) DllStructSetData($tSecurity, "Length", DllStructGetSize($tSecurity)) DllStructSetData($tSecurity, "InheritHandle", True) ; Create a pipe for the child process's STDOUT If Not _Pipe_CreatePipe($hReadPipe, $hWritePipe, $tSecurity) Then LogError("ExecuteCmd ........: _Pipe_CreatePipe failed") Return False EndIf ; Create child process $tProcess = DllStructCreate($tagPROCESS_INFORMATION) $tStartup = DllStructCreate($tagSTARTUPINFO) DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup)) DllStructSetData($tStartup, "Flags", BitOR($STARTF_USESTDHANDLES, $STARTF_USESHOWWINDOW)) DllStructSetData($tStartup, "StdOutput", $hWritePipe) DllStructSetData($tStartup, "StdError", $hWritePipe) If Not _API_CreateProcess("", $sCmd, 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) Then LogError("ExecuteCmd ........: _API_CreateProcess failed") _API_CloseHandle($hReadPipe) _API_CloseHandle($hWritePipe) Return False EndIf _API_CloseHandle(DllStructGetData($tProcess, "hProcess")) _API_CloseHandle(DllStructGetData($tProcess, "hThread")) ; Close the write end of the pipe so that we can read from the read end _API_CloseHandle($hWritePipe) LogMsg("ExecuteCommand ....: " & $sCmd) Return True EndFunc ;==>ExecuteCmd ; ==================================================================================================== =========================== ; Logs an error message to the display ; ==================================================================================================== =========================== Func LogError($sMessage) $sMessage &= " (" & _API_GetLastErrorMessage() & ")" _Lib_ConsoleWrite($sMessage) EndFunc ;==>LogError ; ==================================================================================================== =========================== ; Logs a message to the display ; ==================================================================================================== =========================== Func LogMsg($sMessage) GUICtrlSetData($iMemo, $sMessage & @CRLF, 1) EndFunc ;==>LogMsg ; ==================================================================================================== =========================== ; This function is called when an error occurs or when the client closes its handle to the pipe ; ==================================================================================================== =========================== Func ReconnectClient() ; Disconnect the pipe instance If Not _Pipe_DisconnectNamedPipe($hPipe) Then LogError("ReconnectClient ...: DisonnectNamedPipe failed") Return EndIf ; Connect to a new client ConnectClient() EndFunc ;==>ReconnectClient Good luck with it. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
namingexception Posted January 23, 2008 Share Posted January 23, 2008 Thank you very much. Link to comment Share on other sites More sharing options...
laurent68 Posted July 21, 2008 Share Posted July 21, 2008 Thank you very much.any news, do you try to do something with this lib ?Do you success ? Link to comment Share on other sites More sharing options...
MegaGamerGuy Posted February 25, 2012 Share Posted February 25, 2012 (edited) *bump* if i may, i could use this a lot ThanksDid a search, found a working version of both scritps Edited February 25, 2012 by MegaGamerGuy Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now