Win32 API 事件 - 它在跨不同进程访问方面的限制是什么?
Win32 API Events- What are its limitations in terms of access across different processes?
所以,我有一个应用程序连接到一个库,该库在不同的线程中处理许多不同的任务。
在库的一个线程中,不是库的主线程,创建了一个事件。
但是,当我尝试从使用库本身的应用程序打开事件时,我总是收到无效的 HANDLE
。
该事件不使用私有命名空间,也没有为 Win32 的内核对象命名空间指定任何选项 - 这是非常默认的。
事实上,这是用于在库线程中创建事件的函数:
CreateEventA(NULL, FALSE, FALSE, eventName);
稍后在同一线程中使用以下参数打开事件的调用有效:
OpenEventA(EVENT_ALL_ACCESS, FALSE, eventName); // returns event without issue
此外,根据 MSDN,声明如下 here:
The creating thread can also specify a name for the event object.
Threads in other processes can open a handle to an existing event object by specifying its name in a call to the OpenEvent function.
显然这也不是一个错误,因为重复了相同的要点 here:
The process that creates an object can use the handle returned by the creation function (CreateEvent, CreateMutex, CreateSemaphore, or CreateWaitableTimer).
Other processes can open a handle to the object by using its name, or through inheritance or duplication.
我浏览了 MSDN 以找到可以明确说明情况并非如此的内容,但我还没有找到任何内容。
我还可以声明,在应用程序中查询事件时,我已经看到库线程中的事件处于活动状态 - 据我所知,这排除了它根本没有被创建的可能性。
有人可以阐明为什么当通过应用程序查询时 OpenEvent
的事件 returns NULL 吗?
更新
回复@FrerichRaabe:
返回的错误码为2,即ERROR_FILE_NOT_FOUND
.
@IInspectable:
有趣;我忘了说我实际上已经尝试过为事件使用全局命名空间,这显然也没有用。返回的也是与上面提到的相同的错误...
可能是 EVENT_ALL_ACCESS 标志。你真的需要它吗?
通常 "SYNCHRONIZE | EVENT_MODIFY_STATE" 足够用于活动。
试试看,然后告诉我们。
您的问题是由 2 个不幸的决定引起的:使用名称中包含非 ASCII 字符的事件,以及调用 API 的 ANSI 版本(由结尾的 A
表示)。
由于系统内部使用 Unicode,因此无论何时调用 ANSI API,字符串参数都会转换为 Unicode。非 ASCII 字符的转换由线程的当前语言环境控制。这解释了为什么在同一线程上调用 OpenEventA
成功,而在另一个线程上调用失败。
要解决此问题,请将对 ANSI API 的调用替换为各自的 Unicode 版本 CreateEventW
和 OpenEventW
。
所以,我有一个应用程序连接到一个库,该库在不同的线程中处理许多不同的任务。
在库的一个线程中,不是库的主线程,创建了一个事件。
但是,当我尝试从使用库本身的应用程序打开事件时,我总是收到无效的 HANDLE
。
该事件不使用私有命名空间,也没有为 Win32 的内核对象命名空间指定任何选项 - 这是非常默认的。
事实上,这是用于在库线程中创建事件的函数:
CreateEventA(NULL, FALSE, FALSE, eventName);
稍后在同一线程中使用以下参数打开事件的调用有效:
OpenEventA(EVENT_ALL_ACCESS, FALSE, eventName); // returns event without issue
此外,根据 MSDN,声明如下 here:
The creating thread can also specify a name for the event object.
Threads in other processes can open a handle to an existing event object by specifying its name in a call to the OpenEvent function.
显然这也不是一个错误,因为重复了相同的要点 here:
The process that creates an object can use the handle returned by the creation function (CreateEvent, CreateMutex, CreateSemaphore, or CreateWaitableTimer).
Other processes can open a handle to the object by using its name, or through inheritance or duplication.
我浏览了 MSDN 以找到可以明确说明情况并非如此的内容,但我还没有找到任何内容。
我还可以声明,在应用程序中查询事件时,我已经看到库线程中的事件处于活动状态 - 据我所知,这排除了它根本没有被创建的可能性。
有人可以阐明为什么当通过应用程序查询时 OpenEvent
的事件 returns NULL 吗?
更新
回复@FrerichRaabe:
返回的错误码为2,即ERROR_FILE_NOT_FOUND
.
@IInspectable:
有趣;我忘了说我实际上已经尝试过为事件使用全局命名空间,这显然也没有用。返回的也是与上面提到的相同的错误...
可能是 EVENT_ALL_ACCESS 标志。你真的需要它吗? 通常 "SYNCHRONIZE | EVENT_MODIFY_STATE" 足够用于活动。
试试看,然后告诉我们。
您的问题是由 2 个不幸的决定引起的:使用名称中包含非 ASCII 字符的事件,以及调用 API 的 ANSI 版本(由结尾的 A
表示)。
由于系统内部使用 Unicode,因此无论何时调用 ANSI API,字符串参数都会转换为 Unicode。非 ASCII 字符的转换由线程的当前语言环境控制。这解释了为什么在同一线程上调用 OpenEventA
成功,而在另一个线程上调用失败。
要解决此问题,请将对 ANSI API 的调用替换为各自的 Unicode 版本 CreateEventW
和 OpenEventW
。