我安装了主机应用作为win服务。此主机支持在自己的域中安装插件。使用程序集阴影复制启用域。基本上插件也是赢得服务。因此,在插件安装过程中,有以下几个阶段:
创建域,影子加载插件的程序集
使用依赖注入实例化插件服务
执行服务安装
启动插件的服务
第三和第四阶段:
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从未执行过。
如果手动启动已安装的插件服务或者禁用子域上的卷影复制,我也会看到相同的事件日志。那怎么了?
答案 0 :(得分:0)
从代码中,我的猜测是它正在尝试启动正在启动的服务,因此导致异常。
要确认,请在StartWinService
函数中记录serviceController.Status
的状态。我怀疑它现在是StartPending
,因为您已经调用了ServiceBase.Run(service)
如果正确,请尝试删除serviceController部件。
说明:ServiceBase.Run()只注册服务(又名:标记为启动),因此无法保证当您使用serviceController检查状态时,您的服务已经完成启动。