c++ - 关闭 LoadLibrary 打开的 DLL 文件句柄

标签 c++ windows winapi dll

如何关闭由 LoadLibrary 对 .dll 调用打开的文件句柄,同时保持库已加载?例如,FreeLibrary 将不起作用。

在我的例子中,有一个程序我想保持打开状态,它打开了 DLL,但我不想在每次重新编译和替换 DLL 时都关闭该程序。我不在乎程序是否在内存中有旧版本的库。 DLL 也被另一个程序使用,这就是我希望能够替换它的原因。

最佳答案

这是不可能的,因为“加载”的 DLL 是内存映射文件。这意味着“关闭句柄”会将其从内存中删除,因为它没有复制到内存,只是映射

这就是为什么只要所有程序都使用完全相同的文件,DLL 就具有如此高的内存效率 - 它(几乎)不会花费任何额外的内存来加载它数百次! (如果您想知道:它被映射为写时复制,因此在内存中修改它不会修改磁盘上的文件,而是将受影响的 4k 页复制到实际内存并在那里修改。)

但是,您可以在文件仍在使用时重命名文件(或移动它,只要它位于同一卷上,这在技术上也是重命名操作)。然后您可以使用原始名称创建一个新文件,然后在将旧文件卸载到各处后将其删除。

您也可以使用 MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT) 将旧文件标记为在下次重新启动时自动删除,但这需要提升权限。非升级更新程序/卸载程序避免这种情况的一个流行选择是在本地 appdata 文件夹中删除批处理或 vbs 文件,该文件夹删除文件,然后删除自身(这确实工作,因为脚本 复制到内存中)并将其注册到每个用户的 RunOnce 注册表项中。

(请注意,使用 FILE_FLAG_DELETE_ON_CLOSE 打开文件将不起作用。)

关于c++ - 关闭 LoadLibrary 打开的 DLL 文件句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63678681/

相关文章:

c++值和变量之间的不同打印行为

c++ - C++ 中最快的数组初始化

c++ - 在程序中获取调试断言错误

windows - 为什么没有 ReadDirectoryChangesA?

c - 使用 OpenSCManager 加载非运行 Windows 安装的服务数据库

c# - 使用win api模拟鼠标点击魔兽争霸3按钮

c++ - Xcode 应用程序不再从应用程序存储的文件夹中读取输入

c++ - 给定文件系统路径名,如何检索对应的 ABSOLUTE ITEMIDLIST?

windows - 如何使用forfiles删除不带扩展名的文件

windows - 如何为通过 CreateWindow 创建的窗口指定字体?