Opened 17 months ago
Closed 16 months ago
#3963 closed Feature Request (Completed)
_WinAPI_OpenEvent function missing in WinAPIProc.au3
Reported by: | kleiza44@… | Owned by: | Jpm |
---|---|---|---|
Milestone: | 3.3.17.0 | Component: | AutoIt |
Version: | Severity: | None | |
Keywords: | Cc: |
Description
Please add _WinAPI_OpenEvent function that allows to check global events from windows.
_WinAPI_CreateEvent function by documentation should allow to open events, but if global event was created using different application, then script won't be able to access it.
Function written in AutoIT which works in my case (Maybe positions of parameters could be changed like in already written AutoIT functions, to keep same structure in all AutoIT functions):
Func _WinAPI_OpenEvent($sName = "", $dwDesiredAccess = 0x1F0003 , $bInheritHandle = True) If $sName = "" Then $sName = Null Local $aCall = DllCall("kernel32.dll", "handle", "OpenEventW", "struct*", $dwDesiredAccess, "bool", $bInheritHandle, _ "wstr", $sName) If @error Then Return SetError(@error, @extended, 0) Local $iLastError = _WinAPI_GetLastError() If $iLastError Then Return SetExtended($iLastError, 0) Return $aCall[0] EndFunc ;==>_WinAPI_OpenEvent
If this function can be added, then it would make sense to add it to documentation as well like in here : https://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_CreateEvent.htm
Attachments (0)
Change History (9)
comment:1 follow-up: ↓ 2 Changed 17 months ago by Jpm
comment:2 in reply to: ↑ 1 Changed 17 months ago by anonymous
Replying to Jpm:
Hi,
Can you explain why the first paraameter can be optional (not described in MSDN) ?
can you post an example so I can add it in the doc?
Thanks for the help
Hi,
I just copied the _WinAPI_CreateEvent implementation and replaced parameters/names to make it work with OpenEvent() function. My example is probably incorrect, but since I provide all parameters myself when calling it, it was working for me.
Sorry I am not advanced enough to write clean code as in documentation, but for that I have modified my script to get global event from third party software and it looks like this :
#include <WinAPIHObj.au3> #include <WinAPIProc.au3> #include <Date.au3> Func _WinAPI_OpenEvent($dwDesiredAccess, _ ; Not provided value should translate to EVENT_ALL_ACCESS $bInheritHandle, _ ; Usually is false $sName) ; If you provide empty string or null, it will create a nameless event If $sName = "" Then $sName = Null Local $aCall = DllCall("kernel32.dll", "handle", "OpenEventW", "struct*", $dwDesiredAccess, "bool", $bInheritHandle, "wstr", $sName) If @error Then Return SetError(@error, @extended, 0) Local $iLastError = _WinAPI_GetLastError() If $iLastError Then Return SetExtended($iLastError, 0) Return $aCall[0] EndFunc ;==>_WinAPI_OpenEvent Global $Event = _WinAPI_OpenEvent(0x1F0003, _ ;Value is EVENT_ALL_ACCESS False, "Global\HeartBeatEvent") ;Get global event handle Local $iEvent Local $cycle = True HotKeySet("{ESC}", "_Exit") While $cycle = True $iEvent = _WinAPI_WaitForSingleObject($Event, 1000) ;Get event from handle Switch $iEvent Case -1 ;WAIT_FAILED ConsoleWrite(_Now() & " WAIT_FAILED" & @CRLF) $ErrMsg = _WinAPI_GetLastErrorMessage(@extended) ConsoleWrite("Result:" & $Event & @CRLF & $ErrMsg & @CRLF) ExitLoop Case 0 ;WAIT_OBJECT_0 _WinAPI_ResetEvent($Event) ConsoleWrite(_Now() & " Event appeared as expected." & @CRLF) Case 0x00000102 ;WAIT_TIMEOUT ConsoleWrite(_Now() & " Event not appeared." & @CRLF) Case 0x00000080 ;WAIT_ABANDONED ConsoleWrite(_Now() & " WAIT_ABANDONED" & @CRLF) ExitLoop EndSwitch Sleep(1000) WEnd ;==>While Func _Exit() $cycle = False EndFunc ;==>_Exit
Please let me know if I can help you somehow more.
comment:3 Changed 17 months ago by Jpm
Thanks,
I still wondering when openinf with Null is helpfull.
Can you provide me an example?
comment:4 Changed 17 months ago by Jpm
I recheck your example it is not working on my system
PLrase try with a correct checking of the result
#include <WinAPIHObj.au3> #include <WinAPIProc.au3> #include <Date.au3> Func _WinAPI_OpenEvent($sName, _ ; If you provide empty string or null, it will create a nameless event $dwDesiredAccess = 0x1F0003, _ ; Not provided value should translate to EVENT_ALL_ACCESS $bInheritHandle = False) ; Usually is false If $sName = "" Then $sName = Null Local $aCall = DllCall("kernel32.dll", "handle", "OpenEventW", "struct*", $dwDesiredAccess, "bool", $bInheritHandle, "wstr", $sName) If @error Then Return SetError(@error, @extended, 0) Local $iLastError = _WinAPI_GetLastError() If $iLastError Then Return SetExtended($iLastError, 0) Return $aCall[0] EndFunc ;==>_WinAPI_OpenEvent Local $iEvent, $sErrMsg Local $bCycle = True HotKeySet("{ESC}", "_Exit") Global $g_hEvent = _WinAPI_OpenEvent("Global\HeartBeatEvent", 0x1F0003, _ ;Value is EVENT_ALL_ACCESS False) ;Get global event handle Local $iExtended = @extended If $iExtended Then $sErrMsg = _WinAPI_GetErrorMessage($iExtended) ConsoleWrite("_WinAPI_OpenEvent() = " & $g_hEvent & @CRLF & $sErrMsg & @CRLF) Exit EndIf While $bCycle = True $iEvent = _WinAPI_WaitForSingleObject($g_hEvent, 1000) ;Get event from handle Switch $iEvent Case -1 ;WAIT_FAILED $sErrMsg = _WinAPI_GetErrorMessage($iExtended) ConsoleWrite("Result:" & $iEvent & "(WAIT_FAILED)" & @CRLF & $sErrMsg & @CRLF) ExitLoop Case 0 ;WAIT_OBJECT_0 _WinAPI_ResetEvent($g_hEvent) ConsoleWrite(_Now() & " Event appeared as expected." & @CRLF) Case 0x00000102 ;WAIT_TIMEOUT ConsoleWrite(_Now() & " Event not appeared." & @CRLF) Case 0x00000080 ;WAIT_ABANDONED ConsoleWrite(_Now() & " WAIT_ABANDONED" & @CRLF) ExitLoop EndSwitch Sleep(1000) WEnd ;==>While Func _Exit() $bCycle = False EndFunc ;==>_Exit
comment:5 Changed 17 months ago by anonymous
Hi! It seems a small error escaped you attention:
in
Local $aRet = DllCall("kernel32.dll", "handle", "OpenEventW", "struct*", $iDesired...
there should be "dword" instead of "struct*"
Local $aRet = DllCall("kernel32.dll", "handle", "OpenEventW", "dword", $iDesired...
Also, there was a wrong comment, stating that if an empty string is given to $sName, it will create an nameless event; that is incorrect; OpenEvent does not create events! and with empty $sName always returns 0x00000000.
Here's corrected version; this should be in WinAPIProc.au3:
Global Const $EVENT_ALL_ACCESS = 0x001F0003 Func _WinAPI_OpenEvent($sName, $iDesiredAccess = $EVENT_ALL_ACCESS, $bInheritHandle = False) if $iDesiredAccess=Default OR $iDesiredAccess=-1 then $iDesiredAccess = $EVENT_ALL_ACCESS Local $aRet = DllCall("kernel32.dll", "handle", "OpenEventW", "dword", $iDesiredAccess, "bool", $bInheritHandle, "wstr", $sName) Return SetError(@error, @extended, @error ? False : $aRet[0]) EndFunc
This could be used eg for interprocess communication between two+ scripts (together with _WinApi_[create/set/reset]Event(...)), since the created events are global and acccessable by name.
comment:6 Changed 17 months ago by anonymous
acktchully, it seems more sensible that $bInheritHandle by default should be True! Sorry about that.
from MSDN:
(https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-openeventa)
... [in] bInheritHandle If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.
comment:7 Changed 17 months ago by anonymous
(the code provided in comment 5 is placed by its anonymous author in the Public Domain, if this could even matter for such a measly teeny tiny wrapper!)
comment:8 Changed 17 months ago by Jpm
Thanks for the correction, but "Global\HeartBeatEvent" does NOT work on my system.
What can be another $sEvent working for any system as I plan to put the script as an example in the help
comment:9 Changed 16 months ago by Jpm
- Milestone set to 3.3.17.0
- Owner set to Jpm
- Resolution set to Completed
- Status changed from new to closed
Added by revision [13003] in version: 3.3.17.0
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Hi,
Can you explain why the first paraameter can be optional (not described in MSDN) ?
can you post an example so I can add it in the doc?
Thanks for the help