【发布时间】:2011-11-22 06:09:36
【问题描述】:
我在任务栏上创建了一个桌带。当我想更新桌带的DLL时,我隐藏它,取消注册它,但不幸的是资源管理器仍然保留这个DLL在内存中。
如何在不重新启动资源管理器进程的情况下更新 dll?这种情况有什么Windows api吗?
【问题讨论】:
我在任务栏上创建了一个桌带。当我想更新桌带的DLL时,我隐藏它,取消注册它,但不幸的是资源管理器仍然保留这个DLL在内存中。
如何在不重新启动资源管理器进程的情况下更新 dll?这种情况有什么Windows api吗?
【问题讨论】:
“不支持”(又名 hack)解决方案(C/C++):
HWND hWnd = FindWindowW(L"Shell_TrayWnd", NULL);
if (hWnd != NULL)
PostMessageW(hWnd, WM_TIMER, 0x18, 0);
这将强制在资源管理器进程中调用 CoFreeUnusedLibraries 函数。
在 Windows 7 Ultimate SP1 64 位和 Windows XP Professional SP3 32 位上测试。
顺便说一句,您可以按 Windows+D(最小化所有窗口)并等待 3 分钟。程序化破解就是基于这种行为。它只是在资源管理器进程中调用计时器处理程序。处理程序代码(C/C++)是:
KillTimer(hWnd, 0x18);
CoFreeUnusedLibraries();
不存在的定时器调用KillTimer函数并没有什么坏处。
【讨论】:
不,没有支持的方式来执行此操作。 DLL 可能卸载的最早可能是它从 DllCanUnloadNow 返回 true 几次,中间有延迟——例如由必须来自资源管理器进程中的 CoFreeUnusedLibraries 触发。注销它不会有任何影响。
如果您正在开发这种 DLL,您需要熟悉重启资源管理器。
马丁
【讨论】:
正如 Martyn 所说,没有受支持的方法可以完全按照您的要求进行操作。
但您仍然可以减少更新过程的干扰。只需让您的插件 DLL 仅用作资源管理器的准系统接口,并将其他所有内容卸载到单独的 DLL 中,您可以从进程中显式加载和卸载。然后,您只需要在界面必须更改某些内容时重新加载资源管理器。如果操作正确,您应该很少需要更新插件 DLL。
【讨论】: