如何在服务可执行文件启动期间找到我的服务名称



我想部署一个提供Web服务的exe,并且能够多次启动它(每次作为单独的Windows服务)。exe 的每个实例都需要能够加载不同的配置文件(例如,以便它可以侦听不同的端口,或使用不同的数据库)。

理想情况下,我不想在多个文件夹中安装 exe,只需有多个配置文件即可。

但是,似乎没有办法找到Windows正在启动的服务名称。

我看过Windows 服务如何确定其服务名称?但它似乎对我不起作用,因为在启动期间,正在启动的服务的进程 ID 为 0。

我想我问得太早了什么。我的代码执行以下操作:

Main 设置当前目录并构造一个 WebService 对象(ServiceBase 的一个子类)

WebService 对象构造函数现在需要设置其 ServiceName 属性,并使用 Windows 服务如何确定其 ServiceName?中的代码来尝试查找正确的名称。但是,此时正确服务名称的进程 ID 仍为 0。

在此之后,Main 将构建一个包含 WebService 对象的 (1) ServiceBase 数组,并在该数组上调用 ServiceBase.Run。此时,服务名称必须正确,因为服务运行后可能无法更改。

在阅读 https://stackoverflow.com/a/7981644/862344 后,我找到了实现目标的替代方法

在安装 Web 服务期间,安装程序(恰好是同一个程序,但命令行参数为"install")知道要使用哪个设置文件(因为有一个命令行参数"settings=")。

链接的问题显示了一种简单的方法,可以通过重写安装程序类的 OnBeforeInstall(和 OnBeforeUninstall)方法,在每次启动时将该命令行参数传递给服务。

protected override void OnBeforeInstall(System.Collections.IDictionary savedState) {
    if (HasCommandParameter("settings")) {
        // NB: Framework will surround this value with quotes when storing in registry
        Context.Parameters["assemblypath"] += "" "settings=" + CommandParameter("settings");
    }
    base.OnBeforeInstall(savedState);
}
protected override void OnBeforeUninstall(System.Collections.IDictionary savedState) {
    if (HasCommandParameter("settings")) {
        // NB: Framework will surround this value with quotes when storing in registry
        Context.Parameters["assemblypath"] += "" "settings=" + CommandParameter("settings");
    }
    base.OnBeforeUninstall(savedState);
}

我发现框架中的某些内容在将 Context.Parameters["assemblypath"] 值存储在注册表中之前用引号括起来(在 HKLM\System\CurrentControlSet\Services\\ImagePath),因此有必要在现有值(即 exe 路径)和参数之间添加 '" "'。

最新更新