C#将控制台应用程序作为Windows服务运行 - 服务未响应错误

时间:2017-08-15 13:08:34

标签: c# .net windows-services

我正在尝试运行一些控制台应用程序作为Windows服务,我跟着this question,我做了一些更改,使其适合我的应用程序。

我的主要代码如下:

public static class Program
{
    public class Service : ServiceBase
    {

        public Service(string serviceName)
        {
            this.ServiceName = serviceName;
        }

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

        protected override void OnStop()
        {
            Program.Stop(this.ServiceName);
        }
    }
    #endregion

    static void Main(string[] args)
    {
        if (!Environment.UserInteractive)
            // running as service
            using (var service = new Service("TestService"))
                ServiceBase.Run(service);
        else
        {
            // running as console app
            Start(args);
        }
    }

    private static void Start(string[] args)
    {
        while(true)
        {
            //DO SOMTHING
        }
    }

    private static void Stop(string serviceName)
    {
        //Writing to log that 'serviceName' stopped
    }
}

我尝试使用以下步骤将以下控制台应用程序作为服务运行:

1)使用命令:sc create ServiceTestName123 binPath =“路径到项目调试文件夹中的EXE文件”。

2)使用命令:sc start ServiceTestName123“parameter1”。

我收到了一个错误: “StartService FAILED 1053: 该服务没有及时响应启动或控制请求“

我读到了互联网中的错误,发现我可以尝试通过另一个线程运行start函数来解决这个问题,所以我将OnStart函数更新为以下函数:

protected override void OnStart(string[] args)
{
    Thread t = new Thread(() => Program.Start(args));
    t.Start();
}

尝试重新创建服务(删除旧服务并使用新的OnStart函数再次创建服务)并重新运行它后,我得到了同样的错误。

顺便说一句,当我将此代码作为控制台应用程序运行时,它运行正常。

有人可以解释一下我做错了什么吗?

非常感谢。

2 个答案:

答案 0 :(得分:1)

我尝试了你的确切步骤,它对我有用。我将重点介绍一些我遇到的关键点

  1. OnStart肯定应该及时回归。即工作应该在一个单独的过程/线程中进行。我使用你的代码进行线程,它对我来说很好。
  2. 确保可执行文件位于本地驱动器上,可从本地系统"本地系统访问。帐户没有任何权限问题。
  3. 确保在创建服务时,提供绝对路径而不是相对路径。
  4. 确保sc create ...命令以[SC] CreateService SUCCESS
  5. 回复
  6. 检查服务是否已在service control panel
  7. 中创建
  8. 确保您可以在从命令行尝试之前从service control panel启动它
  9. 此外,打开任务管理器或进程资源管理器以确保服务可执行文件是否正在运行(无论服务控制面板或scm start返回什么状态)
  10. 为了进行调试,我将信息记录到本地临时文件中 - 再次注意本地系统帐户的权限问题。
  11. 如果由于某种原因您必须删除该服务,请确保它确实已从service control panel
  12. 中消失

答案 1 :(得分:0)

要调试正在进行的操作,您可以在启动程序的初始阶段附加调试器。

这样,您可以查看您的计划正在做什么。

您还可以在Windows ever viewer中查看Windows正在抛出的错误。

将此行放在程序的开始跟踪中:

System.Diagnostics.Debugger.Launch()