CreateEvent 失败(事件已存在于 \BaseNamedObjects 中)

CreateEvent fails (event already exists in \BaseNamedObjects)

前段时间我编写了一个小型 Win32 测试应用程序,它除了创建一个用于在两个进程之间同步的事件外什么也没做。回来后我惊呆了,即使 运行 作为管理员,CreateEvent 的进程也会 return 并出现错误 5(访问被拒绝)。

ghWriteEvent = CreateEvent( 
    NULL,                       // default security attributes
    FALSE,                      // auto-reset event
    FALSE,                      // initial state is nonsignaled
    TEXT("Global\WriteEvent")  // object name
    ); 

if (ghWriteEvent == NULL) 
{ 
    printf("CreateEvent failed (%d)\n", GetLastError());
    return 1;
}

经过一些调试后,我决定更改事件的名称,突然它起作用了。一次偶然的机会,我决定查看 WinObj 中的事件 creation/deletion,我明白了失败的原因:\BaseNamedObjects.

下已经有一个名为 WriteEvent 的事件

我可以做些什么来使命名事件在重新启动后持久,更重要的是,我怎样才能摆脱它?


编辑:似乎某些 other 应用程序在我的应用程序有机会这样做之前在全局命名空间中创建了 WriteEvent。 (现在)明显的解决方法是使用一些唯一的名称或使用 GUID 或任何避免名称冲突的方法。

CreateEventW 错误代码为 ERROR_ACCESS_DENIED 的命名对象失败时,这通常意味着其他人已经使用该名称创建了一个事件。在这种情况下,系统会尝试使用 EVENT_ALL_ACCESS 打开事件对象。当此访问模式与调用线程的 ACL 不兼容时,API 调用失败并显示 ERROR_ACCESS_DENIED.

要解决此问题,您需要为事件对象提供一个唯一的名称。一种常见的方法是使用 GUID 的字符串表示形式作为名称。您可以在 Visual Studio 开发人员命令提示符下使用 guidgen.exe 工具生成 GUID。