如何删除被C#中的另一个进程锁定的文件?

时间:2020-03-05 18:37:29  来源:igfitidea点击:

我正在寻找一种删除文件的方法,该文件被使用C#的另一个进程锁定。我怀疑该方法必须能够找到哪个进程正在锁定文件(也许通过跟踪句柄,尽管我不确定如何在C#中执行此操作),然后关闭该进程,然后才能使用File完成文件删除操作.Delete()

解决方案

回答

我们可以使用此程序Handle来查找哪个进程已锁定文件。这是一个命令行工具,所以我想我们会使用它的输出...我不确定要以编程方式找到它。

如果删除文件可以等待,可以在下次启动计算机时指定要删除的文件:

  • 启动REGEDT32(W2K)或者REGEDIT(WXP)并导航至:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager
  • WXP:编辑新的多字符串值enterPendingFileRenameOperations`
  • 在"数据"区域中,输入"" \ ?? " +文件名"以将其删除。可以输入LFN,而不必将其嵌入引号中。要删除" C:\ Long Directory Name \ Long File Name.exe",请输入以下数据:
\??\C:\Long Directory Name\Long File Name.exe

然后按确定

  • WXP:右键单击该值,选择"修改二进制数据",然后在十六进制字符串的末尾单击,输入0000(四个零)。
  • 关闭REGEDT32 / REGEDIT,然后重新启动以删除文件。

(为了后代,从一些随机的论坛上无耻地偷了它。)

回答

杀死其他进程不是健康的事情。如果方案涉及卸载,则可以使用MoveFileExAPI函数将文件标记为在下次重新启动时删除。

如果我们似乎确实需要删除另一个进程正在使用的文件,建议我们在考虑任何解决方案之前重新考虑实际问题。

回答

如果要以编程方式执行此操作。我不确定...,我真的建议我们反对它。
如果我们只是在自己的计算机上进行故障排除,SysInternals Process Explorer可以为我们提供帮助

运行它,使用"查找句柄"命令(我认为它在"查找"或者"处理"菜单中),然后搜索文件的名称。找到手柄后,即可强行关闭它们。

然后,我们可以删除文件,依此类推。

当心,这样做可能会导致拥有句柄的程序表现异常,因为我们刚刚从它下面拉出了众所周知的地毯,但是当我们调试自己的错误代码或者Visual Studio / Windows Explorer时,它会很好地工作被废话并且没有释放文件句柄,即使我们告诉他们很久以前就关闭文件了...叹气:-)

回答

噢,我几年前采用的一大技巧是Windows不允许我们删除文件,但可以删除文件。

伪代码排序:

mv %WINDIR%\System32\mfc42.dll %WINDIR\System32\mfc42.dll.old
Install new mfc42.dll
Tell user to save work and restart applications

当应用程序重新启动时(注意,我们不需要重新启动计算机),他们加载了新的mfc42.dll,一切都很好。这样,再加上" PendingFileOperations",在下次整个系统重新启动时删除旧的文件,效果很好。

回答

典型的方法如下。我们已经说过要在Cso中执行此操作...

  • 如果我们不知道哪个进程已锁定文件,则需要检查每个进程的句柄列表,并查询每个句柄以确定它是否标识了锁定的文件。在C#中执行此操作可能需要P / Invoke或者中介C ++ / CLI来调用所需的本机API。
  • 确定哪个进程已锁定文件后,我们需要安全地将一个小的本机DLL注入到该进程中(也可以注入托管DLL,但这比较麻烦,因为我们必须开始或者添加到.NET运行时)。
  • 然后,该Bootstrap DLL使用CloseHandle等关闭该句柄。

本质上:解锁"锁定"文件的方法是将DLL文件注入有问题的进程的地址空间,然后自行关闭它。我们可以使用本机或者托管代码来执行此操作。无论如何,我们将需要少量的本机代码,或者至少需要P / Invoke。

有用的网址:

  • 将代码注入另一个进程的三种方法
  • .NET代码注入

祝你好运!

回答

这看起来很有希望。一种杀死文件句柄的方法。

http://www.timstall.com/2009/02/killing-file-handles-but-not-process.html

回答

根据Orion Edwards的建议,我下载了Sysinternals ProcessExplorer,这反过来又使我发现我难以删除的文件实际上不是我想的Excel.Applications对象所保存的,而是我的Ccode发送邮件的事实代码创建了一个Attachment对象,该对象使该文件的句柄保持打开状态。

看到此内容后,我很简单地调用了Attachment对象的dispose方法,并释放了句柄。

Sysinternals资源管理器使我发现了与VisualStudio2005调试器结合使用的功能。

我强烈推荐这个工具!