1

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

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

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

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

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

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

WebService 对象构造函数现在需要设置其 ServiceName 属性,并使用Windows 服务如何确定其 ServiceName?尝试找到正确的名称。但是,此时正确的 servicename 的 processid 仍然是 0。

在此之后,Main 将构建一个包含 (1) ServiceBase 的数组,其中包含 WebService 对象,并在该数组上调用 ServiceBase.Run。此时服务名称需要正确,因为一旦服务运行,它可能不会更改。

4

1 回答 1

0

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

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

链接的问题显示有一种简单的方法可以在每次启动时将命令行参数传递给服务,方法是覆盖 Installer 类的 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 路径)和参数之间。

于 2012-08-08T10:13:58.780 回答