Lancer une application .Net winforms de manière interactive à partir d’un service

Environnement – VS2008, Vista SP1.

J’ai écrit un service de gestion de processus permettant de lancer des applications dans la session 0 ou sur la console interactive (généralement 1). S’il vous plaît noter que ce n’est pas le mode de fonctionnement normal, c’est à des fins de débogage interne uniquement. Sur le terrain, ces processus seront cachés en toute sécurité lors de la session 0. Les problèmes de sécurité ne s’appliquent pas.

Clairement, les gens ne lisent pas ceci: les problèmes de sécurité ne s’appliquent pas. Nous avons des dizaines d’applications serveur existantes (PAS des services) écrites comme ceci. Nous ne sums pas sur le sharepoint réorganiser complètement ces applications, nous devons simplement pouvoir accéder à leurs boîtes de dialog de débogage intégrées lors de l’exécution interne des versions. Je sais déjà tout sur la solution canonique, les tuyaux, etc. S’il était acceptable d’append des interfaces distantes à toutes ces applications, c’est ce que nous ferions.

J’utilise le code suivant pour faire ceci:

ZeroMemory (&sui, sizeof(STARTUPINFO)); sui.cb = sizeof (STARTUPINFO); sui.wShowWindow = pTask->GetWinStartState() ; sui.dwFlags = STARTF_USESHOWWINDOW ; ZeroMemory (&pi,sizeof(pi)); if (bInteractive) { HANDLE hToken = NULL; DWORD dwSessionId = WTSGetActiveConsoleSessionId(); WTSQueryUserToken (dwSessionId, &hToken); sui.lpDesktop = TEXT("winsta0\\default"); LPVOID pEnv = NULL; DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; HMODULE hModu = LoadLibrary(TEXT("Userenv.dll")); if (hModu ) { if (CreateEnvironmentBlock (&pEnv, hToken, FALSE)) dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT; else pEnv = NULL; } bCreatedOk = CreateProcessAsUser (hToken, NULL, (LPTSTR)(pTask->GetExeName()), NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &sui, &pi); } else { bCreatedOk = CreateProcess (NULL, ... blah...); } 

Tout cela fonctionne bien et je peux exécuter et surveiller des processus natifs à la fois dans la session de service Vista et sur la console. Génial. Des gâteaux et de la bière pour tous.

Alors voici le problème. Si j’essaie d’exécuter une application winforms (C #) de manière interactive comme celle-ci, elle semble fonctionner. S’affiche dans Process Explorer comme étant en cours d’exécution dans la session 1, mais sur le bureau … nada. Aucune fenêtre n’apparaît du tout. Le processus s’exécute et s’arrête bien, mais aucune fenêtre n’apparaît. Le même WinEx exe exécuté à partir de l’explorateur apparaît également dans la session 1, mais cette fois-ci apparaît parfaitement sur le bureau.

Des idées ?

En dépit de l’hystérie évidente, le lancement d’une application depuis un service dans une session interactive n’a rien d’anormal, à condition que cela soit effectué avec les mêmes privilèges que l’utilisateur interactif ou une version inférieure . Étant donné que vous lancez en tant qu’utilisateur interactif, il ne peut y avoir aucune élévation de privilèges.

Ce que vous faites fonctionne. Je soupçonne que le problème a quelque chose à voir avec votre structure STARTUPINFO. Vous semblez créer votre sui sur la stack, mais vous ne montrez pas ce que vous en faites. Est-ce que vous l’initialisez à tous les 0, sinon vous obtenez peut-être des déchets de la stack qui empêchent la fenêtre de s’afficher ou de montrer des coordonnées à l’extérieur de l’écran.

On dirait que vous essayez de casser l’isolation de session. Comme dit Mystere Man, je ne pense pas que ce soit la bonne chose à faire.

http://support.microsoft.com/?scid=kb%3Ben-us%3B165194&x=5&y=3 pourrait être utile si vous voulez vraiment le faire. Dans l’exemple de code là-bas, ils semblent initialiser plus de choses que vous.


EDIT Si c’est à des fins de débogage, c’est-à-dire VS-2008 pas à pas, ajoutez simplement une boucle d’attente au début et lancez VS avec les droits d’administrateur. Vous pouvez vous connecter à votre processus de service sans rencontrer d’isolation du système.

En un mot, “ne pas”.

Les services s’exécutent généralement avec des privilèges réduits et NON en tant qu’utilisateur actuel. En tant que tels, ils ne sont pas autorisés dans Vista + à interagir avec le bureau des utilisateurs. En plus de tout cela, les services obtiennent une station de fenêtre nulle.

Vous aviez l’habitude de cocher une case qui disait “Permettre d’interagir avec le bureau” mais plus maintenant. C’est une mauvaise pratique.

Votre meilleur choix est de créer une application d’assistance qui s’exécute dans le contexte de l’utilisateur et communique avec le service via un canal nommé, un LRPC ou un socket, puis de laisser votre application d’assistance lancer le programme pour l’utilisateur. C’est ainsi que fonctionnent la plupart des anti-virus.

Lisez également ce livre blanc de Microsoft sur le sujet. Les services ne peuvent être exécutés que dans la session 0.

REMARQUE: une petite recherche semble indiquer que vous devez dupliquer le jeton en utilisant quelque chose comme ceci:

 DuplicateTokenEx(hTokenNew,MAXIMUM_ALLOWED,NULL, SecurityIdentification,TokenPrimary,&hTokenDup);