【问题标题】:How to close a file handle which came from a parent process C#如何关闭来自父进程C#的文件句柄
【发布时间】:2015-08-25 12:21:29
【问题描述】:

我目前正在创建应用程序更新程序模块,但遇到了打开文件句柄的问题。

更新程序模块是一个单独的程序,但在用户单击“升级”选项时通过 Process.Start() 更新的应用程序启动。更新程序要做的第一件事就是关闭正在更新的应用程序,以便可以重新安装它而不会出现任何文件访问问题等。

一切都很好,直到我尝试删除正在更新的应用程序的安装目录。我得到一个例外,上面写着:-

该进程无法访问该文件,因为它正被另一个进程使用。

我已经通过使用 SysInternals Process Explorer 实用程序来跟踪事情。更新程序最初是正在更新的应用程序的子进程,但是一旦要更新的应用程序被杀死,更新程序就是它自己的父进程。问题似乎是更新程序具有正在更新的应用程序的安装目录的打开文件句柄。

我可以通过在更新程序尝试删除安装文件夹之前关闭进程资源管理器中的文件句柄来手动解决问题,然后不会引发异常。但是我需要一些方法来在代码中关闭这个文件句柄,或者首先避免文件句柄被更新程序进程持有。

我尝试使用WIN32 CreateProcess 方法在不继承句柄的情况下创建进程,但安装文件夹的文件句柄仍由更新程序持有。

任何建议将不胜感激。

【问题讨论】:

  • 您退出启动升级过程的过程吗?典型场景应该是:1)创建临时文件夹并复制到那里升级过程exe 2)运行升级过程exe并退出3)升级过程exe运行(您可能想要提升它)4)升级过程运行升级版本并退出。跨度>
  • 那么当您调用 CreateProcess 时,您是否将 bInheritHandles 设置为 false?
  • 这是不可能的。您只能获得句柄的副本,关闭它只会倒计时底层操作系统对象的引用计数。当拥有进程仍然打开句柄时,它不会为零。它必须以这种方式工作,文件句柄永远不会随机消失。
  • @NathanCooper 是的,我将 bInheritHandles 设置为 false 并希望这能解决问题,但不幸的是没有。

标签: c# process handle


【解决方案1】:

这可能是进程的当前目录。如果您将安装目录作为当前目录启动记事本,则会出现相同的句柄。然后,当您使用记事本中的文件打开对话框导航到其他目录时,句柄就会消失。

使用Environment.CurrentDirectory 更改目录或创建具有更好当前目录的子目录。

【讨论】:

  • 感谢您的建议。我会试试这个并告诉你。
  • 谢谢@usr。原来就是这样!我只需要在创建处理时或在更新程序本身中设置当前目录。我还能够使用 .NET Process 类,而不必调用 CreateProcess。
  • 经过数小时的挫折,我找到了您的答案,谢谢。
猜你喜欢
  • 2014-01-18
  • 1970-01-01
  • 2015-02-16
  • 2011-12-30
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多