Почему при выполнении mstsc.exe (удаленный рабочий стол) из c # процесс HasExited = true и не имеет MainWindowHandle - PullRequest
1 голос
/ 30 октября 2019

Моя главная цель - открыть удаленный рабочий стол и освободить его после завершения удаленного сеанса. Я пытаюсь разместить Mstsc.exe в приложении winform, поэтому я управляю закрытием процесса и отправляю команду release на удаленный ПК. это можно сделать с помощью командного файла:

for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do (  %windir%\System32\tscon.exe %%s /dest:console)

Код c #:

[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

Добавить учетную запись удаленного ПК

        Process p = Process.Start(Environment.ExpandEnvironmentVariables(@"C:\Windows\system32\cmdkey.exe "), string.Format(" /generic:TERMSRV/{0} /user:{1} /pass:{2}", host, userName, password));

Открыть удаленный рабочий стол:

        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 всегда равен нулю. Если я обновляю процесс, я получаю исключения. mainP.HasExited - это правда, хотя mstsc открыта. Как я могу получить MainWindowHandle MSTSC.exe?

Спасибо

1 Ответ

2 голосов
/ 30 октября 2019

Клиент удаленного рабочего стола, похоже, реализован таким образом, что при запуске с использованием аргументов командной строки он обрабатывает аргументы, запускает отдельный процесс (если аргументы верны) и затем завершает исходный процесс.

Это означает, что вам потребуется экземпляр Process, представляющий новый процесс, чтобы получить дескриптор его главного окна.

Добавление к исходному коду:

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

Мне удалось успешно получить дескриптор при использовании приведенного выше кода, однако он не учитывает несколько экземпляров mstsc.exe - если вам нужно различать их, вам нужно будет изучить процессы более внимательно (возможно, посмотритена MainWindowTitle?).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...