8
votes

Comment un service Windows peut-il commencer un processus lorsqu'un événement de minuterie est soulevé?

J'ai créé un service Windows avec la minuterie et dans l'événement de tir de Timer.ELAPSED CODE> Je crée un processus ( system.diagnostics.process.start (path EXE) code> ) à l'intervalle de 5 secondes. Mais ce processus ne se crée pas sur la cuisson d'un événement.

Y a-t-il une autre façon de le faire? P>

Merci d'avance. P>

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{       

    Process pr = new Process();
    pr.StartInfo.FileName = @"C:\Program Files\Messenger\msmsgs.exe";
    pr.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
    pr.StartInfo.CreateNoWindow = false;
    pr.Start();
}


8 commentaires

Ou il est créé puis sorti immédiatement? Si vous pouvez coller le code ici, ce serait utile


Les services Windows ne sont pas conçus pour exécuter des applications interactives. vous peut exécuter un processus, mais obtenir une nouvelle fenêtre à ouvrir est une proposition de dés. Sans parler de toutes les problèmes de sécurité que vous allez courir pour essayer de le faire. Les chances sont, vous devez repenser votre conception et utiliser quelque chose d'autre qu'un service Windows, surtout si vos utilisateurs cibles exécutent Windows Vista ou envisagent plus tard son modèle de sécurité resserré pour les services.


Aussi, voir la duplicate possible ici: Stackoverflow.com/questions/677874/... (discutez de la manière dont vous pouvez élever le service à exécuter avec différentes informations d'identification et / ou en mode interactif (Remarque: Ceci est Non pris en charge sous Vista ou ultérieur)).


merci Cody, pouvez-vous me dire quoi d'autre peut être fait pour exécuter un fichier .exe de l'événement de la minuterie ??


L'idée est que vous ne pouvez pas ... je ne sais pas ce qui n'était pas clair sur mon précédente explication.


Avez-vous essayé de faire le service interactif? Vérifiez également avec le responsable de la tâche si le processus est lancé mais non affiché. MSDN.MicRosoft.com /Library/default.asp?url=/library/en-us/...


Dans le gestionnaire de tâches, le processus est en cours d'exécution, mais cela ne s'ouvre pas.


Cela a fonctionné en juin 2019 dans Visual Studio avec une application .NET 4.7.2: code.msdn.microsoft.com/windowsapps/...


4 Réponses :


21
votes

Vous ajoutez des descriptions du problème dans les commentaires que vous allez avoir été utile de savoir au début. La raison que vous pouvez voir le processus a commencé mais aucune fenêtre n'est jamais ouverte est à cause des modifications de modèle de sécurité apportées aux services Windows sous Windows Vista et plus tard. Vous n'avez pas encore mentionné cela, mais j'ai une forte soupçon que vous essayez de courir cela sous l'un de ces systèmes d'exploitation. Le vrai problème ne commence pas un processus, il montre une UI.

Ce que vous essayez d'accomplir s'appelle un "Service interactif" , lequel est une qui est autorisée à interagir directement avec l'utilisateur et le bureau (c.-à-d. Montrer une fenêtre ou une boîte de dialogue).
Si vous utilisez Windows XP (et votre service ne sera que jamais doivent exécuter sous Windows XP), vous pouvez suivre les instructions de cet article pour permettre à votre service d'exécuter en mode interactif, ce qui vous permettra d'afficher la fenêtre d'application Adobe Acrobat à votre guise. Cependant, comme cette documentation indique également, cette fonctionnalité ne fonctionne pas sous Windows Vista et ultérieure:

Les services importants 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 doit pas être utilisé dans le nouveau code.

Plus spécifiquement, dans ces versions, des modifications ont été apportées à la manière dont les services et les applications sont exécutés. Les services sont maintenant isolés par le système dans la session 0, tandis que les applications sont exécutées dans d'autres sessions. Ceci est destiné à isoler les services d'attaques originaires du code d'application. Par conséquent, aucune interface utilisateur montrée par un service ne sera jamais visible pour un utilisateur sur le système, y compris une zone de message simple. Vous pouvez lire le livre blanc qui explique ces modifications plus détaillées ici . Si vous êtes une personne plus visuelle, reportez-vous au diagramme suivant illustrant le nouveau modèle en accordant une attention particulière aux lignes de division:

Modèle d'isolation de processus Windows sous Windows Vista / 7

Le résultat est que si vous ciblez ces versions ou si vous avez besoin de cibler ces versions, vous ne pouvez pas utiliser cette échappatoire. Je dis "échappatoire" parce que l'essentiel, comme je l'ai mentionné dans un commentaire, est que Windows Services ne sont pas destinés à être interactifs . Ce que vous essayez de faire ici fonctionne contrairement au but et à la conception d'un service. Ce n'était pas recommandé avant, et maintenant, il ne fonctionne pas du tout. Si vous avez besoin de cette fonctionnalité particulière, vous devez créer un type d'application différent. Les formulaires Windows et WPF sont destinés aux applications en mode utilisateur, et les deux peuvent démarrer des processus et ouvrir de nouvelles fenêtres si nécessaire. Je vous recommande vivement de convertir à ce style d'application à la place.


7 commentaires

S'il y a une méthode pour implémenter un crochet de clé global via le service Windows? Et aussi le service peut regarder les événements KeyPress SetwindowshookeX ?


@Jimmer No.a href="http://stackoverflow.com/q/5815424"> Crochet de clavier global du service Windows


Ok mais si j'entendais courir un exe quotidiennement? J'aurais créé un service de victoire qui la tirera tous les jours. Pour créer une autre application de bureau pour appeler EXE Daily Vainver dans le but de l'automatisation.


Les services Windows ne doivent pas exécuter des exécutables standard, @Ahsant. Créez une application standard qui exécute une minuterie et lance votre application de bureau. Pas besoin d'un service, et vous obtenez tous les mêmes avantages de l'automatisation.


Merci Cody pour revenir à cet ancien fil. Le problème avec l'application standard est le moment où je me déconnecte, ils mourront également. Est-ce que je manque quelque chose? Alors disons que je crée une application de console, il aura une minuterie et il faudra déclencher mon exe, mais cela fonctionnera-t-il toujours quand je suis déconnecté ??


@ahsant ah, vous voulez qu'il fonctionne quand il n'y a pas de compte connecté. D'accord, alors, quel contexte de compte devrait-il exécuter sous quand il n'y a pas d'utilisateur connecté? Oups, il n'y en a pas. Il n'y a pas non plus de bureau utilisateur sur lequel il peut afficher une interface utilisateur. C'est pourquoi vous ne devriez pas afficher l'application Desktop / UI à partir d'un service Windows. Pourquoi ne pouvez-vous pas prendre en compte les parties du code qui doivent courir en arrière-plan et les mettre au service? Laissez les pièces d'UI dans une application de bureau séparée pouvant afficher une interface utilisateur. Il n'a pas besoin de persister à travers les déconnages. Si nécessaire (par exemple, faire un moniteur), demandez-vous de communiquer avec le service.


@Cody, oui c'est le problème, je travaille avec cette application tierce. Je n'ai pas de code de celui-ci, je ne peux pas le refroidir. Il met à jour certains fichiers lorsque vous l'exécutez. J'espérais le rendre automatisé pour que je n'ai pas à me connecter au serveur quotidien et à le courir manuellement. Merci pour vos commentaires quand même.



1
votes

Étant donné que vous n'obtenez pas de processus pour afficher l'interface utilisateur du service, je vous recommande d'exécuter le processus d'assistant lorsque l'utilisateur se connecte et démarrez votre processus à partir de celui-ci.


2 commentaires

Je ne. Au moins pas nécessairement ... pourquoi créer un service et un processus d'assistance? Si vous vous trouvez besoin de créer un processus d'assistant que les automates sur la connexion (Bleh), vous devez également réévaluer sérieusement si vous avez besoin d'un service en premier lieu. Juste parce que vous peut faire quelque chose ne signifie pas que c'est recommandé de le faire.


Ouais - tu as raison sur celui-ci. Cependant, si vous avez besoin de quelque chose qui fonctionnera toujours et signalera à l'utilisateur parfois, cette architecture est une sorte d'ok-ish?



1
votes

Je me rends compte que je suis un peu en retard à cette fête. Mais comme cette question est arrivée dans ma recherche d'une solution, je vais fournir une réponse à la question de l'OP.

Vous pouvez démarrer un programme à partir d'un service à l'aide de CreateProcessasUser, à l'aide du jeton de l'utilisateur connecté. MSDN fournit une bonne application d'exemple démontrant cela; Recherchez CSCreateProcessasUserFromservice: https://code.msdn.microsoft.com/windowsapps/cscreateProcessasUserfromse-B682134E#Content

Je l'ai essayé et ça marche. Je suis capable de créer un nouveau processus pour mon application existante .NET à partir d'un service et cela fonctionne simplement bien. J'ai défini le journal de service sur les propriétés du compte système local, mais laissé le service "Autoriser le service d'interaction avec le bureau" décoché. Ma candidature est créée lorsque la minuterie expire et fonctionne comme celle-ci, tout comme elle a commencé normalement, y compris la présentation de l'interface graphique et l'interaction de l'utilisateur.

Que ce soit une chose inappropriée ou indésirable à faire est une autre discussion. Mais c'est bien possible, et vraiment pas si difficile.


1 commentaires

lien ne fonctionne pas - peut-être que vous pourriez montrer un extrait de la solution ici



1
votes

Il y a une sorte de travail autour, mais je conseillerais de ne faire que cela si vous êtes sûr d'accepter le problème de sécurité!

Cela pourrait être la réponse à votre problème: CreateProcessasUser .

L'exemple montre comment créer / lancer un processus de manière interactive dans la session de l'utilisateur connecté à partir d'une application de service écrite dans C # .NET.


0 commentaires