如何得知DLL被哪些进程调用?

wsnet 2004-11-20 02:37:53
如果DLL被某些进程/线程调用,而未释放,则该DLL就不可能删掉(尤其用于某些卸载程序和DLL调试),因此如果知道哪些进程空间还有该DLL,就可以提示用户先去关闭那个进程。
高分征解!
...全文
160 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
oyljerry 2004-11-22
  • 打赏
  • 举报
回复
通过共享数据段记录
pepsi1980 2004-11-22
  • 打赏
  • 举报
回复
循环穷举进程模块名称
flyfancy 2004-11-22
  • 打赏
  • 举报
回复
在NT可以使用PSAPI.DLL的EnumProcesses、EnumProcessModules函数

如果要考虑兼容98等,只能用LoadLibrary和GetProcAddress获得函数
BOOL EnumProcesses(
DWORD* pProcessIds,
DWORD cb,
DWORD* pBytesReturned
);

BOOL EnumProcessModules(
HANDLE hProcess,
HMODULE* lphModule,
DWORD cb,
LPDWORD lpcbNeeded
);

大概步骤就是枚举进程,得到PID,然后OpenProcess得到句柄,然后枚举模块,确定是否终止进程,然后释放句柄。

现在手上没有MSDN,只在网上找了声明,这类程序写过很多,具体例子现在手上没有,楼主自己摸索。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/psapi_reference.asp

98下只有老实的用CreateToolhelp32Snapshot

楼主所说的重复数据,我想问题应该在代码上,楼主不妨将那段代码帖出来。
wsnet 2004-11-22
  • 打赏
  • 举报
回复
当然是CLose了的。这点常识还是有的。但关闭之后还是重复数据。大家可以试试。
danyueer 2004-11-22
  • 打赏
  • 举报
回复
CreateToolhelp32Snapshot,通过枚举来得到答案就是正解。
在进行再次枚举之前,记得用CloseHandle关闭先前的快照句柄,否则会得到重复数据。
wsnet 2004-11-22
  • 打赏
  • 举报
回复
通过枚举进程进行模块比较:CreateToolhelp32Snapshot
在第一次得出列表后,我试着关闭了其中的几个进程,但再次列表枚举,还是存在(难道第二次CreateToolhelp32Snapshot的调用是读取的缓存?),重新运行列表程序才刷新进程模块列表。
真是怪事!
MuseIn 2004-11-21
  • 打赏
  • 举报
回复
hehe.方法很多
wsnet 2004-11-21
  • 打赏
  • 举报
回复
不是强行关闭别的进程,而是提示那些现在还在调用abc.dll的进程列表,给用户自己决定是否关闭。
如果用没进枚举的方法, laiyiling(陌生人·100%·小象)提供的代码,可以做到。

不过我想到另外一个办法,不知是否可行:
假如abc.dll是我编程的话,我可以在进程调用dll的时候,将该进程加入该dll创建的一个共享内存区,而卸载的时候,就从共享区删除。这样我用另一个进程检查abc.dll的调用列表时,直接访问那个共享区就行了。(共享区可以保存进程模块名称、进程ID等)。当然dll要对共享区进行有效的管理。
sinall 2004-11-21
  • 打赏
  • 举报
回复
你可以看一下《windows核心编程》

肯定可以办到,大家看看《windows优化大师》的进程管理,它可以得到每个进程的dll列表。

我觉得
1、群举进程
2、群举每个进程的dll模块
3、比较(查找)和abc.dll路径相同的dll,记录下来。
chengjr 2004-11-21
  • 打赏
  • 举报
回复
在DLL之外就不好办了吧:(我也遇到过类似问题,自己写的DLL在卸载不掉的情况下想通过系统提供的工具来强行卸载,结果发现window只提供了查看所有模块的工具,而没有卸载它们的工具(想一想也是有道理的,要强行卸载DLL可能引起加载DLL的进程崩溃)。
下面方法不知道对你有没有用,试试吧
用CreateToolhelp32Snapshot得到进程快照,然后再调用Process32First和Process32Next轮寻每个进程,轮寻中再次调用CreateToolhelp32Snapshot得到此进程的模块列表,再调用Module32First和Module32Next查看是否是abc.dll,是的话给这个进程发送WM_QUIT消息使其推出即可。
wsnet 2004-11-20
  • 打赏
  • 举报
回复
对不住,大家都理解错了!
我的原意:比如我有一个abc.dll,被某些进程调用过后,现在如果要删除abc.dll,如何知道那些进程列表?
关键是我现在是在abc.dll之外。
绝缘 2004-11-20
  • 打赏
  • 举报
回复
呵呵,这个简单:
char buff[256];
HINSTANCE hInst=GetModuleHandle(0);
GetModuleFileName(hInst,buff,255);
MessageBox(0,buff,buff,0);
linxy2002 2004-11-20
  • 打赏
  • 举报
回复
楼上的方法应该可行,去试一下先
老夏Max 2004-11-20
  • 打赏
  • 举报
回复
//获取当前程序的完整路径,包括程序名
CString szPath;
GetModuleFileName(NULL,szPath.GetBuffer(MAX_PATH),MAX_PATH);
szPath.ReleaseBuffer();

使用上面的函数能否获得调用DLL的程序的路径呢?如果可以在DLL中调用这个函数将每个调用的Exe的路径保存下来。
Kudeet 2004-11-20
  • 打赏
  • 举报
回复
http://search.csdn.net/Expert/topic/53/53604.xml?temp=.7103235
老夏Max 2004-11-20
  • 打赏
  • 举报
回复
关注一下!

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧