Starting Remote Desktop Client. No Control Over PID Kill. PID Changes After Start...WTF?
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开发者_JAVA百科 monitor or kill a specific instance of the Remote Desktop Client?
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 to c:\windows\syswow64
.
There are two solutions:
- Recompile your application to 64-bit. Then your application will also use the 64-bit mstsc.
- Disable file system redirection (see http://blog.tonycamilli.com/2005/07/disabling-wow64-file-system.html) and access the 64-bit mstsc from your 32-bit application.
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
, do Process.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:
var timeout = AppSettings.GetIntValue(
Constants.SettingsKeyProcessFinderTimeout, Constants.ProcessFinderTimeoutDefault);
int elapsedTime = 0;
Process process = null;
while (elapsedTime <= timeout)
{
process =
Process.GetProcessesByName("mstsc").FirstOrDefault(p => p.StartInfo.Arguments.Contains(guid));
Logger.TraceVerbose(
string.Format(
"Elapsed time: {0}; Found process with PID {1}", elapsedTime, process == null ? -1 : process.Id));
if (process != null)
{
break;
}
Thread.Sleep(SleepInterval);
elapsedTime += SleepInterval;
}
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.
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.
精彩评论