Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Windows服务和Windows 7中的exe具有相同的互斥体名称_C++_Windows_Mutex - Fatal编程技术网

C++ Windows服务和Windows 7中的exe具有相同的互斥体名称

C++ Windows服务和Windows 7中的exe具有相同的互斥体名称,c++,windows,mutex,C++,Windows,Mutex,我想使用CreateMutex函数通过Windows服务和同名的exe创建互斥。如果一个互斥体是由Windows服务创建的,并且当exe尝试创建另一个具有相同名称的互斥体时,它会成功,而不会出现任何错误,如error_ready_ 这种情况只在Windows7中发生。但对于Windows XP,显示已存在的错误。 我无法找出操作系统中出现这种差异的原因以及如何纠正此问题 示例代码 服务代码 #include<iostream> #include<windows.h> #i

我想使用CreateMutex函数通过Windows服务和同名的exe创建互斥。如果一个互斥体是由Windows服务创建的,并且当exe尝试创建另一个具有相同名称的互斥体时,它会成功,而不会出现任何错误,如error_ready_

这种情况只在Windows7中发生。但对于Windows XP,显示已存在的错误。 我无法找出操作系统中出现这种差异的原因以及如何纠正此问题

示例代码

服务代码

#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; 
} 
在XP上:

在会话0中运行的服务创建互斥锁。同样在会话0中运行的应用程序成功地打开了现有互斥锁的句柄,最后一个错误被设置为error_ready_EXISTS,以让您知道发生了什么

在Windows 7上:

在会话0中运行的服务创建互斥锁。该应用程序可能正在会话1中运行,它创建了一个新的互斥锁,该互斥锁恰好具有相同的名称。这两个互斥体是独立的。这是可能的,因为互斥体名称的作用域是当前会话

如果希望共享互斥体,则需要在名称前加上“Global\”前缀,在全局命名空间中创建互斥体,即:

char muname[]={"Global\\NewMutex2"};

您可以在这里找到更多详细信息。

您的意思是什么?您说过,
ERROR\u已经存在
在这两种情况下都会出现(在两个版本的Windows上)。进程可以共享(命名)互斥。一个会创建它(在您的情况下是服务,因为它在您的独立应用程序之前运行),另一个(您的应用程序)只会打开它(使用
CreateMutex
,它将返回
ERROR\u ready\u EXIST
)。@Bojan:不,他说代码在Win7上运行时没有
ERROR\u ready\u EXIST
。我的错误是,打开的窗口太多了,我们在做多重任务时忽略了这个词:)谢谢你的回答。接下来的问题是,我们如何制作一段既适用于pre-Vista又适用于pos-Vista的代码。我们可以在WIN操作系统中使用GLOBAL\吗?或者我们需要使用头保护来保护不同类型的互斥。您的建议是什么?这篇文章暗示从Windows 2000开始就支持“GLOBAL”:我也遇到了同样的问题,浪费了数小时来回答各种随机答案(包括microsoft官方网站)这建议更改互斥体权限。这么简单。
char muname[]={"Global\\NewMutex2"};