【问题标题】:Multiple Instances of same Application as a Windows Service?同一应用程序的多个实例作为 Windows 服务?
【发布时间】:2009-09-02 22:45:29
【问题描述】:

我有一个应用程序管理我的项目的繁重处理,需要将其转换为“Windows 服务”。我需要允许运行应用程序处理的多个 versions 实例,这似乎是一个相当正常的要求。

我可以看到至少三种方法可以做到这一点:

  1. 创建单个安装目录(EXE、DLL、配置),但作为多个 Services 实例安装。
  2. 让单个 Services 实例在启动后生成多个自身实例,例如 Apache。
  3. 让单个 Services 实例产生多个在同一进程空间中工作的线程。

我的意图是方法#1,但我一直在克服限制,无论是在设计方面,尤其是在服务的文档方面:

  • 参数曾经是否通过无人值守系统上的正常服务机制传递给OnStart()?如果是,何时/为什么?
  • 通过 ImageKey 注册表传递运行时参数似乎很麻烦,有没有更好的机制?
  • 我让应用程序安装/卸载自己作为一对服务(“XYZ #1”,“XYZ #2”,...),使用 ImageKey 给它一个命令行参数实例编号(“-x 1”,“-x 2”),但我遗漏了一些东西。尝试启动该服务时,它会失败并显示“此服务配置为在其中运行的可执行程序没有实现该服务

所以,问题:

  1. 是否有关于服务启动时发生的情况的简明描述,特别是对于那些 ServiceName 没有硬编码的情况(参见上面的 Q)。
  2. 有没有人成功使用方法#1?有cmets吗?

注意:我已经通过使用方法 #3 绕过了这个问题,所以我无法证明花太多时间来解决这个问题。但我认为有人可能有关于如何实施 #1 的信息——或者说它不是一个好主意的充分理由。

[编辑]我最初有第 4 个选项(在硬盘驱动器上安装应用程序的多个副本),但我删除了它,因为它只是感觉,嗯,hackish .这就是为什么我说“至少三种方法”。

但是,除非重新编译应用程序,否则它必须动态设置其 ServiceName,因此可以解决上述第三个项目符号/问题。因此,除非实例需要更改它的安装文件,否则#1 应该可以正常使用目录中的 N 个配置文件和指示实例应该使用哪个注册表项。

【问题讨论】:

    标签: c# windows-services


    【解决方案1】:

    虽然我无法回答您针对选项 #1 的具体问题,但我可以告诉您选项 #2 对我们非常有效。我们想为每个“子”服务创建一个应用程序域以在其下运行,并为每个服务使用不同的配置文件。在我们服务的配置文件中,我们存储了要启动的应用程序域和要使用的配置文件。因此,对于每个条目,我们只需创建应用程序域,设置配置文件等,然后我们就走了。这种配置分离使我们能够轻松地为每个实例唯一地指定端口和日志文件位置。对我们的额外好处是,我们将“子服务”编写为命令行 exe,并在每个“子”服务的新线程上简单地调用 AppDomain 的 ExecuteAssembly()。解决方案中唯一的“麻烦”是关闭,我们没有费心为其创建一个“好的”解决方案。

    2012 年 2 月更新

    前段时间我们开始使用“命名”服务(如 SQL Server)。我在我的博客“构建 Windows 服务 – Part 1Part 7”系列中详细介绍了整个过程。他们将带您完成创建一个命令行/Windows 服务混合并完成自我安装的过程。实现了以下目标:

    • 构建一个也可以从控制台使用的服务
    • 服务启动/关闭和其他活动的正确事件记录
    • 使用命令行参数允许多个实例
    • 自行安装服务和事件日志
    • 服务异常和错误的正确事件记录
    • 控制启动、关闭和重启选项
    • 处理自定义服务命令、电源和会话事件
    • 自定义服务安全和访问控制

    完整的 Visual Studio 项目模板在系列的最后一篇文章Building a Windows Service – Part 7: Finishing touches 中提供。

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 这就是“多次安装应用”的解决方案。
      【解决方案3】:

      我在项目中成功使用了选项 #4,即“命名实例”。

      您的应用的每次安装都有自定义名称,并且每次安装都有自己的服务。它们完全独立,彼此隔离。如果您尝试在单台计算机上多次安装 MS SQL Server,则会使用此模型。

      【讨论】:

      • 实际上,这不仅仅是添加 Service 实例,而是添加每个具有不同 ServiceName 的 installations。但是由于这种方法解决了我遇到的“动态设置 ServiceName”问题,这意味着可以完成 #1。但是,在我看来,#1 会更容易(如果仅适用于最终用户)——只需安装一次文件/包,然后从中安装多个服务。 假设实例不需要安装目录中的文件有很大差异
      • 我知道,但您说您需要更多服务,因为您的应用程序可能有多个版本。为什么通过将所有版本转储到单个文件夹中来使事情变得复杂。如果您假设您的所有版本将来都将与您的单个安装目录中的内容兼容,那么请继续,但在软件开发中假设某些东西是危险的,除非它基于一些坚实的数学基础,而这不是: )
      • 抱歉让您感到困惑,我打错字了:我的意思是 相同版本的多个 instance,而不是我最初所说的“多个版本” .安装的版本永远不会超过一个。
      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      相关资源
      最近更新 更多