在我的C ++ / winapi程序中,我使用一个事件对象来检测我的应用程序的实例是否已在运行,以便不让第二个实例启动。
但同时我想允许程序的多个实例在使用其他用户帐户启动时运行。例如。使用“runas”命令。 (即:对于每个用户帐户,只有1个实例可以同时运行)
我使用的代码如下:
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中使用不同的用户帐户运行多个实例? 或许我的方法完全错了,那么一个是正确的吗?
谢谢
答案 0 :(得分:1)
您所要做的就是以某种方式在事件名称中包含用户名。坦率地说,你的场景在XP中有效,我有点惊讶。
答案 1 :(得分:1)
我认为你在这里遇到了安全问题。一般来说,一个应用程序无法修改由作为另一个用户运行的另一个应用程序创建的对象,因此如果一个应用程序创建事件对象,则作为另一个用户运行的应用程序应该无法打开它 - 即使它已经退出。
Vista上有一些微妙的变化;运行“升高”的概念会带来额外的皱纹;它与另一个用户一样运行,但不完全相同。由于compat原因允许使用某些资源 - 如果事件/互斥体属于此类别,我无法记得。
无论哪种方式,正如当前所写,您的代码可能是不正确的:部分问题是OpenEvent可能由于多种原因而失败:您的代码假定它失败,因为事件未创建,但它可能失败,因为事件是已创建但调用代码无权修改对象。
正如其他一个回复中所述,如果您希望基于每个用户(但仍在同一会话中)执行此操作,则需要为每个用户的名称提供事件:将用户名添加到事件的基本名称,你应该完成。