问题描述
我有一个自定义安装程序类,用于安装我的 Windows 服务.精简到必要的细节,类看起来像这样.
I have a custom Installer class that is used when installing my Windows Service. Stripped down to the necessary details the class looks like this.
[RunInstaller(true)]
public class MyWindowsServiceInstaller : Installer
{
public MyWindowsServiceInstaller()
{
ServiceProcessInstaller processInstaller = new ServiceProcessInstaller();
ServiceInstaller serviceInstaller = new ServiceInstaller();
processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.DisplayName = Program.ServiceDetails.Name;
serviceInstaller.Description = Program.ServiceDetails.Description;
//Must be the same as what was set in Program's constructor
serviceInstaller.ServiceName = Program.ServiceDetails.Name;
Installers.Add(processInstaller);
Installers.Add(serviceInstaller);
}
}
然后根据传递给服务的参数,通过调用以下类通过代码安装服务,如下所示.这是从 Main
内部调用的.
The service is then installed through code by calling the following class, depending on arguments passed into the service, like so. This is called from inside of Main
.
using (ServiceHandler serviceHandler = new ServiceHandler(program.ModuleName, typeof(Program).Assembly))
{
serviceHandler.InstallService();
}
ServiceHandler
类在哪里(再次精简以消除噪音).
Where the ServiceHandler
class is (again stripped down to remove noise).
public class ServiceHandler : IDisposable
{
private ServiceController _serviceController;
private AssemblyInstaller _assemblyInstaller;
public ServiceHandler(string serviceName, Assembly assembly)
{
_serviceController = new ServiceController(serviceName);
_assemblyInstaller = new AssemblyInstaller(assembly, null);
_assemblyInstaller.UseNewContext = true;
}
public void InstallService()
{
if (IsServiceInstalled())
{
return;
}
IDictionary state = new Hashtable();
try
{
_assemblyInstaller.Install(state);
_assemblyInstaller.Commit(state);
}
catch
{
try
{
_assemblyInstaller.Rollback(state);
}
catch { }
throw;
}
}
public bool IsServiceInstalled()
{
try
{
ServiceControllerStatus status = _serviceController.Status;
}
catch
{
return false;
}
return true;
}
}
然而,目前我们所有的服务都使用相同的 MyWindowsServiceInstaller
,但分别复制到每个项目中.为了解决这个问题,我打算将该类移动到具有一些其他功能的公共程序集(并移除该类与 Program
的耦合),但我不确定是否可以使用 安装程序
在另一个程序集中.
However, at the moment all of our services use the same MyWindowsServiceInstaller
but copied into each project separately. To resolve this I was going to move that class to a common assembly with some other functionality (and remove the coupling of the class with Program
) but I'm not sure if it's possible to have the Installer
in another assembly.
这可能吗?如果是这样,我该怎么做?
Is this possible? If so how do I go about it?
我想我的方法的另一个问题是用于创建 ServiceHandler
的 typeof(Program).Assembly
调用,但我不确定.
I imagine another problem with my approach is the typeof(Program).Assembly
call to create the ServiceHandler
but I'm not sure.
推荐答案
Installer 查看程序集并寻找 [RunInstaller(true)] 属性.只认为您应该这样做:标记安装程序女巫是您的安装程序类.将继承的空类放入主程序集中.
Installer looks into the assembly and looking for [RunInstaller(true)] attribute. Only think you should do: Mark for installer witch is your installer class. Put an inherited empty class into your main assembly.
公共程序集:
//[RunInstaller(true)] <<-- REMOVE this
public class MyWindowsServiceInstaller : Installer
{
public MyWindowsServiceInstaller(){
ServiceProcessInstaller processInstaller = new
ServiceProcessInstaller();
ServiceInstaller serviceInstaller = new ServiceInstaller();
processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.DisplayName = Program.ServiceDetails.Name;
serviceInstaller.Description = Program.ServiceDetails.Description;
//Must be the same as what was set in Program's constructor
serviceInstaller.ServiceName = Program.ServiceDetails.Name;
Installers.Add(processInstaller);
Installers.Add(serviceInstaller);
}
}
主要装配
[RunInstaller(true)] // <<-- put it here
public class ProjectInstaller : MyWindowsServiceInstaller { }
这篇关于Service Installer 类可以在不同的程序集中运行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!