Service Installer 类可以在不同的程序集中运行吗? [英] Can the Service Installer class run in a different Assembly?

查看:17
本文介绍了Service Installer 类可以在不同的程序集中运行吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义安装程序类,用于安装我的 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?

我想我的方法的另一个问题是用于创建 ServiceHandlertypeof(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 类可以在不同的程序集中运行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆