My main goal is to open remote desktop and release it back when the remote session is ended. I am tryng to host Mstsc.exe in winform application , so I will manage the closing of the process and send release command to the remote PC. this can be done by batch file:
for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do ( %windir%\System32\tscon.exe %%s /dest:console)
The c# code:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
Add the cratential of the remote PC
Process p = Process.Start(Environment.ExpandEnvironmentVariables(@"C:\Windows\system32\cmdkey.exe "), string.Format(" /generic:TERMSRV/{0} /user:{1} /pass:{2}", host, userName, password));
Open remote desktop:
Process mainP = Process.Start(@"C:\Windows\system32\mstsc.exe ", (" /v " + host));
mainP.Exited += P_Exited;
while (mainP.MainWindowHandle ==null || mainP.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep(20);
//mainP.Refresh();
}
Console.WriteLine(mainP.MainWindowHandle);
SetParent(mainP.MainWindowHandle, panel1.Handle);
MainWindowHandle is always zero , If I refresh the process I get exceptions. mainP.HasExited is true altought mstsc is open. How can I get MainWindowHandle of MSTSC.exe ?
Thanks
The Remote Desktop client seems to be implemented in such a way that, when launched using command-line arguments, it will process the arguments, start a separate process (if the arguments are valid) and then terminate the original process.
This means that you will need a Process
instance that represents the new process in order to get the handle to its main window.
Adding to your original code:
Process mainP = Process.Start(@"C:\Windows\system32\mstsc.exe ", (" /v " + "CLSERVER"));
mainP.WaitForExit();
mainP.Dispose();
Process otherP;
while ((otherP = Process.GetProcessesByName("mstsc").FirstOrDefault()) == null) {
Thread.Sleep(20);
}
otherP.Exited += P_Exited;
while (otherP.MainWindowHandle == IntPtr.Zero) {
Thread.Sleep(20);
}
Console.WriteLine(otherP.MainWindowHandle);
SetParent(otherP.MainWindowHandle, panel1.Handle);
I was able to successfully get the handle when using the above code, however it does not account for multiple instances of mstsc.exe - if you need to distinguish between them, you will need to examine the processes more closely (maybe look at MainWindowTitle
?).