Windows服务安装并在另一个服务中启动

时间:2016-05-25 19:16:41

标签: c# windows-services

我安装了主机应用作为win服务。此主机支持在自己的域中安装插件。使用程序集阴影复制启用域。基本上插件也是赢得服务。因此,在插件安装过程中,有以下几个阶段:

  1. 创建域,影子加载插件的程序集

  2. 使用依赖注入实例化插件服务

  3. 执行服务安装

  4. 启动插件的服务

  5. 第三和第四阶段:

    public class ServiceCommander : MarshalByRefObject
    {
        public Exception InstallWinService()
        {
            var assembly = service.GetType().Assembly;
            var account = AccountStore.GetAccount().Split(' ');
            var installer = new AssemblyInstaller(assembly, 
                new [] { $"/user={account[0]}", $"/password={account[1]}", $"/LogFile={TracksSinkHost.InstallLogPath}" });
            try
            {
                installer.UseNewContext = true;
                installer.Install(null);
                installer.Commit(null);
                return null;
            }
            catch (Exception ex)
            {
                installer.Rollback(null);
                return new Exception(ex.Message) { Source = ex.Source }; 
            }
        }
    
        public Exception StartWinService(bool ignoreManualStartType = false)
        {
            try
            {
                ServiceBase.Run(service);
                var serviceController = new ServiceController(service.ServiceName);
                if (serviceController.Status != ServiceControllerStatus.Running &&
                    (serviceController.StartType == ServiceStartMode.Automatic || ignoreManualStartType))
                    serviceController.Start();
                return null;
            }
            catch (Exception ex)
            {
                return new Exception(ex.Message) { Source = ex.Source };
            }
        }
    }
    

    其中 service 对象是ServiceBase

    虽然所有阶段都取得了成功,但第四阶段并没有成功。 serviceController.Start() 立即抛出"由于以下错误,服务无法启动: 该服务没有及时响应启动或控制请求。" 我也在系统事件日志中看到"等待超时(30000毫秒)服务连接。"

    对我来说,似乎服务控制管理器无法找到插件的入口点,所以我在插件的项目中提供了启动对象:

    static class Program
    {
        public static ServiceBase Service;
    
        static void Main(string[] args)
        {
            if (Service != null)
                ServiceBase.Run(Service);
        }
    }
    

    但是Main从未执行过。

    如果手动启动已安装的插件服务或者禁用子域上的卷影复制,我也会看到相同的事件日志。那怎么了?

1 个答案:

答案 0 :(得分:0)

从代码中,我的猜测是它正在尝试启动正在启动的服务,因此导致异常。

要确认,请在StartWinService函数中记录serviceController.Status的状态。我怀疑它现在是StartPending,因为您已经调用了ServiceBase.Run(service)

如果正确,请尝试删除serviceController部件。

说明:ServiceBase.Run()只注册服务(又名:标记为启动),因此无法保证当您使用serviceController检查状态时,您的服务已经完成启动。