【发布时间】:2019-06-05 12:31:39
【问题描述】:
当我想在服务器上放置一个新版本的 exe 时(通过 .Net 程序),当某些用户在离开办公室时没有关闭 exe(所有用户在服务器上使用这个 exe)时,我遇到了这个烦人的问题)。
简单的重现方法:
- 将 exe 放在共享网络驱动器上 (Windows Server)
- 打开 de exe op pc1 (WIN7)
在 pc2 (WIN7) 上删除这个 exe =>文件没有被删除,但exe文件不再有所有者,甚至没有管理员;并且没有办法恢复文件的所有者,因为没有人有权这样做(甚至没有管理员)。
退出 de exe op pc1 =>exe在打开的文件中不可见,无法删除文件(资源管理器或提升的命令提示符)
我已经尝试了几个“解锁”工具,但没有一个可以解锁文件,因为他们没有看到文件被锁定。但我认为该文件被Windows系统锁定,直到隔夜在de exe中的用户退出exe;然后 Windows 会进行真正的删除。
问题是“要删除”的 exe 在某种程度上是“损坏的”,所以你不能再打开这个 exe。
有没有办法(.Net 代码)强制将此文件归还所有者(例如管理员),以便该所有者可以永久删除该文件?
备注:因为很多用户都使用这个exe,所以如果用户还在程序中或者在每台电脑上运行ProcessExplorer,就不可能在每台电脑上查看。
提前致谢。
【问题讨论】:
-
Windows 中的常规删除是一个两步过程。底层文件系统文件控制块 (FCB) 或链接控制块 (LCB) 首先被标记为“已删除”。这会使文件处于防止再次打开它的状态。不管调用者是谁,所有打开文件的请求都被拒绝。这不是所有权问题。只有现有句柄可用于访问“已删除”文件。具有删除访问权限的句柄可以“取消删除”它以恢复访问权限。如果不是,当最后一个句柄关闭时,文件会从父目录中取消链接,如果链接计数现在为 0,它会被真正删除。
-
阻止已删除的 exe 被取消链接的真正文件句柄当然是在服务器上。你可以在那里强制关闭,可以远程执行。
-
你可以做的是有一个小程序来启动你的程序的最新版本。仍在使用旧版本的用户不会回到崩溃的程序。
-
当然如果你有删除权限,你也可以重命名文件。为了尽量减少问题,我会在删除之前用数字后缀重命名它。然后新的 exe 就可以取而代之了。
-
..这是另一个疯狂的解决方案。在“共享”的某处有一个名为“should_I_quit.txt”的文件,并让计时器每隔几分钟检查一次它的内容(非锁定读取!),如果文件包含“请立即死去”,则程序退出。