如何等待MSTSC.exe退出

时间:2013-08-23 14:42:36

标签: c# .net mstsc

我创建了一个管理应用程序,它还允许快速访问远程桌面会话到远程计算机。我需要等到进程结束,这样我才能关闭到远程服务器的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流程立即终止。有人知道我做错了吗?

6 个答案:

答案 0 :(得分:3)

process.WaitForExit();

无法正常工作,因为mstsc on start会打开自身的新副本并关闭原始文件。

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();

答案 1 :(得分:1)

以下是MSDN about starting mstsc的链接,

mstsc在运行后立即关闭(提升Exited事件)可能会解决您的问题。尝试将Visual Studio 目标平台更改为 AnyCPU

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

这对我有用:

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


private static int getNumProcesses()
{
    Process[] myProcesses = Process.GetProcessesByName("mstsc");
    return myProcesses.Length;
}

答案 5 :(得分: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