Jump to content

fp001

Members
  • Posts

    4
  • Joined

  • Last visited

Everything posted by fp001

  1. I love you! This is immensely helpful.
  2. Well, in the meanwhile i've found the following solution: Func _pipeReceive($pipeName,$wait=Default) If $wait=Default Then $wait=1 Local Const $pipePath = "\\.\pipe\"&$pipeName Local $sendBufferSize=4096 Local $receiveBufferSize=4096 Local $return="" Local $error="" If Not IsDeclared("pipeHandle") Then _ Global $pipeHandle = _NamedPipes_CreateNamedPipe( _ $pipePath, _ 2, _ ;access-mode (0 inbound, 1 outbound, 2 duplex) 2, _ ;flags 0, _ ;security ACL flags (none) 1, _ ;message mode (not byte-mode) 1, _ ;read mode Not($wait), _ ;0 - Blocking mode is enabled, 1 - Nonblocking mode is enabled --> Not($wait) 1, _ ;maximum number of instances that can be created for this pipe $receiveBufferSize, _ ;OutBufSize $sendBufferSize, _ ;InpBufSize 5000, _ ;time out value, in milliseconds (Maximum time, in milliseconds, that can pass before a remote named pipe transfers information) 0 _ ;pointer to a tagSECURITY_ATTRIBUTES structure ) If $pipeHandle <> -1 Then If $wait==1 Then _NamedPipes_ConnectNamedPipe($pipeHandle) ;peek Local $cache=_NamedPipes_PeekNamedPipe($pipeHandle) Local $error=@error ;error: 0 ... data received, all fine; 230 no input; 109 ... empty message received (?) $cache[0]=_StringReverse($cache[0]) $return=$cache[0] ;~ ConsoleWrite(@LF) ;~ ConsoleWrite($error&" (error); ") ;~ ConsoleWrite($cache[1]&" (Bytes read from the pipe); ") ;~ ConsoleWrite($cache[2]&" (Total bytes available to be read); ") ;~ ConsoleWrite($cache[3]&" (Bytes remaining to be read for this message); ") ;error handling If $error<>0 And $error<>230 And $error<>109 And $error<>536 Then _error("_pipeReceive [200912102031]: abnormal peekNamedPipe-@error-value; @error: "&$error) SetError(1) ;~ Return "" EndIf If $cache[2]-$cache[1]>0 Then _error("_pipeReceive [200912102031]: pipe-buffer overflow, terminating: bytes to be read: "&$cache[2]&"; bytes read: "&$cache[1]&"; difference: "&$cache[2]-$cache[1]) Exit EndIf _NamedPipes_DisconnectNamedPipe($pipeHandle) If $wait==0 Then _NamedPipes_ConnectNamedPipe($pipeHandle) ;return Return $return Else _error("_pipeReceive [200912102031]: _CreateNamedPipe() failed; $vzbEZ_PIPE_NAME "&$pipePath) SetError(1) Return "" Endif Return "" EndFunc In order to flush the buffer in non-blocking mode, I just make a disconnect and reconnect again: _NamedPipes_DisconnectNamedPipe($pipeHandle) If $wait==0 Then _NamedPipes_ConnectNamedPipe($pipeHandle) Unfortunately, there's still one serious limitation: if 4096 bites are exceeded (I tried specifying a greater size, however, 4096 seems to be the maximum), the rest will be lost on flushing the pipe and peekNamedPipe does not seem to allow for retrieving the remaining data. Help/feedback/suggestions are greatly appreciated.
  3. SkinnyWhiteGuy, thanks a lot for your code . It made creating the following UDF, which can be used to retrieve all current, non-virtual displays' positions, a doddle: #cs author: "SkinnyWhiteGuy" on http://www.autoitscript.com/forum/index.php?showtopic=105921 #ce #include-once ;out: [n][0:x 1:y 2:width 3:height 4:is primary] Func _displayGetPos() Local $returnArray[1][5] Local $tag_DISPLAY_DEVICE = "dword cb;char DeviceName[32];char DeviceString[128];dword StateFlags;char DeviceID[128];char DeviceKey[128]" Local $DISPLAY_DEVICE_MIRRORING_DRIVER = 0x00000008 Local $DISPLAY_DEVICE_PRIMARY_DEVICE = 0x00000004 Local $tag_POINTL = "long x;long y" Local $tag_DEVMOD = "char dmDeviceName[32];ushort dmSpecVersion;ushort dmDriverVersion;short dmSize;" & _ "ushort dmDriverExtra;dword dmFields;" & $tag_POINTL & ";dword dmDisplayOrientation;dword dmDisplayFixedOutput;" & _ "short dmColor;short dmDuplex;short dmYResolution;short dmTTOption;short dmCollate;" & _ "byte dmFormName[32];ushort LogPixels;dword dmBitsPerPel;int dmPelsWidth;dword dmPelsHeight;" & _ "dword dmDisplayFlags;dword dmDisplayFrequency" Local Const $ENUM_CURRENT_SETTINGS = -1 Local $i = 0 While 1 $struct = DllStructCreate($tag_DISPLAY_DEVICE) DllStructSetData($struct, "cb", DllStructGetSize($struct)) Local $aRetrun = DllCall("user32.dll", "int", "EnumDisplayDevices", "ptr", 0, "dword", $i, "ptr", DllStructGetPtr($struct), "dword", 0) If Not $aRetrun[0] Then ExitLoop If Not BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_MIRRORING_DRIVER) Then ; Avoid Virtual Displays ConsoleWrite(DllStructGetData($struct, "DeviceName") & @TAB & "Primary: " & (BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_PRIMARY_DEVICE) > 0) & @CRLF) $dev = DllStructCreate($tag_DEVMOD) DllStructSetData($dev, "dmSize", DllStructGetSize($dev)) $aRetrun = DllCall("user32.dll", "int", "EnumDisplaySettings", "str", DllStructGetData($struct, "DeviceName"), "dword", $ENUM_CURRENT_SETTINGS, "ptr", DllStructGetPtr($dev)) If IsNumber($returnArray[0][0]) Then ReDim $returnArray[UBound($returnArray)+1][5] ;if not first fill in, upsize $returnArray[UBound($returnArray)-1][0]=DllStructGetData($dev,"x") $returnArray[UBound($returnArray)-1][1]=DllStructGetData($dev,"y") $returnArray[UBound($returnArray)-1][2]=DllStructGetData($dev,"dmPelsWidth") $returnArray[UBound($returnArray)-1][3]=DllStructGetData($dev,"dmPelsHeight") $returnArray[UBound($returnArray)-1][4]=(BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_PRIMARY_DEVICE) > 0) ;is primary? EndIf $i += 1 WEnd Return $returnArray EndFunc
  4. Based on this post: http://www.autoitscript.com/forum/index.php?showtopic=59464, i have created these two functions: ;return: success: 1; failure: 0 or <>1 Func _pipeSend($pipeName,$data,$maxRetries=Default,$retryPause=Default,$retries=Default) If $maxRetries=Default Then $maxRetries=10 If $retryPause=Default Then $retryPause=10000 If $retries=Default Then $retries=0 Local Const $vzbEZ_PIPE_NAME = "\\.\pipe\"&$pipeName While 1 Local $file=FileOpen($vzbEZ_PIPE_NAME,2) If $file<>-1 Then FileWrite($file,$data) FileClose($file) Return 1 Else FileClose($file) If $retries<$maxRetries Then $retries+=1 Sleep($retryPause) ContinueLoop Else Return "couldNotOpenPipe" EndIf EndIf WEnd Return 0 EndFunc Func _pipeReceive($pipeName) Local Const $vzbEZ_PIPE_NAME = "\\.\pipe\"&$pipeName Local $pipeData[4] Local $return If Not IsDeclared("pipeHandle") Then Global $pipeHandle = _NamedPipes_CreateNamedPipe($vzbEZ_PIPE_NAME) If $pipeHandle <> -1 Then ; wait for a client process to connect to an instance of a named pipe If _NamedPipes_ConnectNamedPipe($pipeHandle) Then $pipeData = _NamedPipes_PeekNamedPipe($pipeHandle) $return=$pipeData[0] If Not _NamedPipes_DisconnectNamedPipe($pipeHandle) Then $return="" _error("_pipeReceive; DisconnectNamedPipe() failed; $vzbEZ_PIPE_NAME "&$vzbEZ_PIPE_NAME) Endif Else $return="" _error("_pipeReceive; connectNamedPipe() failed; $vzbEZ_PIPE_NAME "&$vzbEZ_PIPE_NAME) Exit Endif Else $return="" _error("_pipeReceive; _CreateNamedPipe() failed; $vzbEZ_PIPE_NAME "&$vzbEZ_PIPE_NAME) Endif Return $return EndFunc Unfortunately, _NamedPipes_ConnectNamedPipe() interrupts the execution until a pipe client connects. To avoid this I have tried: Func _pipeReceive($pipeName,$wait=Default) If $wait=Default Then $wait=1 Local Const $vzbEZ_PIPE_NAME = "\\.\pipe\"&$pipeName Local $pipeData[4] Local $return="" If Not IsDeclared("pipeHandle") Then _ Global $pipeHandle = _NamedPipes_CreateNamedPipe( _ $vzbEZ_PIPE_NAME, _ 2, _ ;bi-directional 2, _ ;overlapped mode 0, _ ;security ACL flags (none) 1, _ ;message mode (not byte-mode) 1, _ ;read mode is message Not($wait), _ ;0 - Blocking mode is enabled, 1 - Nonblocking mode is enabled --> Not($wait) 1, _ ;maximum number of instances that can be created for this pipe 4096, _ ;OutBufSize 4096, _ ;InpBufSize 5000, _ ;time out value, in milliseconds 0 _ ;pointer to a tagSECURITY_ATTRIBUTES structure ) If $pipeHandle <> -1 Then ;~ DllCall("psapi.dll","int","EmptyWorkingSet","long",-1); Reduziert Memory ;~ If _NamedPipes_ConnectNamedPipe($pipeHandle) Then While 1 ;~ If $wait==1 Then If _NamedPipes_ConnectNamedPipe($pipeHandle)==0 Then $return="couldNotConnectPipe" ExitLoop EndIf ;~ EndIf ;~ Local $inputBuffer="" ;~ Local $numberOfBytesRead=0 ;~ ;~ msgbox(1,"",_NamedPipes_CallNamedPipe( _ ;~ $pipeName, _ ;~ $inputBuffer, _ ;pInpBuf ;~ 4096, _ ;iInpSize ;~ $return, _ ;$pOutBuf ;~ 4096, _ ;$iOutSize ;~ $numberOfBytesRead, _ ;~ 0));-1 - Wait indefinitely 0 - Uses the default time-out specified in the call to the CreateNamedPipe 1 - Do not wait. If the pipe is not available, return an error ;~ MsgBox(0,"",$return) $pipeData = _NamedPipes_PeekNamedPipe($pipeHandle) ;~ MsgBox(1,"$pipeData",$pipeData) $return=$pipeData[0] ;~ _ArrayDisplay($pipeData,"$pipeData") If Not _NamedPipes_DisconnectNamedPipe($pipeHandle) Then $return="couldNotDisconnectPipe" _error("_pipeReceive; DisconnectNamedPipe() failed; $vzbEZ_PIPE_NAME "&$vzbEZ_PIPE_NAME) ExitLoop Endif ;~ Else ;~ $return="" ;~ _error("_pipeReceive; connectNamedPipe() failed; $vzbEZ_PIPE_NAME "&$vzbEZ_PIPE_NAME) ;~ Exit ;~ Endif ExitLoop WEnd Else $return="couldNotCreatePipe" _error("_pipeReceive; _CreateNamedPipe() failed; $pipeHandle: "&$pipeHandle&"; $vzbEZ_PIPE_NAME: "&$vzbEZ_PIPE_NAME) Endif Return $return EndFunc (The code is a bit messy, sorry for that.) This does not block the script, however, once a client has written something to the pipe, the function returns the same data over and over even if another instance of a client tries to write different data to the pipe (server). More oddly, the latter fails, as if the server pipe would not accept any more data. I have already tried to disconnect the server-side pipe and reconnect it again. I thought this would kind of "flush" the pipe and allow for further input. I kindly request support in this matter.
×
×
  • Create New...