| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2232 人关注过本帖
标题:两次调用CreateMutex没有产生互斥
只看楼主 加入收藏
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
结帖率:91.43%
收藏
已结贴  问题点数:40 回复次数:10 
两次调用CreateMutex没有产生互斥
这样是可以用的,第二次运行能弹出对话框
程序代码:
int main()
{
    HANDLE hMutex=CreateMutex(0,true,"four_glass");
    if(GetLastError()==ERROR_ALREADY_EXISTS)
    {
        MessageBox(NULL, "已有该实例", "注意:", MB_OK);

    }
    while(1);
    return 0;
}


但是这样就弹不出对话框了。
第一次成功启动以后可以在服务里看到,抓包可以看到服务开启的ping线程一直在工作。
但是第二次运行该程序,CreateMutex还是返回了一个句柄,并没有返回ERROR_ALREADY_EXISTS。
程序代码:
int main(int argc,char *argv[])
{
    Register();
    SERVICE_TABLE_ENTRY   DispatchTable[] = 
    { 
        { "Temp_For_Test", (LPSERVICE_MAIN_FUNCTION) ServiceMain }, 
        { NULL, NULL } 
    }; 
    if (!StartServiceCtrlDispatcher( DispatchTable)) 
    { 
        printf("error :%d\n",GetLastError());
    } 
    while(1);
    system("pause");
    return 0;

void Register()
{
    HANDLE hMutex=CreateMutex(0,true,"four_glass");
    if(GetLastError()==ERROR_ALREADY_EXISTS)
    {
        if(Debug_)
            Printf_Debug('b', 1, "already running");
        exit(0);
    }
    InstallService();//功能是创建服务,创建完成后启动服务然后用exit退出。  里面还有不明白的地方待指教
}

void InstallService(void)
{
    const char ServiceName[]="Temp_For_Test";
    char FilePathName[MAX_PATH];
    SERVICE_STATUS_PROCESS s_Status; 
    SC_HANDLE h_SCManager;
    SC_HANDLE h_Service;
    DWORD dwBytesNeeded;
    DWORD dwOldCheckPoint; 
    DWORD dwStartTickCount;
    DWORD dwWaitTime;

    GetModuleFileName(NULL, FilePathName, MAX_PATH);                        //获得自身路径

    h_SCManager=OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);            //打开SCM
    if (NULL == h_SCManager) 
    {
        printf("OpenSCManager failed (%d)\n", GetLastError());
        exit(0);
    }
    else
        printf("OpenSCManager succeeded\n");

    //query if the service exist.
    h_Service = OpenService(h_SCManager, ServiceName, SC_MANAGER_ALL_ACCESS);
    if (h_Service != NULL)
    { 
        printf("OpenService succeeded\n");

        if (!QueryServiceStatusEx(h_Service, SC_STATUS_PROCESS_INFO, (LPBYTE)&s_Status, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) )            
                             // handle to service // info level  // address of structure // size of structure  // if buffer too small
        {
            printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
            exit(0); 
        }

        CloseServiceHandle(h_Service);
        CloseServiceHandle(h_SCManager);
        return ;
    }
    else
    {
        printf("OpenService failed:%d\n",GetLastError());
    }
    

    h_Service=CreateService(                                                //创建服务
        h_SCManager,                // SCM 句柄
        ServiceName,                // 服务名
        ServiceName,                // 显示的服务名
        SERVICE_ALL_ACCESS,            // 存取权限
        SERVICE_WIN32_OWN_PROCESS,    // 服务类别
        SERVICE_AUTO_START,            // 启动类别
        SERVICE_ERROR_NORMAL,        // 错误控制类别
        FilePathName,                // 服务的可执行文件路径
        NULL,                        // no load ordering group 
        NULL,                        // no tag identifier 
        NULL,                        // no dependencies 
        NULL,                        // LocalSystem account 
        NULL);                        // no password 
    if (NULL == h_Service) 
    {
        printf("CreateService failed (%d)\n", GetLastError());
        exit(0);
    }
    else
        printf("CreateService succeeded\n"); 

    if(!StartService(h_Service, 0, NULL))                                    //启动服务
    {
        printf("StartService failed (%d)\n", GetLastError());
        exit(0);
    }

                                                                            //查询状态
    if (!QueryServiceStatusEx(h_Service, SC_STATUS_PROCESS_INFO, (LPBYTE)&s_Status, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) )            
                         // handle to service // info level  // address of structure // size of structure  // if buffer too small
    {
        printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
        exit(0); 
    }


    //这段代码没看懂,功能不知道?????????????????????????????????????
    dwStartTickCount = GetTickCount();
    dwOldCheckPoint = s_Status.dwCheckPoint;
    // 查询状态,确定 PENDING 状态结束
    while (s_Status.dwCurrentState == SERVICE_START_PENDING) 
    { 
        // 等待一段时间
        dwWaitTime = s_Status.dwWaitHint / 10;
        if( dwWaitTime < 1000 )
            dwWaitTime = 1000;
        else if ( dwWaitTime > 10000 )
            dwWaitTime = 10000;
        Sleep( dwWaitTime );
        // 再次查询
        if (!QueryServiceStatusEx( 
            h_Service,             // handle to service 
            SC_STATUS_PROCESS_INFO, // info level
            (LPBYTE)&s_Status,              // address of structure
            sizeof(SERVICE_STATUS_PROCESS), // size of structure
            &dwBytesNeeded ) )              // if buffer too small
            break; 
        if ( s_Status.dwCheckPoint > dwOldCheckPoint )
        {
            // 进程创建中
            dwStartTickCount = GetTickCount();
            dwOldCheckPoint = s_Status.dwCheckPoint;
        }
        else
        {
            if(GetTickCount()-dwStartTickCount > s_Status.dwWaitHint)
            {
                // WaitHint 时间到
                break;
            }
        }
    } 

    if (s_Status.dwCurrentState == SERVICE_RUNNING) 
        printf("StartService SUCCESS.\n");
    else 
    { 
        printf("\nService not started. \n");
        printf("  Current State: %d\n", s_Status.dwCurrentState); 
        printf("  Exit Code: %d\n", s_Status.dwWin32ExitCode); 
        printf("  Service Specific Exit Code: %d\n", 
            s_Status.dwServiceSpecificExitCode); 
        printf("  Check Point: %d\n", s_Status.dwCheckPoint); 
        printf("  Wait Hint: %d\n", s_Status.dwWaitHint); 
        printf("error : %d\n",GetLastError());
    }
    CloseServiceHandle(h_Service);
    CloseServiceHandle(h_SCManager);
    exit(0);
}
}
搜索更多相关主题的帖子: 对话框 color 
2016-12-20 18:30
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:28 
试试这样:
#include <windows.h>

HANDLE hMutex = NULL;

int _Register()
{
    hMutex = CreateMutex(NULL, 1, "four_glass");
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        //if(Debug_)
        //    Printf_Debug('b', 1, "already running");
        MessageBox(0, "already running", "", 0);
        return 0;
    }
    return 1;
}

main()
{
    if (!_Register())
    {
        exit(0);
    }
    InstallService();//功能是创建服务,创建完成后启动服务然后用exit退出。  里面还有不明白的地方待指教
    //..........
    while (1);
}
2016-12-20 19:53
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 2楼 吹水佬
还是不行。
第二次CreateMutex返回还是一个句柄,没有出错,跳不到输出那个括号里面去。
2016-12-20 20:44
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
回复 3楼 lyl930130

就这几行代码应该可以的,是否其他模块有异常?

图片附件: 游客没有浏览图片的权限,请 登录注册


#include <windows.h>

HANDLE hMutex = NULL;

int _Register()
{
    hMutex = CreateMutex(NULL, 1, "four_glass");
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        //if(Debug_)
        //    Printf_Debug('b', 1, "already running");
        MessageBox(0, "already running", "", 0);
        return 0;
    }
    return 1;
}

void InstallService()
{
    NULL;
}

main()
{
    if (!_Register())
    {
        exit(0);
    }
    InstallService();//功能是创建服务,创建完成后启动服务然后用exit退出。  里面还有不明白的地方待指教
    //..........
    while (1);
}
2016-12-20 21:10
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 4楼 吹水佬
这里你有没有创建服务,还是只是分别运行两个exe?

如果只是两个main函数的exe,应该和我1楼说的第一种情况一样,可以识别互斥的。

现在我是第一次运行,他会自己在服务注册,然后从服务启动。
然后再第二次运行,还是能运行,中间结果告诉我服务已经注册了,但是没有提示互斥。



2016-12-20 22:50
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
回复 5楼 lyl930130
由系统服务启动与通常启动进程不同吧?

2016-12-21 11:00
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 6楼 吹水佬
这个我也不清楚,因为也是才开始学习这一点东西。

我单独创建一个线程调用试试。
2016-12-21 12:20
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 6楼 吹水佬
谢谢版主,的确是服务启动的程序和正常的不一样。
服务启动的在servicemain之前都会过一遍,但是好像都没有运行(奇怪的是用Messagebox会卡主,因为没有交互点确认)。
2016-12-27 21:12
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
回复 8楼 lyl930130
服务没有UI,也就不会出现程序窗口或对话框。
2016-12-27 21:59
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 9楼 吹水佬
我在Messagebox调用前创建了一个线程用来发ping包(都在调用ServiceMain前),从服务启动的时候抓包没有看到,也就是说ping包线程没有启动,那Messagebox应该也不会启动啊?
这点非常不理解
2016-12-29 16:50
快速回复:两次调用CreateMutex没有产生互斥
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.076961 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved