4

我创建了一个管理应用程序,它还允许快速访问远程计算机的远程桌面会话。我需要等到进程结束,才能关闭与远程服务器的 VPN 连接。一切正常,除了等待过程结束。

以下代码用于启动 MSTSC 进程并等待它结束:

var process = new Process
{
  StartInfo = new ProcessStartInfo("mstsc.exe"),
  EnableRaisingEvents = true
};
process.Exited += (o, e) => Console.WriteLine("Process stopped.");
process.Start();
Console.ReadLine();

Exited事件几乎在程序启动后立即引发。当我替换mstsc.exe一切notepad.exe按预期工作时。我认为 MSTSC 可能会自行分叉并中止初始过程。

但是可以使用以下命令(从命令行)等待 MSTSC 结束:

start /wait mstsc.exe

在我退出远程桌面会话之前,此命令不会返回。鉴于这些信息,我用以下代码替换了我的代码:

var process = new Process
{
  StartInfo = new ProcessStartInfo("cmd.exe"),
  Arguments = "/c start /wait mstsc.exe",
  EnableRaisingEvents = true
};
process.Exited += (o, e) => Console.WriteLine("Process stopped.");
process.Start();
Console.ReadLine();

这将运行 CMD.exe 并发出start /wait mstsc.exe命令。如果这结束了,CMD 过程也结束了,我很好(有一个讨厌的解决方法,但没关系)。不幸的是,这不会发生。CMD 进程立即终止。有人知道我做错了什么吗?

4

6 回答 6

5
process.WaitForExit();

不起作用,因为启动时的 mstsc 会打开自身的新副本并关闭原始副本。

process.WaitForExit();    
process = Process.GetProcessesByName(process.ProcessName).First();
process.WaitForExit();

会工作,但这是一个糟糕的解决方法。

更新1:

似乎 mstsc 关闭了原始进程,但不是输出流!所以你可以等待进程 StandardOutput 关闭。

var process = new Process
{
    StartInfo = new ProcessStartInfo("mstsc.exe") { UseShellExecute = false, RedirectStandardOutput = true }
};
process.Start();
process.StandardOutput.ReadToEnd(); //This will wait for stream to close.

或者,如果您不想阻止当前线程:

var process = new Process
{
    StartInfo = new ProcessStartInfo("mstsc.exe") { UseShellExecute = false, RedirectStandardOutput = true }
};

process.Start();

var outputResultPromise = process.StandardOutput.ReadToEndAsync();
outputResultPromise.ContinueWith(o=> Console.WriteLine("Stream closed"));

Console.ReadLine();
于 2013-08-23T15:21:01.923 回答
1

这是MSDN 关于启动 mstsc的链接,

这可能是您在运行(引发Exited事件)后立即关闭 mstsc 的问题的答案。尝试将 Visual Studio目标平台更改为AnyCPU

假设您的机器是 64 位 Windows,您的应用程序是 32 位。该应用程序运行 32 位 mstsc。32 位 mstsc 检测到 Windows 是 64 位,尝试关闭自身并运行 64 位 mstsc(Exited即使 mstsc 启动 GUI 窗口,此时也会引发事件)。 更改目标平台解决了我的问题

于 2014-06-01T09:41:41.450 回答
0

有多个 MSTSC 进程正在运行,因此很难等待一个。我不明白的是,当我使用start /wait命令时,CMD.EXE 可以做到这一点。

于 2013-08-23T22:08:27.013 回答
0

这对我有用:

process.Start();
Thread.Sleep(2000);
while(getNumProcesses() > 0)
   process.WaitForExit();


private static int getNumProcesses()
{
    Process[] myProcesses = Process.GetProcessesByName("mstsc");
    return myProcesses.Length;
}
于 2014-11-18T14:54:58.180 回答
0

您不能等待 mstsc.exe 进程。确切地说,您不能简单地等待远程桌面结束。当我通过 Process Monitor 观察 mstsc.exe 进程时,mstsc 将他的工作传递给 svchost,mstsc.exe 结束,但远程桌面仍在运行。

但是我为远程应用程序编写了脚本。脚本remoteCmd.cmd 启动remoteApplication,远程机器创建一个临时文件(\\tsclient\c..\temp\xxx)并且remoteCmd.cmd 等待直到临时文件存在。请参阅 https://github.com/turzik/WindowsScripts/tree/master/remoteApp

于 2020-04-20T12:17:35.517 回答
-1

调用 Start() 后需要调用 WaitForExit():

process.Start();
process.WaitForExit();

这种重载会导致当前线程无限期地等待,直到进程退出。还有一个重载允许您指定要等待的毫秒数。

于 2013-08-23T14:53:25.097 回答