本地计算机上的Windows服务启动,然后停止了错误


104

通常,我会收到以下错误消息:(我的代码出现问题时,例如不存在,(本地计算机上的“服务名称”服务已启动,然后停止。如果某些服务未被其他服务或程序使用,则某些服务会自动停止))驱动器路径等。Windows服务将无法启动。

我有一个Windows服务,可以将文件夹/文件备份到某个位置(如果达到大小限制)。所有细节均由Windows服务在启动时读取的XML配置提供。我有一个单独的Windows窗体,该窗体具有一个按钮,该按钮的功能与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窗体模拟器运行正常。似乎是什么问题?

更新:经过多次试验,我注意到仅使用文件夹目录(不带文件),Windows服务无法正常工作。当我用特定文件(包括其目录)替换fileWatch变量时,Windows服务启动。当我将其更改回文件夹位置时,它不起作用。我认为文件夹位置在Filewatcher中不起作用。

当我尝试创建一个监视文件夹位置的新Windows服务时,它可以工作。.但是,当我在原始Windows服务中尝试相同位置时,它却无法工作!我介意$#* ed!似乎每次放置新代码/函数时,我都必须创建一个新的Windows服务并构建安装程序。这样,我可以跟踪出现错误的位置。

Answers:


202

如果服务以这种方式启动和停止,则意味着您的代码将引发未处理的异常。这很难调试,但是有一些选择。

  1. 咨询Windows 事件查看器。通常,您可以通过转到计算机/服务器管理器,然后单击事件查看器 -> Windows日志 -> 应用程序来实现此目的。您可以在此处查看引发异常的原因,这可能有所帮助,但您没有得到堆栈跟踪。
  2. 将程序逻辑提取到库类项目中。现在,创建程序的两个不同版本:控制台应用程序(用于调试)和Windows服务。(这是一些初期工作,但从长远来看可以节省很多麻烦。)
  3. 添加更多的try / catch块并登录到应用程序,以更好地了解正在发生的事情。

10
Windows Event Viewer显示了完整的堆栈跟踪,非常有用的工具。
Talha Imam

37

不确定这是否有帮助,但是对于调试服务,您可以始终在OnStart方法中使用以下命令:

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

比您可以将Visual Studio附加到该过程中,并具有更好的调试能力。

希望这会有所帮助,祝你好运


到目前为止,这是最好的解决方案(至少对我而言)。VS 2015也很好地处理了这个问题。对我来说,它弹出了JIT调试器的UAC确认对话框,然后让我选择VS 2015作为调试器。
Smitty

9

我发现通过简单地使用以下内容更改程序即可将现有的Windows服务转换为控制台非常方便。通过此更改,您可以通过在Visual Studio中调试或正常运行可执行文件来运行程序。但是它也可以作为Windows服务使用。我也写了一篇博客文章

程式

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
    }
}




0

使用计时器和滴答事件复制文件。

启动服务时,启动时间并指定时间间隔。

因此,该服务将继续运行,并按要求复制文件。

希望对您有所帮助。


0

您可能需要对初始化进行单元测试-但由于它在OnStart方法中,因此几乎是不可能的。我建议将初始化代码移到一个单独的类中,以便可以对其进行测试或至少在表单测试器中重新使用它。

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


0

运行该服务的帐户可能尚未映射D:驱动器(它们是特定于用户的)。尝试共享目录,然后在中使用完整的UNC路径backupConfig

watcher的类型FileSystemWatcher是局部变量,OnStart完成方法后超出范围。您可能需要将它作为实例或类变量。


0

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

当我进入事件日志时,我尝试对其进行过滤。它提示我事件日志已损坏。

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


0

在我们的情况下,Windows事件日志中未添加任何内容,只有已启动有问题的服务然后停止了该问题的日志。

事实证明该服务的CONFIG文件无效。更正无效的CONFIG文件可解决此问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.