5 votes

Comment attendre que MSTSC.exe se ferme

J'ai créé une application de gestion qui permet également un accès rapide à une session de bureau à distance sur des machines distantes. J'ai besoin d'attendre que le processus se termine, pour pouvoir fermer la connexion VPN au serveur distant. Tout fonctionne correctement, sauf l'attente de la fin du processus.

Le code suivant est utilisé pour démarrer le processus MSTSC et attendre qu'il se termine:

var process = new Process
{
  StartInfo = new ProcessStartInfo("mstsc.exe"),
  EnableRaisingEvents = true
};
process.Exited += (o, e) => Console.WriteLine("Process stopped.");
process.Start();
Console.ReadLine();

L'événement Exited est déclenché presque immédiatement après le démarrage du programme. Lorsque je remplace mstsc.exe par notepad.exe, tout fonctionne comme prévu. Je pensais que MSTSC pouvait se dupliquer et interrompre le processus initial.

Il est pourtant possible d'attendre la fin de MSTSC en utilisant la commande suivante (de l'invite de commandes):

start /wait mstsc.exe

Cette commande ne retourne pas tant que je ne quitte pas la session de bureau à distance. Étant donné cette information, j'ai remplacé mon code par ceci:

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

Cela exécutera CMD.exe et il exécutera la commande start /wait mstsc.exe. Si cela se termine, le processus CMD se termine également et tout va bien (avec un contournement désagréable, mais d'accord). Malheureusement, cela ne se produit pas. Le processus CMD se termine immédiatement. Quelqu'un sait ce que je fais de mal?

5voto

mswietlicki Points 1383
process.WaitForExit();

Ne fonctionnera pas avant Windows 11 car mstsc, au démarrage, ouvre une nouvelle copie de lui-même et ferme l'original.

process.WaitForExit();    
process = Process.GetProcessesByName(process.ProcessName).First();
process.WaitForExit();

Fonctionnera mais c'est une solution de contournement horrible.

Mise à jour 1:

Il semble que mstsc ferme le processus d'origine mais PAS son flux de sortie! Vous pouvez donc attendre que le flux de sortie du processus se ferme.

var process = new Process
{
    StartInfo = new ProcessStartInfo("mstsc.exe") { UseShellExecute = false, RedirectStandardOutput = true }
};
process.Start();
process.StandardOutput.ReadToEnd(); //Cela va attendre que le flux se ferme.

Ou si vous ne voulez pas bloquer le thread actuel:

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("Le flux s'est fermé"));

Console.ReadLine();

2voto

user277768 Points 11

Voici le lien sur MSDN à propos du démarrage de mstsc.

Cela pourrait être la réponse à votre problème avec mstsc se fermant immédiatement après son exécution (déclenchant l'événement Exited). Essayez de changer dans Visual Studio la plateforme cible en AnyCPU.

Disons que votre machine est sous Windows 64 bits, votre application est en 32 bits. L'application lance mstsc en 32 bits. Mstsc en 32 bits détecte que Windows est en 64 bits, tente de se fermer et de lancer mstsc en 64 bits (l'événement Exited est déclenché à ce moment-là même si mstsc affiche sa fenêtre GUI). Changer la plateforme cible a résolu mon problème.

0voto

Il y a plusieurs processus MSTSC en cours d'exécution, donc il est difficile d'attendre un. Ce que je ne comprends pas, c'est que CMD.EXE peut le faire lorsque j'utilise la commande start /wait.

0voto

Cela a fonctionné pour moi :

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

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

0voto

lison Points 11

Vous ne pouvez pas attendre le processus mstsc.exe. Dites exactement, vous ne pouvez pas simplement attendre la fin du bureau à distance. Lorsque j'ai observé le processus mstsc.exe avec Process Monitor, mstsc a passé son travail à svchost, mstsc.exe s'est terminé, mais le bureau à distance était toujours en cours.

Mais j'ai écrit un script pour l'application de bureau à distance. Le script remoteCmd.cmd lance l'application distante, la machine distante crée un fichier temporaire (\\tsclient\c..\temp\xxx) et remoteCmd.cmd attend que le fichier temporaire existe. Voir https://github.com/turzik/WindowsScripts/tree/master/remoteApp

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X