112

通常,我收到此错误:(本地计算机上的“服务名称”服务启动然后停止。如果某些服务未被其他服务或程序使用,则某些服务会自动停止)当我的代码出现问题时,例如不存在驱动器路径等。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 服务启动。当我将其更改回文件夹位置时,它不起作用。我认为文件夹位置在文件观察器中不起作用。

当我尝试创建一个监视文件夹位置的新 Windows 服务时,它起作用了。但是,当我在原始 Windows 服务中尝试相同的位置时,它不起作用!我很介意$#*!似乎每次我放置一个新的代码/功能时,我都必须创建一个新的 Windows 服务并构建安装程序。这样我可以跟踪哪里出现错误。

4

11 回答 11

213

如果服务像这样启动和停止,则意味着您的代码正在引发未处理的异常。这很难调试,但有几个选项。

  1. 查阅 Windows事件查看器。通常,您可以通过转到计算机/服务器管理器,然后单击Event Viewer -> Windows Logs -> Application来解决此问题。您可以在此处查看引发异常的原因,这可能会有所帮助,但您不会获得堆栈跟踪。
  2. 将您的程序逻辑提取到库类项目中。现在创建两个不同版本的程序:控制台应用程序(用于调试)和 Windows 服务。(这是一些初步的努力,但从长远来看可以节省很多焦虑。)
  3. 添加更多 try/catch 块并记录到应用程序,以更好地了解正在发生的事情。
于 2012-08-31T04:59:41.863 回答
37

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

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

比您可以将您的视觉工作室附加到该过程并具有更好的调试能力。

希望这有帮助,祝你好运

于 2012-08-31T05:44:51.637 回答
9

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

程序.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
    }
}
于 2014-06-05T22:22:04.423 回答
4

请检查您是否已在本地机器的访问控制列表 (ACL) 中注册了所有 HTTP 端点

http://just2thepoint.blogspot.fr/2013/10/windows-service-on-local-computer.html

于 2013-10-13T09:30:57.177 回答
2

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

于 2015-10-20T06:02:09.293 回答
1

同时,另一个原因:不小心删除了.config文件导致出现同样的错误信息:

“本地计算机上的服务启动然后停止。某些服务自动停止......”

于 2019-02-15T12:10:56.230 回答
0

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

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

所以该服务继续运行并复制文件ontick。

希望它有所帮助。

于 2012-08-31T05:03:21.407 回答
0

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

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

于 2012-08-31T05:31:37.590 回答
0

运行服务的帐户可能没有映射 D:-驱动器(它们是用户特定的)。尝试共享目录,并在backupConfig.

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

于 2012-08-31T05:59:01.577 回答
0

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

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

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

于 2014-07-25T11:05:43.450 回答
0

在我们的例子中,除了有问题的服务已经启动然后停止的日志之外,没有任何内容添加到 Windows 事件日志中。

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

于 2019-08-29T08:21:10.320 回答