得到占用指定dll的进程

本文介绍如何在Windows系统中查找占用特定dll的进程,通过遍历进程快照和模块快照,实现动态库占用进程的检测。文章提供了一个C语言实现的函数示例,该函数遍历所有进程及其模块,找到指定dll并返回相关信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接之前的一篇文章http://blog.youkuaiyun.com/bloonfield/article/details/6780918

在制作软件的安装卸载时,有时一些动态库被某些进程占用,不可以直接删除,需要先将占用这个动态库的进程结束。怎么才能知道动态库被哪个进程占用呢?

开始的思路是这样的,在DOS里面有这样一个命令“tasklist /m XXX.dll”这个命令会列出所有占用了XXX.dll的进程。OK,原理简单。只要能得到DOS命令的返回结果就OK了。

。。。

这种方法确实可以在XP中实现,可是在win2K的系统上就不行了,因为“taskllist”这个命令是在XP及其之后的系统上才加上的。而且如果程序本身是32位的,在64位的机器上也是不行的,需要重新编译一个64位的程序。不然用“tasklist”得到的结果是不完整的。只能说,这种方法弱爆了。

所以,最后用了另一种方法,通过进程快照。

先要遍历所有的进程,然后对每个进程遍历其占用的模块,从中查找指定的dll。OK,废话不多说,代码如下:


//结构体,用来存放进程的相关信息
typedef struct sPROCESSINFO 
{
    char    caExeName[100];         //进程名
    char    caWindowName[MAX_PATH]; //对应的窗体名称
    DWORD   dwProcessId;            //进程ID
    HWND    hProWinHandle;           //窗体句柄
}PROCESSINFO, *LPPROCESSINFO;

void GetDllAttach(IN  char * pcDllName, //指定的dll名称
                  OUT sPROCESSINFO * psExeInfo,//返回的进程
                  OUT int * piExeNum) //进程个数
{
    BOOL bModule = FALSE;
    BOOL bProcess = FALSE;
    HANDLE hSnapPro;
    PROCESSENTRY32 sPro;
    MODULEENTRY32 sModule;
    int iNum = 0;
    WCHAR wcaDllName[0x100] = {0};


    memset(&sPro, 0, sizeof(sPro));
    memset(&sModule, 0, sizeof(sModule));


    MultiByteToWideChar(CP_ACP, 0, pcDllName, -1, wcaDllName, sizeof(wcaDllName));  //转换到Unicode编码




    //得到进程快照
    hSnapPro = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    sPro.dwSize = sizeof(sPro);
    sModule.dwSize = sizeof(sModule);


    //得到第一个进程信息,之后遍历所有进程
    bProcess = Process32First(hSnapPro, &sPro);
    while (bProcess)
    {   //得到当前进程的模块快照
        HANDLE hSnapModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, sPro.th32ProcessID);
        //遍历所有模块,看是否有指定名称的DLL
        bModule = Module32First(hSnapModule, &sModule);
        while (bModule)
        {
            if (memicmp((char*)sModule.szModule, (char*)wcaDllName, sizeof(wcaDllName)) == 0)
            {
                WideCharToMultiByte(CP_ACP, 0, sPro.szExeFile, -1, psExeInfo[iNum].caExeName, sizeof(psExeInfo[iNum].caExeName), NULL, NULL);
                psExeInfo[iNum++].dwProcessId = sPro.th32ProcessID;
                break;
            }
            bModule = Module32Next(hSnapModule, &sModule);
        }
        bProcess = Process32Next(hSnapPro, &sPro);
        CloseHandle(hSnapModule);
    }
    CloseHandle(hSnapPro);
    *piExeNum = iNum;
}


另外,多说一句,上面这个函数因为放在了一个定义了UNICODE的库里,所以中间有宽字符的转换,如果不用支持宽字符,可将其去掉。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值