5

我刚刚遇到了一个令人惊讶的错误,其中使用LoadLibraryAPI 调用加载的 DLL 文件在加载时被重命名。显然,在文件上打开 DLL 句柄并不能阻止该文件被重命名,甚至移动到不同的路径。但是,它受到保护,不会被删除并被移动到不同的磁盘。如果发生这种情况,使用 DLL 的程序将继续正常工作。ProcessExplorer 显示 DLL 句柄的路径会相应更新。

此行为不同于 Windows 中的普通文件句柄。例如,当保持std::ifstream对同一个 DLL 的打开时,操作系统不再允许重命名。我发现这种行为非常令人惊讶,并且想知道是否有人可以对此做出解释?特别是我会对允许这样做的理由感兴趣,因为我认为跟踪磁盘上的文件比仅仅锁定它更困难。所以操作系统可能必须积极支持这个功能,这意味着它必须有一个用例吗?

4

1 回答 1

6

这不是一个错误。LoadLibrary使用文件映射来访问文件。当您有一个映射到文件的部分时,它不能被删除(或移动到另一个磁盘)。似乎LoadLibrary关闭了文件句柄(不需要)并仅使用映射部分的句柄,因此您可以自由重命名文件但不能删除它。

另一方面,std::ifstream使用文件句柄来访问文件。并且它没有设置FILE_SHARE_DELETE重命名和删除操作所需的共享访问权限。

实际上没有对磁盘上的文件进行特殊跟踪。文件句柄指向文件,仅此而已。打开文件并获得其句柄后,可以重命名甚至删除文件,并且您仍然可以访问该文件(如果文件已被删除,则访问受限,但您可以取消删除文件并拥有完全访问权限) .

于 2013-07-22T15:39:03.647 回答