我在C#中编写了一个Windows服务。一开始的要求是我应该只运行该服务的一个实例,但是已经改变了,现在我需要多个实例。这就是我需要根据配置文件更改服务名称的原因。
使用正确的名称注册的最佳方法是什么?我应该写另一个工具来做吗?我可以从App.config文件中读取名称并相应地在服务和安装程序类中设置它吗?
PS>我真的不明白名称是如何工作的 - 应该在服务和安装程序类中设置名称,但是当使用installutil.exe甚至PowerShell new-service进行安装时,也应该指定名称。那必须是一样的吗?或者一个覆盖另一个?
答案 0 :(得分:4)
您只需从app.config中读取它并在安装程序类中进行设置即可
通常,会自动创建一个继承自Installer
的类。它包含System.ServiceProcess.ServiceInstaller
类型的成员,很可能名为serviceProcessInstaller1
。这有一个你可以设置的属性ServiceName
。此外,您需要将ServiceBase
派生类的ServiceName
属性设置为相同的值
在默认实现中,这些在相应的InitializeComponent
方法中设置为常量值,但没有理由坚持这一点。它可以动态完成而不会出现问题。
答案 1 :(得分:2)
自从我遇到这个问题以来,我加了2美分。我有一个名为" ProjectInstaller.cs"拥有设计师和资源。在设计中打开它会将MyServiceInstaller和MyProjectInstaller显示为设计图面上的项目。我能够更改ProjectInstaller()
构造函数中的名称,并从模块目录手动加载配置文件:
public ProjectInstaller()
{
InitializeComponent();
var config = ConfigurationManager.OpenExeConfiguration(this.GetType().Assembly.Location);
if (config.AppSettings.Settings["ServiceName"] != null)
{
this.MyServiceInstaller.ServiceName = config.AppSettings.Settings["ServiceName"].Value;
}
if (config.AppSettings.Settings["DisplayName"] != null)
{
this.MyServiceInstaller.DisplayName = config.AppSettings.Settings["DisplayName"].Value;
}
}
答案 2 :(得分:0)
与Jason Goemaat的回答一样,这就是您如何遍历项目中所有可用的安装程序,这样可以节省您确保将每项新服务添加到此类的时间。在我的项目中,我总共有12个服务(我们在这里和那里添加一个新服务),我们希望它们按实例名称组合在一起,因此SVC(实例1)服务XX和SVC(实例1)服务YY在服务管理单元控制台中查看时,它们彼此相邻。
public ProjectInstaller()
{
InitializeComponent();
var config = ConfigurationManager.OpenExeConfiguration(this.GetType().Assembly.Location);
string instanceName = config.AppSettings.Settings["Installer_NamedInstanceName"].Value;
string instanceID = config.AppSettings.Settings["Installer_NamedInstanceID"].Value;
bool usesNamedInstance = !string.IsNullOrWhiteSpace(instanceName) && !string.IsNullOrWhiteSpace(instanceID);
if (usesNamedInstance)
{
foreach (var installer in this.Installers)
{
if (installer is ServiceInstaller)
{
var ins = (ServiceInstaller)installer;
ins.ServiceName = ins.ServiceName + "-" + instanceID;
// Want the service to be named SVC (Instance Name) Audit Log Blah Blah Service
ins.DisplayName = ins.DisplayName.Replace("SVC ", "SVC (" + instanceName + ") ");
}
}
}
}
HOWEVER ,您还需要做其他事情 - 初始化服务时,您还必须更改服务名称,否则您将收到“可执行文件”的错误不实施服务“。我是通过在Program.cs
中实现以下代码来实现此目的的:
internal static void HandleCustomServiceName(ServiceBase sbase)
{
if (!string.IsNullOrWhiteSpace(customInstanceName))
{
sbase.ServiceName = sbase.ServiceName + "-" + customInstanceName;
}
}
然后,在每个服务的构造函数中:
public SystemEventWatcher()
{
InitializeComponent();
Program.HandleCustomServiceName(this);
}
我赞成Jason的回答,为在我自己的项目中实现这一点铺平了道路。谢谢!