启动远程桌面客户端。无法控制 PID Kill。启动后 PID 发生变化...WTF?
我正在编写一个程序(C# Windows 窗体中的 Visual Studio 2010),它跟踪远程桌面客户端的多个实例(mstsc.exe - 使用 Windows 7 版本进行测试)。我一直在尝试启动该程序并使用以下代码获取其 PID:
Process mstsc = Process.Start(mstscLocation, mstscConString);
int mstscProcessId = mstsc.Id;
DataRow row = openConn.NewRow();
row["RDP ID"] = mstscID;
openConn.Rows.Add(row);
这会启动客户端并返回一个 ID。问题是,如果我尝试使用以下代码终止 PID,则无法执行此操作:
int rdpID = Convert.ToInt32(dgvOpenConnections.Rows[selectedIndex].Cells["RDP ID"].Value.ToString());
try
{
// kill off mstsc
Process mstsc = Process.GetProcessById(rdpID);
mstsc.Kill();
}
我已验证从 Process.Start 记录的 PID 与从 DataGridView (dgvOpenConnections) 检索并放入 rpdID 中的 PID 相同(尝试失败并命中 catch,因为原始 PID 不再存在)。此外,在启动 MSTSC.EXE 的一个实例后,我在命令提示符下发出了一个“任务列表”,并且可以验证它是否更改了 PID(在此测试中,C# 记录了 4288,但任务列表显示它运行为 8172)。
我无法终止所有 MSTSC 进程,因为我试图控制多个进程。有没有办法追踪 MSTSC 似乎使用的第二个 PID?我的猜测是它要么启动第二个进程并摆脱第一个进程,要么这是一个子进程(尽管启动后返回的 PID 不再存在)。
在 C# 中,如何确保拥有正确的进程 ID 以便稍后监视或终止远程桌面客户端的特定实例?
I am writing a program (Visual Studio 2010 in C# Windows Forms) which keeps track of multiple instances of the Remote Desktop Client (mstsc.exe - tested with Windows 7 version). I have been attempting to launch this program and grab its PID with the following code:
Process mstsc = Process.Start(mstscLocation, mstscConString);
int mstscProcessId = mstsc.Id;
DataRow row = openConn.NewRow();
row["RDP ID"] = mstscID;
openConn.Rows.Add(row);
This starts the client and returns an ID as it should. Problem is, if I try to terminate the PID with the following code, it fails to do so:
int rdpID = Convert.ToInt32(dgvOpenConnections.Rows[selectedIndex].Cells["RDP ID"].Value.ToString());
try
{
// kill off mstsc
Process mstsc = Process.GetProcessById(rdpID);
mstsc.Kill();
}
I have verified that the PID that is recorded from Process.Start is the same as is retrieved from the DataGridView (dgvOpenConnections) and placed into rpdID (try fails and hits catch as the original PID no longer exists). Furthermore, I have issued a "tasklist" at a command prompt after starting one instance of MSTSC.EXE and can verify that it changes PIDs (in this test, C# recorded 4288 but tasklist shows it running as 8172).
I cannot kill all MSTSC processes as I am trying to control more than one. Is there a way to trace down the second PID MSTSC appears to use? My guess is it either starts a second process and gets rid of the first or maybe this is a child process (although the PID that is return no longer exists after start).
How in C# can I ensure I have the right process ID to later monitor or kill a specific instance of the Remote Desktop Client?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您尝试在 64 位 Windows 中从 32 位应用程序运行 mstsc,则会发生这种情况。
(来源:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/22c10140-a502- 4aa1-98d3-3607b8b573e8/)
在 64 位 Windows 上有 两个版本的 mstsc:
c:\windows\system32\mstsc.exe
是64位版本c:\windows\syswow64\mstsc.exe
或多或少是一个“重定向”,它将打开c:\windows\system32\mstsc .exe
来自与您的应用程序不同的进程。我也遇到过同样的问题。我的应用程序启动了 mstsc,该进程立即退出,并且 mstsc 重新出现,并具有不同的父进程和不同的 PID。
发生这种情况是因为 64 位 Windows 使用文件系统重定向将对 64 位
c:\windows\system32
可执行文件的调用重定向到c:\windows\syswow64
。有两种解决方案:
我只尝试过重新编译,并且成功了。 :-)
编辑:
如果您不希望用户使用正确的版本(我们使用的是 ClickOnce 部署,因此我们宁愿向每个人发送一个链接),这里有一个解决方法:
如果您使用的是mstsc 的 .RDP 文件,只需在文件名中添加唯一标记即可。 mstsc 将使用
mstsc host_user_token.rdp
等命令行启动。现在,在调用
Process.Start
后,执行Process.WaitForExit
并设置较短的超时(5 秒)。如果进程没有退出,则您拥有正确的对象。如果进程确实退出,请执行一个小的轮询循环(100毫秒间隔,5秒超时)来检查带有您的令牌的进程:
在该循环之后,如果您仍然有
process == null,出现一些错误(未找到进程或根本未执行进程)。如果您有进程参考,那就是“新”mstsc 进程。
This happens if you try to run mstsc from a 32-bit application in 64-bit Windows.
(Source: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/22c10140-a502-4aa1-98d3-3607b8b573e8/)
There are two versions of mstsc on a 64-bit Windows:
c:\windows\system32\mstsc.exe
is a 64-bit versionc:\windows\syswow64\mstsc.exe
is more or less a "redirect" that will openc:\windows\system32\mstsc.exe
from a different process than your application.I've had the same issue. My application started mstsc, the process immediately exited, and mstsc reappeared with a different parent process and different PID.
This happens because 64-bit Windows uses file system redirection to redirect calls to the 64-bit
c:\windows\system32
executables toc:\windows\syswow64
.There are two solutions:
I have only tried recompiling, and it worked. :-)
Edit:
If you don't want your users to use the right version (we're using ClickOnce deployment, so we'd rather send one link to everybody), here's a workaround:
If you're using an .RDP file for mstsc, just add a unique token to your file name. mstsc will be started with a command line like
mstsc host_user_token.rdp
.Now, after you called
Process.Start
, doProcess.WaitForExit
with a short timeout (5s). If the process did not exit, you have the right object.If the process did exit, do a little polling loop (100ms interval, 5s timeout) that checks for processes with your token:
After that loop, if you still have
process == null
, there was some error (process was not found or never executed at all). If you have a Process reference, that's the "new" mstsc process.我使用 Process Explorer 尝试了您的示例,但看不到正在创建的第二个或子进程。从开始到结束,远程桌面进程都是一样的,创建后我能够使用我一开始看到的相同 PID 来终止该进程。
I tried your example using Process Explorer, and I couldn't see a second or child process being created. From beginning to end the Remote Desktop Process was one and the same, and after being created I was able to kill the process using the same PID I saw in the beginning.