在父进程退出后保持子进程活动

4
我正在为Windows服务编写自动更新程序。这是我希望它能够实现的功能(如果有更好的解决方案,请告诉我):
1) The service launches a child Process (the updater).
2) The child stops the parent service (I'm using sc.exe).
3) The child applies the updated .exe and .dll files for the parent.
4) The child starts the parent service.

我在第二步遇到困难,因为当我停止父进程服务时,子进程也被终止了。我该如何在C#中启动一个不是子进程的新进程,它独立存在?
2个回答

8
您可以使用 Process.Start 来启动一个独立的进程:
例如:
System.Diagnostics.Process.Start(@"C:\windows\system32\notepad.exe");

这和运行以下代码不同吗:Process p = new Process(); p.start();?据我理解,这种方式会创建一个子进程。 - Matthew
我不确定那会在服务被停止后工作。 - csharptest.net
是的,它们是不同的。以这种方式启动它类似于从“运行”对话框中启动某些内容。它与其父级没有关联。如果您前往 MSDN,他们会详细解释重载之间的差异。 - Mrchief
1
如果服务以这种方式启动子进程,则当服务停止时,子进程将不会被杀死。以这种方式启动时,两者之间没有关联。 - Mrchief
@Mrchief:它们并不不同,但它不会创建一个子进程。 - SLaks
@Slaks:我所说的“子进程”是指由服务启动的进程(并不是说被_启动_的进程是子进程)。我知道这听起来很混乱,也许我应该把它们称为进程A、B等。 - Mrchief

0

您可以使用调度程序服务。虽然其他人建议可以直接完成此操作。

  1. 确保“计划任务”服务正在运行。
  2. 运行AT.EXESCHTASKS.EXE命令行实用程序,以安排执行子进程的时间。
  3. 等待停止事件到达服务,如果在超时期限内未收到,则存在问题;)根据其如何被安排,您可以尝试再次运行它。

我更喜欢schtasks命令,类似于以下内容:

C:\> schtasks.exe /create /tn "My Updater" /sc once /ru System /sd 01/01/1999 /st 00:00 /tr "C:\Windows\System32\cmd.exe /c dir c: > c:\temp\ran.txt"

这应该会产生以下输出:

警告:任务可能无法运行,因为/ST早于当前时间。 已成功创建计划任务“My Updater”。
注意,如果该名称的任务已经存在,将会产生覆盖提示。任务创建后,您可以随时运行它:
C:\> schtasks.exe /run /tn "My Updater" 尝试运行计划任务“My Updater”成功。
最后,您可以删除任务,但需要确认:
C:\> schtasks.exe /delete /tn "My Updater" 是否确定要删除任务"My Updater"(Y/N)?y 已成功删除计划任务“My Updater”。
因此,要使用这些命令,您只需要生成所选调度程序即可。当然,这也可以通过编程完成;不过我从来没有想明白如何做到;)
由于同时使用了 std::out/err 和 std::in,请务必阅读一下这篇关于如何正确使用 System.Diagnostics.Process 的文章。此外,我建议您使用一个良好的 Process.Start 包装器 API,比如我的 ProcessRunner 类,这样您就不会在等待进程退出时出现死锁情况。

感谢您的帮助。我不喜欢这个想法,因为使用任务计划程序时,在服务正在处理某些重要内容时可能会被终止。 - Matthew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接