【问题标题】:Why am I able to rename a Windows Service executable while it is running?为什么我可以在运行时重命名 Windows 服务可执行文件?
【发布时间】:2017-03-17 07:44:54
【问题描述】:

我有一个使用托管语言 (.NET Framework v4.0) 编写的 Windows 服务,该服务当前正在运行。

由于某种原因,我可以在服务运行时重命名服务主可执行文件。 我怀疑该文件在服务运行时被 Windows 锁定,但事实并非如此。 更有趣的是,重命名后它仍然存在于任务管理器中。

我没有抱怨这是可能的,但我想知道为什么。有人对此有解释吗?

【问题讨论】:

  • Windows 服务没有什么特别之处,特别是。见this SuperUser question
  • 功能,不是错误。操作系统会锁定文件数据,而不是目录条目。这是在程序运行时为程序安装更新的基本方式。
  • 在服务重新启动之前,它不会获取新的可执行映像。依赖此机制的更新过程很容易出现不一致,如果它们无法执行服务控制命令(例如由于缺少权限) - 并且系统最终处于文件是新文件但服务正在运行的状态一张老照片未被注意到。然后突然,当服务器重新启动时,更新中的功能更改或错误变得明显。不仅在生产环境中见过一次,而且从那以后就避免了。
  • 这个问题没有具体的 C#/.net 内容。试图回答它,但看到它作为题外话关闭并不感到惊讶,尽管在其他 SE 网站上重复 are not necessarily off-topic
  • @CeeMcSharpface 这正是发生在我身上的事情:成功安装了新版本的 Windows 服务,但安装程序无法停止当前正在运行的服务(顺便说一句,这是另一个 Windows 功能),最终运行旧版本而

标签: windows windows-services


【解决方案1】:

取自this answer on superuser, 和How can we overwrite EXE files while users are running them?,

可以重命名非独占锁定的可执行文件。 Windows 服务管理器获取服务可执行文件的文件句柄,只要服务运行,它就会保持打开状态,并且完全不受重命名的影响。它不会锁定目录条目本身。所以可执行文件可以被其他进程读取,文件的目录项可以重命名。

启示:

  • 重命名后,可以放置不同版本的文件。
  • 如果您或自动更新进程未能放置新版本,则指向该可执行文件的任何服务将无法在下次启动(重新启动/重新启动时)
  • 如果新版本出现问题,例如错误或缺少依赖项,服务可能会在下次启动失败(重启/重启时)
  • 如果您放置了新版本,但未能立即重新启动服务,那么它将在未来的任何时间变为活动状态,这与生产环境中的管理员(和用户)不同。

建议:

  • 不要依赖这种机制。让您的更新过程停止服务。当您的更新过程没有足够的权限时,更新失败。然后替换可执行文件和所有依赖项,并重新启动服务。

【讨论】:

    猜你喜欢
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    相关资源
    最近更新 更多