dllmain设置锁之后,其他程序使用dll时总是报自己设置的程序正在运行的提示

下面是我编写DLL时dllmain中的代码。


#include "stdafx.h"

HANDLE hMutex = NULL;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    {
        hMutex = CreateMutex(NULL, FALSE, _T("GLock"));
        if (!hMutex)
        {
            MessageBox(NULL, _T("Create mutex error!"), _T("Error"), MB_OK);
            return FALSE;
        }

        DWORD dwWait = WaitForSingleObject(hMutex, 0);
        switch (dwWait)
        {
        case WAIT_OBJECT_0:
            break;
        case WAIT_TIMEOUT:
        {
            MessageBox(NULL, _T("The program is running!"), _T("Warning"), MB_OK);
            return FALSE;
        }
        case WAIT_FAILED:
        {
            MessageBox(NULL, _T("Failed to get mutex!"), _T("Error"), MB_OK);
            return FALSE;
        }
        }

        /// 校验audit文件
        char tip[255] = { 0 };
        if (checkAuditFile(tip) == 0)
        {
            CString tipErr(tip);
            MessageBox(NULL, tipErr, _T("Error"), MB_OK);
            return FALSE;
        }

        break;
    }
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    {
        if (hMutex)
        {
            ReleaseSemaphore(hMutex, 1, NULL);
            CloseHandle(hMutex);
            hMutex = NULL;
        }

        break;
    }
    }
    return TRUE;
}

本意是,我写的dll不能被两个程序同时调用,也不能在一个程序中,同时使用dll的两个函数。

img

  1. 就是上面的加解密功能,点击加密按钮后,如果再点击解密按钮,dll提示程序正在运行,不能进行解密。同理,解密时也不能点击加密。

  2. 还有就是开两个上面的程序,一个点击加密后,另一个立即点击解密,这时dll要弹出提示程序正在运行。

不要说控制加密按钮点击后设置界面不可用,因为这只是个测试程序,是我自己写的,别人调用我的dll程序我都不知道别人的程序啥样。

本来,我写的这个测试程序中,点击加密或解密,然后再Loadlibrary,再获取函数进行加解密,这样做没有啥异常,满足我的本意。但是我修改了测试程序,在构造函数中加载了dll,获取了函数句柄。然后运行点击打开文件按钮时就弹出了程序正在运行的提示:

img
而且关了之后又继续弹了13次,才出来文件对话框。

所以这是怎么回事呢?如果上面代码不对该怎么实现我的本意呢?

1.ReleaseSemaphore应该换成ReleaseMutex
2.你的mutex是在公共命名空间,也就是说会变成全局只能创建一个,任何进程加载后实际上用的都是一个内核对象,实际上这个mutex处于allreadycreate,所以其他进程加载dll后属于openmutex,并且你释放代码写在了dll卸载后,所以只要有一个进程加载了dll,其他进程都无法获取到锁了,你的wait时间写的是等待0秒,所以其他进程都等于走进了超时逻辑

如果你想细分mutex可以参考我这个文章,https://blog.csdn.net/slslslyxz/article/details/112154474