Windows服务的互斥对象名称与Windows 7中的exe名称相同
Same mutex name for a Windows service and exe in Windows 7
我想使用CreateMutex函数通过Windows服务和同名的exe创建互斥。如果一个互斥对象是由Windows服务创建的,并且当exe尝试创建另一个同名互斥对象时,它成功了,没有出现任何错误,如error_ALREADY_EXIST。
这种情况仅在Windows7中发生。但对于Windows XP,显示ERROR_ALREADY_EXIST。我不知道操作系统出现这种差异的原因以及如何纠正这个问题。
样本代码
对于服务代码
#include<iostream>
#include<windows.h>
#include<winbase.h>
using namespace std;
#define SLEEP_TIME 50000
typedef void* handle;
typedef WINADVAPI BOOL (WINAPI *PInitializeSecurityDescriptor)(PSECURITY_DESCRIPTOR, DWORD);
typedef WINADVAPI BOOL (WINAPI *PSetSecurityDescriptorDacl)(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL);
#define LOGFILE "D:\result.txt"
handle temp=NULL;
static int a=65;
char muname[]={"NewMutex2"};
int errNm;
char *str;
FILE* log;
SECURITY_ATTRIBUTES *g_pSaCms;
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();
bool Win32Mutex(char muname[8])
{
HINSTANCE hAdvApi = LoadLibrary("Advapi32.DLL");
PInitializeSecurityDescriptor pInitializeSecurityDescriptor = 0;
PSetSecurityDescriptorDacl pSetSecurityDescriptorDacl = 0;
PSECURITY_DESCRIPTOR pSD = 0;
g_pSaCms = new SECURITY_ATTRIBUTES;
if (g_pSaCms == 0)
{
prinerr();
return 1;
}
memset(g_pSaCms,0X0, sizeof(*g_pSaCms));
g_pSaCms->nLength = sizeof(*g_pSaCms);
g_pSaCms->bInheritHandle = 1;
pSD = new SECURITY_DESCRIPTOR;
if (pSD == 0)
{
printerr();
goto LABEL_CSA_ERROR;
}
pInitializeSecurityDescriptor = (PInitializeSecurityDescriptor)GetProcAddress(hAdvApi,"InitializeSecurityDescriptor");
if (pInitializeSecurityDescriptor == 0)
{
printerr();
goto LABEL_CSA_ERROR;
}
pSetSecurityDescriptorDacl = (PSetSecurityDescriptorDacl)GetProcAddress(hAdvApi, "SetSecurityDescriptorDacl");
if (pSetSecurityDescriptorDacl == 0)
{
goto LABEL_CSA_ERROR;
}
if (!(*pInitializeSecurityDescriptor)(pSD, SECURITY_DESCRIPTOR_REVISION)
|| (!(*pSetSecurityDescriptorDacl)(pSD, TRUE, (PACL)0, FALSE)))
{
goto LABEL_CSA_ERROR;
}
(void)FreeLibrary(hAdvApi);
g_pSaCms->lpSecurityDescriptor=pSD;
goto LABEL_CSA_PASS;
LABEL_CSA_ERROR:
(void)FreeLibrary(hAdvApi);
if (pSD != 0)
{
delete pSD;
pSD = 0;
}
if (g_pSaCms != 0)
{
delete g_pSaCms;
g_pSaCms = 0;
}
LABEL_CSA_PASS:
temp=::CreateMutex(g_pSaCms,0,muname); //for icdcomm
errNm=GetLastError();
if (!temp)
{
print_err();
}
else
{
print_err();
}
if ((!temp) || errNm == ERROR_ALREADY_EXISTS)
{
if(temp)
{
(void)CloseHandle(temp);
a++;
muname[8]=a;
Win32Mutex(muname);
}
else
{
printInf()
}
return 0;
}
return 1;
}
int main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "MemoryStatus";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
void ServiceMain(int argc, char** argv)
{
int error;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(
"MemoryStatus",
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
// Initialize Service
error = InitService();
if (error)
{
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// My service
muname[8]=a;
Win32Mutex(muname);
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);
// The worker loop of a service
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
Sleep(SLEEP_TIME);
}
return;
}
// Control handler function
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus (hStatus, &ServiceStatus);
return;
}
对于可执行代码(代码保持不变,buc仅更改主要功能)
int main()
{
muname[8]=a;
Win32Mutex(muname);
Sleep(SLEEP_TIME);
return 0;
}
在XP:上
在会话0中运行的服务创建互斥对象。该应用程序也在会话0中运行,它成功地打开了现有互斥对象的句柄,最后一个错误设置为error_ALREADY_EXISTS,让您知道发生了什么。
在Windows 7上:
在会话0中运行的服务创建互斥对象。可能在会话一中运行的应用程序创建了一个新的互斥对象,该互斥对象恰好具有相同的名称。这两个互斥对象是独立的。这是可能的,因为互斥对象名称的作用域是当前会话。
如果您想要共享互斥,您需要在全局名称空间中创建它们,方法是在名称前面加上"Global\"前缀,即:
char muname[]={"Global\NewMutex2"};
您可以在此处找到有关会话零隔离的更多详细信息。
相关文章:
- 分段 Linux Ubuntu 中的 g++ 错误,但在 Windows 中的 g++/MingW 中,在 C++ 中打
- 绕过 Windows 中的 __declspec(dllimport) 到 Linux 项目的转换
- 以原子方式将彩色文本写入 Windows 中的控制台
- 使用 pipe() 和 fdopen() 将数据从 Python 脚本传递到 Windows 中的C++应用程序
- 无法在windows中的virtualenv中安装psycopg2
- 从 Windows 中的其他应用程序 GUI 中提取数据
- 为什么我不能在 Windows 中的 rabbitmq 中创建队列?
- 跨平台 c++ 与 Linux 和 Windows 中的 c# 集成
- 我们如何劫持DLL以锁定Windows中的所有目录以进行验证
- QT库链接Windows中的错误
- Windows中的主音量控制,在启动时运行
- 尽管它在Linux中起作用,但无法从Windows中的Pclvisualizer中删除点云
- Windows中的CodeBlock中的设置OpenFramework
- 代码:: blocks printf double windows中的固定精度
- 在C 中将多个客户端连接到Windows中的单个服务器中的多线程
- 如何从Windows中的可执行文件中推断出文件/目录路径
- 如何将共享库 *DLL与Windows中的cmake链接
- 可以在不在Windows中的ROS的情况下安装KDL_PARSER
- 程序在Windows中的DLL边界上使用嵌入式Python/C 代码崩溃
- 如何从Windows中的进程中读取Unicode字符串