48 votes

Comment un service Windows peut-il exécuter une application graphique?

J'ai écrit un service Windows qui me permet d'exécuter et d'arrêter des applications à distance. Ces applications sont exécutées à l'aide de CreateProcess, et cela fonctionne pour moi car la plupart d'entre elles effectuent uniquement un traitement back-end. Récemment, je dois exécuter des applications présentant une interface utilisateur graphique pour l'utilisateur actuellement connecté au journal. Comment coder en C ++ pour permettre à mon service de localiser le bureau actuellement actif et d'exécuter l'interface graphique sur celui-ci?

54voto

mdb Points 20629

Roger Lipscombe, en réponse, à utiliser WTSEnumerateSessions de trouver le bon bureau, puis CreateProcessAsUser pour démarrer l'application sur l'ordinateur (vous passer la poignée de l'ordinateur de bureau dans le cadre de la STARTUPINFO structure) est correct.

Cependant, je tiens à vivement recommander contre cela. Dans certains environnements, tels que Terminal Server hôtes avec beaucoup d'utilisateurs actifs, la détermination de bureau est le "actif" n'est pas facile, et peut-être même pas possible.

Mais le plus important, si une application tout à coup apparaissent sur le bureau d'un utilisateur, cela peut très bien se produire à un mauvais moment (soit parce que l'utilisateur n'est tout simplement pas attendre, ou parce que vous essayez de lancer l'application au démarrage de la session n'est pas initialisé et pourtant, dans le processus d'arrêt, ou quoi que ce soit).

Une approche plus conventionnelle serait de mettre un raccourci vers une petite application client à votre service dans le global groupe de démarrage. Cette application va lancer ensuite le long de chaque session de l'utilisateur, et peut être utilisé démarrer d'autres applications (si désiré), sans jongler d'identification de l'utilisateur, des séances et/ou des postes de travail.

Aussi, ce raccourci peut être déplacé/désactivées par les administrateurs comme souhaité, ce qui fera de déploiement de votre application beaucoup plus facile, car il ne pas s'écarter de la norme utilisée par d'autres applications Windows...

17voto

mlarsen Points 2339

La réponse courte est "Vous n'avez pas", comme l'ouverture d'un programme graphique en cours sous un autre contexte de l'utilisateur est une faille de sécurité communément connu comme un Eclat d'Attaque.

Jetez un oeil à cet article MSDN: les Services Interactifs. Il donne quelques options pour un service à interagir avec un utilisateur.

En bref, vous avez les options suivantes:

  • Afficher une boîte de dialogue dans la session de l'utilisateur à l'aide de la WTSSendMessage fonction.

  • Créer un caché interface graphique de l'application et de l'utilisation de la CreateProcessAsUser fonction pour exécuter l'application dans le contexte de l'utilisateur interactif. La conception de l'interface graphique de l'application pour communiquer avec le service à travers des méthodes de communication interprocessus (IPC), par exemple, des canaux nommés. Le service communique avec l'interface graphique de l'application pour le dire lors de l'affichage de l'interface graphique. L'application communique les résultats de l'interaction de l'utilisateur vers le service ainsi que le service peut prendre les mesures appropriées. Notez que l'IPC peuvent les exposer à des interfaces de service sur le réseau, sauf si vous utiliser une liste de contrôle d'accès (ACL).

    Si ce service s'exécute sur un système multi-utilisateur, ajouter l'application à la clé suivante de sorte qu'il est exécuté à chaque séance: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. Si l'application utilise des canaux nommés pour l'IPC, le serveur peut faire la distinction entre plusieurs processus utilisateur, en donnant à chaque pipe un nom unique basé sur l'ID de session.

6voto

Roger Lipscombe Points 34344

WTSEnumerateSessions et CreateProcessAsUser.

6voto

Windows programmer Points 5365

Plusieurs personnes ont suggéré WTSEnumerateSessions et CreateProcessAsUser. Je me demande pourquoi personne n'a suggéré WTSGetActiveConsoleSessionId, puisque vous avez dit que vous ne souhaitez cibler qu'un seul utilisateur connecté.

Plusieurs personnes ont cependant raison de suggérer CreateProcessAsUser. Si vous appelez tout simplement l'ancien CreateProcess comme vous l'avez dit, l'interface graphique de l'application s'exécutera avec les privilèges de votre service au lieu des privilèges de l'utilisateur.

2voto

Mehmet Taskopru Points 111

La session 0, Services interactifs, Service Windows permet au service d'interagir avec le bureau sous Windows 7 ou Windows Vista

Vous pouvez lire cet article http://www.codeproject.com/KB/vista-security/SubvertingVistaUAC.aspx

J'essaie d'expliquer ici que cela fonctionne sur Windows 7

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