【问题标题】:Different behaviour of an event object in Windows XP and Windows 7Windows XP 和 Windows 7 中事件对象的不同行为
【发布时间】:2011-05-26 21:13:41
【问题描述】:

在我的 C++/winapi 程序中,我使用一个事件对象来检测我的应用程序的一个实例是否已经在运行,以便不让第二个实例启动。

但同时,如果程序的多个实例使用不同的用户帐户启动,我想允许它们运行。例如。使用“runas”命令。 (即:每个用户帐号只能同时运行一个实例)

我使用如下代码:

HANDLE hSingleInstance=OpenEvent(EVENT_MODIFY_STATE,FALSE,
                                   "Local\\SingleInstanceEventName");
if(hSingleInstance!=NULL) {
  // there is an instance already running
  SetEvent(hSingleInstance);// let know the 1st instance that we are trying to start
  CloseHandle(hSingleInstance);
  return 0; // exit the program
}
else {
  // this is the 1st instance
  hSingleInstance=CreateEvent(NULL,FALSE,FALSE, "Local\\SingleInstanceEventName");
}

它在 XP 中按预期工作 - 我只能使用同一个用户帐户运行 1 个实例,我可以使用多个用户帐户运行多个实例。

但在 Windows 7 中,OpenEvent() 函数总是“找到”我的事件对象,即使事件对象是使用另一个用户帐户创建的。因此,我无法使用不同的用户帐户(根据需要)运行多个实例。

我应该在我的代码中进行哪些更改以允许在 Windows 7 中使用不同的用户帐户运行多个实例? 或者也许我的方法完全错误,那么什么是正确的?

谢谢

【问题讨论】:

  • 顺便说一句,您的代码中似乎存在竞争条件:大约同时启动的两个实例可能会尝试执行“打开偶数”,都失败,然后都继续进行 CreateEvent ,两者都认为他们是“第一个”——即使事件已经存在,CreateEvent 也会成功。正确的做法是只调用 CreateEvent,然后如果成功,检查 GetLastError 是否有 ERROR_ALREADY_EXISTS。 (这是基本的想法,请在网上查看示例代码并填写详细信息。)不清楚这是否真的是您的问题的原因,但无论如何都值得检查。

标签: winapi windows-7


【解决方案1】:

您所要做的就是以某种方式在活动名称中包含用户名。坦率地说,我有点惊讶您的方案在 XP 中有效。

【讨论】:

    【解决方案2】:

    我认为您在这里遇到了安全问题。一般来说,一个应用程序无法修改由另一个以另一个用户身份运行的应用程序创建的对象,因此如果一个应用程序创建了事件对象,那么以另一个用户身份运行的应用程序应该无法打开它——即使它已经退出。

    从 Vista 开始,这有一些细微的变化;运行“高架”的概念引入了额外的皱纹;它与以其他用户身份运行类似,但并不完全相同。出于兼容性原因,允许某些资源通过 - 如果事件/互斥锁属于此类,我不记得了。

    无论哪种方式,如当前编写的那样,您的代码可能是不正确的:部分问题是 OpenEvent 可能由于多种原因而失败:您的代码假定它失败是因为未创建事件,但它可能会失败,因为事件是已创建,但调用代码无权修改该对象。

    正如其他回复中提到的那样,如果您想在每个用户的基础上执行此操作(但仍在同一个会话中),您需要为您的活动提供每个用户的名称:将用户名添加到活动的基本名称,你应该完成了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 2011-12-23
      • 1970-01-01
      • 2012-10-12
      相关资源
      最近更新 更多