2012-08-31 11 views
76

Normalmente, aparece este error: (el servicio "nombre de servicio" en el equipo local se inició y luego se detuvo. Algunos servicios se detienen automáticamente si no están siendo utilizados por otro servicio o programas) cuando hay algún problema con mi código, como rutas de disco no existentes, etc. El servicio de Windows no se iniciará.Servicio de Windows en computadora local iniciado y luego detenido error

Tengo un servicio de Windows que realiza una copia de seguridad de las carpetas/archivos, en una ubicación si alcanzó el límite de tamaño. Los detalles son proporcionados por una Configuración XML que el servicio de Windows lee al inicio. Tengo un formulario de Windows separado que tiene un botón que hace exactamente lo que está haciendo el inicio de mi servicio de Windows. Uso mis formularios de Windows para depurar el código antes de ponerlo en mi servicio de Windows.

Cuando comienzo mis formularios de Windows. Hace lo que se supone que debe hacer. Cuando puse mi código en el servicio de Windows, el método OnStart() apareció el error.

Aquí está mi código:

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(); 
     } 
    } 

No sé lo que mantiene el servicio de Windows no se inicia, el simulador de forma ventanas funcionaba bien. ¿Cuál parece ser el problema?

ACTUALIZACIÓN: Después de muchas pruebas, he notado que al usar solo un directorio de carpetas (sin archivo), el servicio de Windows no funciona. Cuando reemplacé la variable de FileWatch con un archivo específico (incluido su directorio), se inició el servicio de Windows. Cuando lo cambié a una ubicación de carpeta, no funcionó. Lo que creo es que las ubicaciones de las carpetas no funcionan en un vigilante de archivos.

Cuando traté de crear un nuevo servicio de Windows que mira la ubicación de una carpeta, funcionó .. Sin embargo, cuando probé la misma ubicación en mi servicio de Windows original, ¡no funcionó! ¡Tenía la mente $ # * ed! Parece que tengo que crear un nuevo servicio de Windows y construir el instalador cada vez que coloque un nuevo código/función. De esta forma puedo hacer un seguimiento de donde obtengo un error.

Respuesta

156

Si el servicio se inicia y se detiene así, significa que su código arroja una excepción no controlada. Esto es bastante difícil de depurar, pero hay algunas opciones.

  1. Consulte el Visor de eventos de Windows . Normalmente puede acceder a esto yendo al administrador de la computadora/servidor, luego haciendo clic en Visor de eventos ->Registros de Windows ->Aplicación. Puede ver qué arrojó la excepción aquí, lo que puede ayudar, pero no obtiene el seguimiento de la pila.
  2. Extraiga la lógica de su programa en un proyecto de clase de biblioteca. Ahora cree dos versiones diferentes del programa: una aplicación de consola (para la depuración) y el servicio de Windows. (Esto es un poco esfuerzo inicial, pero ahorra mucha angustia a largo plazo).
  3. Agregue más bloques de prueba/captura e inicie sesión en la aplicación para tener una mejor idea de lo que está sucediendo.
+5

Muchas gracias! Lo intenté y este es el error: "El servicio no se puede iniciar. System.ArgumentException: La ruta no es de una forma legal. en System.IO.Path.NormalizePath (ruta de la cadena, Boolean fullCheck, Int32 maxPathLength) en el sistema .IO.Path.GetFullPathInternal (String path) en System.IO.Path.GetFullPath (camino String) en System.IO.FileSystemWatcher.StartRaisingEvents() en System.IO.FileSystemWatcher.set_EnableRaisingEvents (valor booleano) en LogBackupWinSvc.Service1.OnStart (String [] args) en System.ServiceProcess.ServiceBase. ServiceQueuedMainCallback (estado del objeto) " – Blackator

+3

Windows Event Viewer mostró el rastro completo de la pila, herramienta muy útil. –

0

Utilice el evento Timer and tick para copiar sus archivos.

Al iniciar el servicio, comience la hora y especifique el intervalo en el tiempo.

Así que el servicio sigue ejecutándose y copie los archivos ontick.

Espero que ayude.

0

Es posible que desee probar la inicialización de la unidad, pero como está en el método OnStart, es casi imposible. Sugeriría mover el código de inicialización a una clase separada para que pueda ser probado o al menos reutilizado en un comprobador de formularios.

En segundo lugar, agregue un poco de registro (usando Log4Net o similar) y agregue algunos registros detallados para que pueda ver detalles sobre los errores de tiempo de ejecución. Ejemplos de errores de tiempo de ejecución serían AccessViolation, etc. especialmente si su servicio se está ejecutando sin suficientes privilegios para acceder a los archivos de configuración.

28

No estoy seguro de que esto sea útil, pero para depurar un servicio siempre se puede utilizar el siguiente en el método OnStart:

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

de lo que podría conectar el estudio visual para el proceso y tienen mejores capacidades de depuración.

esperanza que esto era útil, buena suerte

+0

es una gran solución para la depuración, gracias –

+0

Esta es de lejos la mejor solución (al menos para mí). VS 2015 maneja esto muy bien Bueno, para mí apareció un diálogo de confirmación de UAC para el depurador JIT y luego me dejó seleccionar VS 2015 como depurador. – Smitty

0

La cuenta que se está ejecutando el servicio no podría haber mapeado el D: -drive (que son específicos del usuario). Intente compartir el directorio y use la ruta UNC completa en su backupConfig.

Su watcher del tipo FileSystemWatcher es una variable local, y está fuera del alcance cuando se realiza el método OnStart. Probablemente lo necesite como una instancia o variable de clase.

8

he encontrado que es muy útil para convertir su servicio ventanas existentes a una consola simplemente cambiando su programa con lo siguiente. Con este cambio, puede ejecutar el programa depurando en Visual Studio o ejecutando el ejecutable normalmente. Pero también funcionará como un servicio de Windows. I also made a blog post about it

Program.cs

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

YOUR_PROGRAM.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 
    } 
} 
+2

Solo digo, el blog no funciona. –

0

me encontré con el mismo problema. Mi servicio está cargando/recibiendo XMLS y escribiendo los errores en el Registro de eventos.

Cuando fui al registro de eventos, traté de filtrarlo. Me indicó que el registro de eventos estaba dañado.

Borré el registro de eventos y todo está bien.

1

EventLog.Log debe configurarse como "Aplicación"

+0

Acabo de votar porque esta era en realidad la solución al problema para yo – Savage

Cuestiones relacionadas