Le service Windows sur l'ordinateur local a démarré puis arrêté l'erreur

105

Habituellement, j'obtiens cette erreur: (Le service "nom du service" sur l'ordinateur local a démarré puis s'est arrêté. Certains services s'arrêtent automatiquement s'ils ne sont pas utilisés par d'autres services ou programmes) lorsqu'il y a un problème avec mon code, comme inexistant chemins de lecteur, etc. Le service Windows ne démarre pas.

J'ai un service Windows qui sauvegarde le dossier / les fichiers, à un emplacement s'il a atteint la limite de taille. Les détails sont tous fournis par une configuration XML que le service Windows lit au démarrage. J'ai un formulaire Windows distinct qui a un bouton qui fait exactement ce que fait le démarrage de mon service Windows. J'utilise mes formulaires Windows pour déboguer le code avant de le mettre dans mon service Windows.

Lorsque je démarre mes formulaires Windows. Il fait ce qu'il est censé faire. Lorsque j'ai mis mon code dans la méthode OnStart () du service Windows, l'erreur est apparue.

Voici mon code:

protected override void OnStart(string[] args)
{

    private static string backupConfig = @"D:\LogBackupConfig\backupconfig.xml";
    private static string serviceStat = @"D:\LogBackupConfig\Status.txt";
    private static string fileFolderStat = @"D:\LogBackupConfig\FileFolderStat.txt";

    protected override void OnStart(string[] args)
    {
        if (File.Exists(backupConfig))
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            XmlTextReader reader = new XmlTextReader(backupConfig);

            XmlNodeType type;
            List<string> listFile = new List<string>();
            string fileWatch = "";

            //this loop is for reading XML elements and assigning to variables
            while (reader.Read())
            {
                type = reader.NodeType;
                if (type == XmlNodeType.Element)
                {
                    if (reader.Name == "File")
                    {
                        reader.Read();
                        fileWatch = reader.Value;
                    }
                    else if (reader.Name == "Folder")
                    {
                        reader.Read();
                        fileWatch = reader.Value;
                    }
                }
            }
            reader.Close();

            watcher.Path = fileWatch;
            watcher.Filter = "*.*";

            //this loop reads whether the service will watch a file/folder
            XmlTextReader reader1 = new XmlTextReader(backupConfig);
            while (reader1.Read())
            {
                type = reader1.NodeType;
                if (type == XmlNodeType.Element)
                {
                    if (reader1.Name == "File")
                    {
                        watcher.IncludeSubdirectories = false;
                        watcher.Changed += new FileSystemEventHandler(OnChangedFile);
                    }
                    else if (reader1.Name == "Folder")
                    {
                        watcher.IncludeSubdirectories = true;
                        watcher.Changed += new FileSystemEventHandler(OnChangedFolder);
                    }
                }
            }
            reader1.Close();

            watcher.EnableRaisingEvents = true;

        }
        else
        {
            StreamWriter sw = new StreamWriter(serviceStat, true);
            sw.WriteLine("File not found. Please start the Log Backup UI first.");
            sw.Close();
        }
    }

Je ne sais pas ce qui empêche le service Windows de démarrer, le simulateur de formulaire Windows a bien fonctionné. Quel semble être le problème?

MISE À JOUR: Après de nombreux essais, j'ai remarqué qu'en utilisant uniquement un répertoire de dossiers (sans fichier), le service Windows ne fonctionne pas. Lorsque j'ai remplacé la variable fileWatch par un fichier spécifique (y compris son répertoire), le service Windows a démarré. Lorsque je l'ai changé à un emplacement de dossier, cela n'a pas fonctionné. Ce que je pense, c'est que les emplacements des dossiers ne fonctionnent pas dans un gestionnaire de fichiers.

Lorsque j'ai essayé de créer un nouveau service Windows qui surveille l'emplacement d'un dossier, cela a fonctionné. Cependant, lorsque j'ai essayé le même emplacement dans mon service Windows d'origine, cela n'a pas fonctionné! J'étais mindf $ # * ed! Il semble que je doive créer un nouveau service Windows et construire le programme d'installation à chaque fois que je place un nouveau code / une nouvelle fonction. De cette façon, je peux suivre où j'obtiens une erreur.

Blackator
la source

Réponses:

203

Si le service démarre et s'arrête comme ça, cela signifie que votre code lève une exception non gérée. C'est assez difficile à déboguer, mais il existe quelques options.

  1. Consultez l'Observateur d' événements Windows . Normalement, vous pouvez y accéder en accédant au gestionnaire d'ordinateur / serveur, puis en cliquant sur Observateur d'événements -> Journaux Windows -> Application . Vous pouvez voir ce qui a généré l'exception ici, ce qui peut aider, mais vous n'obtenez pas la trace de la pile.
  2. Extrayez la logique de votre programme dans un projet de classe de bibliothèque. Créez maintenant deux versions différentes du programme: une application console (pour le débogage) et le service Windows. (Ceci est un peu d'effort initial, mais évite beaucoup d'angoisse à long terme.)
  3. Ajoutez plus de blocs try / catch et connectez-vous à l'application pour avoir une meilleure image de ce qui se passe.
McGarnagle
la source
10
L'Observateur d'événements Windows a montré la trace complète de la pile, un outil très utile.
Talha Imam
37

Je ne suis pas sûr que cela soit utile, mais pour déboguer un service, vous pouvez toujours utiliser ce qui suit dans la méthode OnStart:

protected override void OnStart(string[] args)
{
     System.Diagnostics.Debugger.Launch();
     ...
}

que vous pourriez attacher votre studio visuel au processus et avoir de meilleures capacités de débogage.

j'espère que cela a été utile, bonne chance

Eyal H
la source
C'est de loin la meilleure solution (du moins pour moi). VS 2015 gère cela bien aussi. Pour moi, il est apparu une boîte de dialogue de confirmation UAC pour le débogueur JIT, puis laissez-moi sélectionner VS 2015 comme débogueur.
Smitty
9

J'ai trouvé très pratique de convertir votre service Windows existant en console en changeant simplement votre programme avec ce qui suit. Avec cette modification, vous pouvez exécuter le programme en déboguant dans Visual Studio ou en exécutant l'exécutable normalement. Mais cela fonctionnera également comme un service Windows. J'ai aussi fait un article de blog à ce sujet

program.cs

class Program
{
    static void Main()
    {
        var program = new YOUR_PROGRAM();
        if (Environment.UserInteractive)
        {
            program.Start();
        }
        else
        {
            ServiceBase.Run(new ServiceBase[]
            {
                program
            });
        }
    }
}

VOTRE_PROGRAMME.cs

[RunInstallerAttribute(true)]
public class YOUR_PROGRAM : ServiceBase
{
    public YOUR_PROGRAM()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        Start();
    }

    protected override void OnStop()
    {
        //Stop Logic Here
    }

    public void Start()
    {
        //Start Logic here
    }
}
Ben Anderson
la source
2

EventLog.Log doit être défini comme "Application"

panini pitke
la source
Je viens de voter car c'était en fait la solution au problème pour moi
Savage
1

Pendant ce temps, une autre raison: la suppression accidentelle du fichier .config a provoqué le même message d'erreur:

"Le service sur l'ordinateur local a démarré puis s'est arrêté. Certains services s'arrêtent automatiquement ..."

Emre Guldogan
la source
0

Utilisez Timer et cochez l'événement pour copier vos fichiers.

Au démarrage du service, démarrez l'heure et spécifiez l'intervalle de temps.

Ainsi, le service continue de fonctionner et copiez les fichiers en un clic.

J'espère que cela aidera.

Sethu
la source
0

Vous voudrez peut-être effectuer un test unitaire de l'initialisation - mais comme c'est dans la OnStartméthode, c'est presque impossible. Je suggérerais de déplacer le code d'initialisation dans une classe distincte afin qu'il puisse être testé ou au moins réutilisé dans un testeur de formulaire.

Deuxièmement, ajouter une journalisation (en utilisant Log4Net ou similaire) et ajouter une journalisation détaillée afin que vous puissiez voir les détails sur les erreurs d'exécution. Des exemples d'erreurs d'exécution seraient AccessViolationetc., en particulier si votre service s'exécute sans suffisamment de privilèges pour accéder aux fichiers de configuration.

Quinton Bernhardt
la source
0

Le compte qui exécute le service n'a peut-être pas mappé le lecteur D: (ils sont spécifiques à l'utilisateur). Essayez de partager le répertoire et utilisez le chemin UNC complet dans votre fichier backupConfig.

Votre watcherde type FileSystemWatcherest une variable locale et est hors de portée lorsque la OnStartméthode est terminée. Vous en avez probablement besoin comme variable d'instance ou de classe.

Alf Kåre Lefdal
la source
0

Je suis tombé sur le même problème. Mon service télécharge / reçoit XMLS et écrit les erreurs dans le journal des événements.

Quand je suis allé au journal des événements, j'ai essayé de le filtrer. Cela m'indique que le journal des événements a été corrompu.

J'ai effacé le journal des événements et tout est OK.

PanosPlat
la source
0

Dans notre cas, rien n'a été ajouté dans les journaux des événements Windows, sauf les journaux indiquant que le service problématique a été démarré puis arrêté.

Il s'avère que le fichier CONFIG du service n'était pas valide. La correction du fichier CONFIG non valide a résolu le problème.

rikitikitik
la source