none
Service Windows RRS feed

  • Question

  • Bonjour,

    J'ai réalisé un service Windows intégrant l'installeur et tout se passe bien avec InstallUtil mais quand je tente de démarrer mon service, j'obtiens invariablement :

    Impossible de démarrer le service sur Ordinateur local. Erreur 1067 : le processus s'est arrêté inopinément.

    Je teste mon servicev à l'aide d'un form lançant mon service et là tout se passe bien...

    Any suggestion ?

    mercredi 11 mai 2011 12:42

Réponses

  • Oui Environment.CurrentDirectory renvoi le répertoire de travail qui dans le cas d'un service est différent du répertoire ou s'exécute l'assembly.
    Pour corriger, vous pouvez récuperer le path par reflexion sur l'assembly :

    System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    
    Cordialement

     

    mardi 17 mai 2011 09:24
    Modérateur
  • Bonjour,

    pour déboguer le service réellement lancé, vous pouvez ajouter l'instruction : Debugger.Break(); ou Debugger.Launch(); dans le constructeur par exemple.

    Ceci devrait vous permettre d'attacher Visual Studio au process lancé.

    Par contre il faudra compiler en Debug et il faudra mettre en commentaire votre code de test via la directive de precompilation #DEBUG

    Cordialement
    lundi 16 mai 2011 14:17
    Modérateur

Toutes les réponses

  • Bonjour,

    le source de l'executable du service est-il dans le Path ?

    Le service démarre-t-il avec un compte spécifique ou bien system ?

    Si tu copies le chemin executé lors du lancement du service dans une boite DOS as-tu une erreur ?

     

     


    fred
    mercredi 11 mai 2011 12:49
  • 1. "le source de l'executable du service est-il dans le Path ?" : non et je ne vois pas le rapport...

    2. "Le service démarre-t-il avec un compte spécifique ou bien system ?" : j'ai essayé les deux, LocalSystem et mon compte d'ouverture de session, sans succès

    3. "Si tu copies le chemin executé lors du lancement du service dans une boite DOS as-tu une erreur ?" : oui : Echec de démarrage du service Windows : Impossible de démarrer un service à partir de la ligne de commande ou du débogueur...

    Cordialement,

    mercredi 11 mai 2011 12:54
  • Bonjour,

    Peux-tu nous montrer le code de ton service ?

     


    fred
    mercredi 11 mai 2011 22:13
  • La classe de lancement du service (avec le mode DEBUG qui va bien) :

      static class Program
      {
    #if DEBUG
        private static Service m_serv = new Service();
    #endif
    
        /// <summary>
        /// Point d'entrée principal de l'application.
        /// </summary>
        static void Main()
        {
    #if !DEBUG
          ServiceBase[] ServicesToRun;
          ServicesToRun = new ServiceBase[] 
    			{ 
    				new Service() 
    			};
          ServiceBase.Run(ServicesToRun);
    #else
          m_serv.OnDebugStart(new string[0]);
          System.Windows.Forms.Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
          System.Windows.Forms.Application.Run(new dbgForm());
    #endif
        }
    
    #if DEBUG
        private static void Application_ApplicationExit(object sender, EventArgs e)
        {
          m_serv.OnDebugStop();
        }
    #endif
    
      }
    
    
    La classe de mon service :

      /// <summary>Classe de gestion du service Windows des échanges Copilote</summary>
      public partial class Service : ServiceBase, ILog
      {
        #region Classes internes
        /// <summary>
        /// Classe interne de gestion d'un triplet d'échanges
        /// <remarks>Implémente ILog</remarks>
        /// </summary>
        internal class GestionTriplet : ILog
        {
           //...
        }
    
        #region Propriétés publiques
        /// <summary>Hôte de communication pour les services WCF (service communiquant)</summary>
        public ServiceHost host = null;
        #endregion
    
        #region Propriétés privées
        /// <summary>Liste des instances d'échanges</summary>
        private List<GestionTriplet> listeTriplets = new List<GestionTriplet>();
        #endregion
    
        #region Constructeurs
        /// <summary>
        /// Constructeur
        /// </summary>
        public Service()
        {
          this.InitializeComponent();
          if (!System.Diagnostics.EventLog.SourceExists("Echanges"))
          {
            System.Diagnostics.EventLog.CreateEventSource(
              "Echanges", "LogCopilote");
          }
          this.eventLog.Source = "Echanges";
          this.eventLog.Log = "LogCopilote";
        }
        #endregion
    
        #region Méthodes d'implémentation des actions du service
        /// <summary>
        /// Méthode de lancement du service
        /// </summary>
        /// <param name="args">Paramètres optionnels</param>
        protected override void OnStart(string[] args)
        {
          this.eventLog.WriteEntry("Démarrage du service");
          // Définition des canaux de log
          this.RaiseLogEvent += GestionLog.Instance.AddEntry;
          // Mise en place de la partie WCF
          if (this.host != null) { this.host.Close(); }
          this.host = new ServiceHost(
           typeof(WCFService),
           new Uri[]{
            new Uri("http://localhost:9999"),
            new Uri("net.pipe://localhost")
           });
          this.host.AddServiceEndpoint(typeof(IWCFService), new BasicHttpBinding(), "HttpGetInfos");
          this.host.AddServiceEndpoint(typeof(IWCFService), new NetNamedPipeBinding(), "PipeGetInfos");
          this.host.Open();
    
          this.InitialiseConfiguration();
          this.eventLog.WriteEntry("Service démarré.");
        }
    
        /// <summary>
        /// Redéfinition en public de la méthode OnStart
        /// <remarks>Utilisé pour le mode Debug du service</remarks>
        /// </summary>
        /// <param name="args">Paramètres optionnels</param>
        public void OnDebugStart(string[] args)
        {
          this.OnStart(args);
        }
    
        /// <summary>
        /// Redéfinition en public de la méthode OnStop
        /// <remarks>Utilisé pour le mode Debug du service</remarks>
        /// </summary>
        public void OnDebugStop()
        {
          this.OnStop();
        }
    
        /// <summary>
        /// Méthode d'arrêt du service
        /// </summary>
        protected override void OnStop()
        {
          this.eventLog.WriteEntry("Arrêt du service");
          if (this.host != null)
          {
            this.host.Close();
            this.host = null;
          }
          this.listeTriplets.Clear();
    
          this.eventLog.WriteEntry("Service arrêté");
        }
    
        /// <summary>
        /// Méthode de mise en pause du service
        /// </summary>
        protected override void OnPause()
        {
          this.eventLog.WriteEntry("Mise en pause du service du service");
          this.timer.Enabled = false;
        }
    
        /// <summary>
        /// Méthode de reprise du service
        /// </summary>
        protected override void OnContinue()
        {
          this.eventLog.WriteEntry("Mise en marche du service du service");
          this.timer.Enabled = true;
        }
        #endregion
    
        private void eventLog_EntryWritten(object sender, EntryWrittenEventArgs e)
        {
    
        }
    
        private void InitialiseConfiguration()
        {
          // On va chercher les éléments de configuration dans le app.config
          NameValueCollection appSettings = ConfigurationManager.AppSettings;
          for (int i = 0; i < appSettings.Count; i++)
          {
            // Le appSettings référence le nom de la section Triplet de paramétrage du noyau
            if (appSettings.GetKey(i) == "Config")
            {
              this.listeTriplets.Add(new GestionTriplet(appSettings[appSettings.GetKey(i)], this.RaiseLogEvent));
              break;
            }
            else
            {
              this.OnRaiseLogEvent(new LogEventArgs(TypeLog.Noyau, TypeErreur.ErreurFatale, "Paramétrage manquant pour le noyau."));
              Environment.Exit(0);
            }
          }
        }
    
        private void timer_Tick(object sender, EventArgs e)
        {
          // On désactive le compteur...
          this.timer.Enabled = false;
          foreach (GestionTriplet triplet in this.listeTriplets)
          {
            // On envoie le Tick à chaque noyau
            triplet.Tick();
          }
          // On réactive le compteur...
          this.timer.Enabled = true;
        }
    
        #region Implémentation de l'interface ILog
        /// <summary>
        /// Evénement permettant de logger
        /// </summary>
        public event LogEventHandler RaiseLogEvent;
    
        /// <summary>
        /// Méthode d'écriture de l'événement si l'événement est souscrit
        /// </summary>
        /// <param name="eventArg">Objet événement typé</param>
        public virtual void OnRaiseLogEvent(LogEventArgs eventArg)
        {
          // Make a temporary copy of the event to avoid possibility of
          // a race condition if the last subscriber unsubscribes
          // immediately after the null check and before the event is raised.
          LogEventHandler handler = RaiseLogEvent;
    
          // Event will be null if there are no subscribers
          if (handler != null)
          {
            // Use the () operator to raise the event.
            handler(this, eventArg);
          }
        }
        #endregion
      }
    
    

    jeudi 12 mai 2011 07:13
  • Bonjour,

    Pouvez-vous obtenir plus des infos sur l’erreur que « Impossible de démarrer le service sur Ordinateur local. Erreur 1067 : le processus s'est arrêté inopinément » par le système de log ?

     

    Cordialement,

    Cipri


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    lundi 16 mai 2011 13:27
  • Bonjour,

    J'ai ça dans l'observateur d'événements :

     

    Type de l'événement :	Informations
    Source de l'événement :	Service Control Manager
    Catégorie de l'événement :	Aucun
    ID de l'événement :	7035
    Date :		11/05/2011
    Heure :		16:16:20
    Utilisateur :	JBR_SM\JBR
    Ordinateur :	JBR_SM
    Description :
    Un contrôle Démarrer a correctement été envoyé au service Service d'échanges avec Copilote.
    
    Pour plus d'informations, consultez le centre Aide et support à l'adresse http://go.microsoft.com/fwlink/events.asp.
    

     

    puis 1 seconde plus tard :

     

     

    Type de l'événement : Erreur
    Source de l'événement : Service Control Manager
    Catégorie de l'événement : Aucun
    ID de l'événement : 7034
    Date :  11/05/2011
    Heure :  16:16:21
    Utilisateur : N/A
    Ordinateur : JBR_SM
    Description :
    Le service Service d'échanges avec Copilote s'est terminé de façon inattendue pour la 8ème fois.
    
    Pour plus d'informations, consultez le centre Aide et support à l'adresse http://go.microsoft.com/fwlink/events.asp.
    
    Cordialement,

     


    lundi 16 mai 2011 13:35
  • Bonjour,

    pour déboguer le service réellement lancé, vous pouvez ajouter l'instruction : Debugger.Break(); ou Debugger.Launch(); dans le constructeur par exemple.

    Ceci devrait vous permettre d'attacher Visual Studio au process lancé.

    Par contre il faudra compiler en Debug et il faudra mettre en commentaire votre code de test via la directive de precompilation #DEBUG

    Cordialement
    lundi 16 mai 2011 14:17
    Modérateur
  • Bonjour, Julien,

    De ce que j’ai lu il semble que l’erreur 1067 peut être générée par une erreur de code dans votre service windows, donc déboguer comme Nikho vous a proposée peut vous donner plus des informations. Ce qui m’étonne est que si la source d’erreur est en fait une erreur de code, il devrait être dans votre log… ou je n’ai pas lu bien votre code ?

     

    Puis j’ai vu qu’il y a des personnes qui ont résolu le problème par publier une nouvelle version du service windows (voir ce thread, par exemple). Avez-vous essayé de republier et réinstaller votre service ?

     

    Cordialement,

    Cipri


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    mardi 17 mai 2011 08:07
  • Bonjour,

    Je vais tenter la démarche proposée par Nikho... Mais vu que c'est opérationnel en mode DEBUG (lancement du service via une winform) j'ai des doutes...

    J'ai tenté à moult reprises de dés/ré-installer avec ou sans redémarrage de Windows et j'obtiens toujours la même chose...

    Cordialement,

    mardi 17 mai 2011 08:11
  • J'obtiens ce message :

    "Aucun symbole n'a été chargé pour un frame de pile des appels. Le code source ne peut pas être affiché."

    Cordialement,

    mardi 17 mai 2011 08:27
  • Avez vous compilez le service en mode debug ?

    Cordialement

    mardi 17 mai 2011 08:27
    Modérateur
  • OK... J'ai pu rentrer en débuggage et du coup je me rends compte que Environment.CurrentDirectory est positionné à "C:\Windows\System32" dans le contexte de service et non au répertoire dans lequel j'ai mon exécutable de service ainsi que les dll de dépendance... Vous avez une idée ?

    Cordialement,

    mardi 17 mai 2011 09:05
  • Oui Environment.CurrentDirectory renvoi le répertoire de travail qui dans le cas d'un service est différent du répertoire ou s'exécute l'assembly.
    Pour corriger, vous pouvez récuperer le path par reflexion sur l'assembly :

    System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    
    Cordialement

     

    mardi 17 mai 2011 09:24
    Modérateur
  • Merci à tous ! Et un bravo à Nikho !
    mercredi 18 mai 2011 08:11