为什么打开的DLL句柄不能保护文件不被移动?

Com*_*sMS 5 windows dll winapi filehandle

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

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

Ser*_*bry 6

这不是一个bug.LoadLibrary使用文件映射来访问文件.虽然您有一个映射到文件的部分,但它无法删除(或移动到另一个磁盘).它似乎LoadLibrary关闭了一个文件句柄(它不需要)并且只使用映射部分的句柄,因此您可以自由地重命名该文件但不能删除它.

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

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