2012-08-31 73 views
76

通常情况下,我得到这个错误: (本地计算机上的“服务名称”服务启动,然后停止一些服务自动停止,如果他们不被其他服务或应用。程序),当我的代码出现问题时(例如不存在的驱动器路径等),Windows服务将无法启动。Windows服务启动,然后停止错误

我有备份的文件夹/文件,一个位置,如果它达到大小限制Windows服务。详细信息全部由Windows服务读取的XML配置提供。我有一个单独的窗体,它有一个按钮,它完全符合我的Windows服务的onstart所做的。我使用我的Windows窗体来调试代码,然后将其放入我的Windows服务中。

当我启动我的Windows窗体。它做它想做的事情。当我将我的代码放入Windows服务OnStart()方法时,出现错误。

这里是我的代码:

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

我不知道是什么让Windows服务没有启动,Windows窗体模拟器的罚款。什么似乎是问题?

更新: 经过多次试验后,我发现只使用文件夹目录(w/out文件),windows服务不起作用。当我用特定文件(包括其目录)替换fileWatch变量时,Windows服务启动。当我将其更改回文件夹位置时,它不起作用。我认为文件夹位置在filewatcher中不起作用。

当我尝试创建一个新的Windows服务,观看文件夹的位置,它的工作..但是,当我在我原来的Windows服务中尝试相同的位置,它不工作!我是mindf $#ed!看来我必须创建一个新的Windows服务,并且每次我放置一个新的代码/函数时都要构建安装程序。这样我就可以跟踪出现错误的位置。

回答

156

如果该服务启动和停止这样的,这意味着你的代码抛出一个未处理的异常。这很难调试,但有几个选项。

  1. 查看Windows 事件查看器。通常情况下,您可以转到计算机/服务器管理器,然后单击事件查看器Windows日志应用程序。你可以看到什么抛出异常,这可能会有所帮助,但是你没有得到堆栈跟踪。
  2. 将您的程序逻辑解压缩到库类项目中。现在创建两个不同版本的程序:一个控制台应用程序(用于调试)和Windows服务。 (这是一个初步的努力,但从长远来看可以节省很多焦虑。)
  3. 添加更多的try/catch块并登录到应用程序以更好地了解正在发生的事情。
+5

非常感谢!我试过了,这是错误:“服务无法启动System.ArgumentException:路径不是合法的形式 at System.IO.Path.NormalizePath(String path,Boolean fullCheck,Int32 maxPathLength) at System .IO.Path.GetFullPathInternal(String path) at System.IO.Path。GetFullPath(字符串路径) 在System.IO.FileSystemWatcher.StartRaisingEvents() 在System.IO.FileSystemWatcher.set_EnableRaisingEvents(布尔值) 在LogBackupWinSvc.Service1.OnStart(字串[] args) 在了System.ServiceProcess.ServiceBase。 ServiceQueuedMainCallback(Object state)“ – Blackator

+3

Windows事件查看器显示了完整的堆栈跟踪,非常有帮助的工具 –

0

使用定时器和Tick事件复制文件。

在启动该服务,启动时间和指定的时间间隔。

所以服务是保持运行和复制文件ontick。

希望它有帮助。

0

你可能想单元测试初始化​​ - 但因为它在OnStart方法中,这几乎是不可能的。我建议将初始化代码移出到一个单独的类中,以便它可以被测试或至少在表单测试器中重新使用。

其次要添加一些日志记录(使用Log4Net或类似的)并添加一些详细的日志记录,以便您可以看到有关运行时错误的详细信息。运行时错误的例子是AccessViolation等,特别是如果您的服务运行时没有足够的权限访问配置文件。

28

不知道这会有所帮助,但调试服务,你总是可以使用在OnStart方法如下:

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

比你可以在你的Visual Studio附加到该进程,并有更好的调试能力。

希望这是有帮助的, 好运

+0

这是一个很好的调试解决方案,谢谢 –

+0

这是迄今为止最好的解决方案(至少对我而言)。对我来说,它弹出了一个JIT调试器的UAC确认对话框,然后让我选择VS 2015作为调试器 – Smitty

0

这是运行此服务的帐户可能没有映射d:A-驱动(它们是用户专用)。尝试共享目录,并在您的backupConfig中使用完整的UNC路径。

您的watcher类型FileSystemWatcher是局部变量,并且在OnStart方法完成时超出范围。你可能需要它作为一个实例或类变量。

8

我发现它非常方便的将现有窗口服务转换控制台只需更改以下程序即可。有了这个改变,你可以通过在Visual Studio中调试或者正常运行可执行文件来运行程序。但它也可以作为一个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

只是FYI,博客不起作用 –

0

我碰到了同样的问题。我的服务正在上传/接收XMLS并将错误写入事件日志。

当我去了事件日志,我试图过滤它。它提示我事件日志已损坏。

我清除了事件日志,一切正常。

1

EventLog.Log应设置为“应用程序”

+0

我刚刚upvoted,因为这实际上是解决问题的方法我 – Savage

相关问题