代码之家  ›  专栏  ›  技术社区  ›  Luca

服务没有响应控制功能(错误2186)

  •  7
  • Luca  · 技术社区  · 14 年前

    我正在开发一个在Windows平台上使用.NET的服务。

    它一直有效到昨天…但今天不想开始!!!!看起来很奇怪,我觉得我错过了什么…

    我还尝试将源恢复到上一个工作版本,但没有发生其他情况: 网络启动 输出:

    服务没有响应控制功能。

    什么会导致这个故障?


    也许你们大多数人都想了解更多。那么,让我给你看一些代码:

    服务代码:

    #if DEBUG
    class iGeckoService : DebuggableService
    #else
    class iGeckoService : ServiceBase
    #endif
    {
        static void Main()
        {
    #if DEBUG
            if (Debugger.IsAttached == true) {
                DebuggableService[] services = Services;
    
                // Create console
                AllocConsole();
    
                // Emulate ServiceBase.Run
                foreach (DebuggableService service in services)
                    service.Start(null);
    
                // Wait for new line
                Console.WriteLine("Press ENTER to exit..."); Console.ReadLine();
    
                // Emulate ServiceBase.Run
                foreach (DebuggableService service in services)
                    service.Stop();
            } else
                ServiceBase.Run(Services);
    #else
            ServiceBase.Run(Services);
    #endif
        }
    
    #if DEBUG
    
        static DebuggableService[] Services
        {
            get {
                return (new DebuggableService[] { new iGeckoService() });
            }
        }
    
        [DllImport("kernel32")]
        static extern bool AllocConsole();
    
    #else
    
        static DebuggableService[] Services
        {
            get {
                return (new ServiceBase[] { new iGeckoService() });
            }
        }
    
    #endif
    
        #endregion
    
        #region Constructors
    
        /// <summary>
        /// Default constructor.
        /// </summary>
        public iGeckoService()
        {
            // Base properties
            ServiceName = DefaultServiceName;
    
            // Service feature - Power events
        }
    
        #endregion
    
        protected override void OnStart(string[] args)
        {
            try {
                ...
    
            } catch (Exception e) {
                sLog.Error("Unable to initialize the service. Request to stop.", e);
            }
        }
    
        /// <summary>
        /// Stop this service.
        /// </summary>
        protected override void OnStop()
                {
                         ...
                }
      }
    
      [RunInstaller(true)]
    public class iGeckoDaemonInstaller : Installer
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        public iGeckoDaemonInstaller()
        {
            ServiceProcessInstaller spi = new ServiceProcessInstaller();
            spi.Account = ServiceAccount.LocalSystem;
    
            ServiceInstaller si = new ServiceInstaller();
            si.ServiceName = iGeckoService.DefaultServiceName;
            si.StartType = ServiceStartMode.Automatic;
    
            Installers.AddRange(new Installer[] {spi, si});
        }
    }
    
    class DebuggableService : ServiceBase
    {
        public void Start(string[] args) { OnStart(args); }
    }
    

    开始脚本是:

    installutil ..\bin\Debug\iGeckoService.exe
    net start "Gecko Videowall"
    

    当停止脚本是:

    net stop "Gecko Videowall"
    installutil /u ..\bin\Debug\iGeckoService.exe
    

    但是,我认为这是一个系统设置,因为应用程序直到最后一天都运行良好。(叹气)


    更新

    当服务工作时,我使用log4net记录服务活动(我无法将调试程序附加到正在运行的服务…),并且它始终记录。

    从现在开始,它永远不会被创建的log4net日志(即使我启用了内部调试选项),即使我在主例程上登录!


    另一个更新

    似乎从未执行过该应用程序。我减少了所有的程序(主程序、启动程序、启动程序),并且运行了一个空服务。OnStart例程在一个目录上创建一个文件(每个人都可以完全写入),但是当服务启动时,不会创建任何文件。


    又一个更新

    在Rob的评论的刺激下,我在事件查看器上看到了以下消息:

    > Faulting application name: iGeckoService.exe, version: 1.0.0.0, time stamp: 0x4c60de6a
    > Faulting module name: ntdll.dll, version: 6.1.7600.16385, time stamp: 0x4a5be02b
    > Exception code: 0x80000003
    > Fault offset: 0x000000000004f190
    > Faulting process id: 0x1258
    > Faulting application start time: 0x01cb384a726c7167
    > Faulting application path: C:\Users\Luca\Documents\Projects\iGeckoSvn\iGeckoService\bin\Debug\iGeckoService.exe
    > Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
    > Report Id: b096a237-a43d-11df-afc4-001e8c414537
    

    这无疑是服务关闭的原因…问题不是这样的:“ 如何调试它? “(谢谢Rob,我到现在才想到事件查看器!) 调试它作为控制台应用程序运行,它不会显示任何错误,实际上它似乎与服务环境有关。我唯一想到的可能是某个DLL加载失败,因为现在服务是空的…有什么想法吗?

    (谢谢大家跟踪我…我想给你提供披萨和啤酒)


    解决了的!

    由于安装和安装MS应用程序验证程序(x64)导致主例程之前发生崩溃,服务无法启动。卸载应用程序后,一切正常!

    谢谢大家!

    3 回复  |  直到 14 年前
        1
  •  4
  •   Oleg    14 年前

    一般来说,每个服务都必须做以下两件简单的事情

    • 如果服务经理给他一个控制代码 SERVICE_CONTROL_START , SERVICE_CONTROL_STOP 等等,如果应该在短时间内返回。使用 SetServiceStatus 函数服务可以延长此间隔,例如通过调用 设置服务状态 递增 dwCheckPoint 价值。(在.NET中,可以使用 ServiceBase.RequestAdditionalTime 相反)
    • 每项服务都必须响应 SERVICE_CONTROL_INTERROGATE 控制代码仅返回。此控制代码用于从服务管理器检测服务是否仍然存在。

    如果您的程序不遵循其中一个规则,则会收到错误“服务没有响应控制功能”。

    如果你在.NET中编写一个程序,你不需要直接做我前面描述的两件事。这个 ServiceBase 同学们为你做。不过,如果创建一个 线程运行优先级高于正常值 或者如果你在一个onxxx手柄内做了太长的工作( OnStop , OnStart , OnPowerEvent 等)无需呼叫 ServiceBase.RequestAdditionalTime . 使用其他线程的一些技巧也会产生问题。

        2
  •  3
  •   Jon Skeet    14 年前

    通常情况下,如果您试图在 OnStart 打电话。例如,如果您在同一个线程中开始一个无休止的循环,您将收到这个错误消息。

    通常,服务应该在 开始时 调用,然后在 OnStop 打电话。

    当然,如果您使用的是以前工作过的代码,那么这不会有帮助。失败后您是否尝试重新启动它?我似乎记得,如果您已经有了一个已被借用的服务,那么在不重新启动它的情况下恢复到工作状态有时会很困难。您可能想查看您的进程列表,看看是否有一个副本仍在运行,如果有,就杀死它。

        3
  •  0
  •   ajay_whiz    14 年前

    我看到有一个代码块

    // Wait for new line
                Console.WriteLine("Press ENTER to exit..."); Console.ReadLine();
    

    如@jon所述,因为这是一项服务。当服务启动时,它会等待一个规定的时间来响应。

    有一个声明” Console.ReadLine() “您的服务将等待按键。因为这是一项服务,所以会一直在等待