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 à distance des applications. Ces applications sont exécutées à l’aide de CreateProcess, et cela fonctionne pour moi car la plupart d’entre elles n’effectuent que le traitement backend. Récemment, j’ai besoin d’exécuter des applications qui présentent une interface graphique à l’utilisateur courant. Comment puis-je coder en C ++ pour permettre à mon service de localiser le bureau actuellement actif et d’exécuter l’interface graphique dessus?

La réponse de Roger Lipscombe, d’utiliser WTSEnumerateSessions pour trouver le bureau approprié , puis CreateProcessAsUser pour démarrer l’application sur ce bureau (vous lui transmettez le handle du bureau dans le cadre de la structure STARTUPINFO ) est correcte.

Cependant, je recommande fortement de ne pas le faire. Dans certains environnements, tels que les hôtes Terminal Server avec de nombreux utilisateurs actifs, il est difficile de déterminer quel poste de travail est actif, voire impossible.

Mais plus important encore, si une application apparaît soudainement sur le bureau d’un utilisateur, cela peut très bien se produire au mauvais moment (soit parce que l’utilisateur ne s’y attend pas ou parce que vous essayez de lancer l’application lorsque la session est terminée). pas tout à fait initialisé, en cours de fermeture, ou autre).

Une approche plus conventionnelle consisterait à mettre un raccourci vers une petite application client pour votre service dans le groupe de démarrage global. Cette application sera ensuite lancée avec chaque session utilisateur et peut être utilisée pour démarrer d’autres applications (si vous le souhaitez) sans jongler avec les informations d’identification, les sessions et / ou les bureaux des utilisateurs.

De plus, ce raccourci peut être déplacé / désactivé par les administrateurs selon les besoins, ce qui facilitera le déploiement de votre application, car elle ne s’écarte pas des normes utilisées par d’autres applications Windows …

La réponse courte est “vous ne faites pas”, car l’ouverture d’un programme graphique s’exécutant dans un autre contexte utilisateur est une vulnérabilité de sécurité communément appelée attaque Shatter .

Consultez cet article MSDN: Interactive Services . Il offre certaines options pour un service d’interagir avec un utilisateur.

En bref, vous avez ces options:

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

  • Créez une application graphique distincte masquée et utilisez la fonction CreateProcessAsUser pour exécuter l’application dans le contexte de l’utilisateur interactif. Concevez l’application graphique pour communiquer avec le service via une méthode de communication interprocessus (IPC), par exemple des canaux nommés. Le service communique avec l’application GUI pour lui indiquer quand afficher l’interface graphique. L’application communique les résultats de l’interaction de l’utilisateur au service afin que le service puisse prendre les mesures appropriées. Notez que IPC peut exposer vos interfaces de service sur le réseau, sauf si vous utilisez une liste de contrôle d’access appropriée.

    Si ce service s’exécute sur un système multi-utilisateur, ajoutez l’application à la clé suivante afin qu’elle soit exécutée dans chaque session: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run. Si l’application utilise des canaux nommés pour IPC, le serveur peut distinguer plusieurs processus utilisateur en atsortingbuant à chaque canal un nom unique basé sur l’ID de session.

WTSEnumerateSessions et CreateProcessAsUser.

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 vouliez cibler qu’un seul utilisateur connecté.

Bien sûr, plusieurs personnes ont raison de suggérer CreateProcessAsUser. Si vous appelez plain old 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.

Que les problèmes de session 0, services interactifs, service Windows autorisent le service à interagir avec le bureau sur Windows 7 ou Windows Vista

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

J’ai essayé expliqué ici, cela fonctionne sur Windows 7

Sous Win2K, XP et Win2K3, l’utilisateur de la console est connecté à la session 0, la même session que les services. Si un service est configuré comme interactif, il pourra afficher l’interface utilisateur sur le bureau de l’utilisateur.

Toutefois, sous Vista, aucun utilisateur ne peut être connecté à la session 0. L’affichage de l’interface utilisateur à partir d’un service est un peu plus compliqué. Vous devez énumérer les sessions actives à l’aide de l’API WTSEnumerateSessions , rechercher la session de console et créer le processus en tant qu’utilisateur. Bien sûr, vous avez également besoin d’un jeton ou des informations d’identification de l’utilisateur pour pouvoir le faire. Vous pouvez lire plus de détails sur ce processus ici .

Je pense que tant que vous n’avez qu’un seul utilisateur connecté, il s’affichera automatiquement sur le bureau de cet utilisateur.

Quoi qu’il en soit, soyez très prudent quand un service lance un exe.

Si l’access en écriture au dossier avec l’exe n’est pas restreint, tout utilisateur peut remplacer cet exe par tout autre programme, qui sera alors exécuté avec les droits de système. Prenez par exemple cmd.exe (disponible sur tous les systèmes Windows). La prochaine fois que le service essaie de démarrer votre exe, vous obtenez un shell de commande avec les droits système …

Si vous lancez une interface graphique depuis votre service, elle apparaîtra sur le bureau actuellement actif.

Mais uniquement si vous avez ajusté les permissions de service: vous devez lui permettre d’ interagir avec le bureau .

Important Les services ne peuvent pas interagir directement avec un utilisateur à partir de Windows Vista. Par conséquent, les techniques mentionnées dans la section intitulée Utilisation d’un service interactif ne doivent pas être utilisées dans un nouveau code.

Ceci est tiré de: http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx