我有几个使用某个.dll文件运行的游戏服务器。 有时我需要更新游戏服务器,但是我不想中断已经运行的游戏。
有没有一种方法可以替代.dll文件(它被Windowslocking),所以使用该文件的游戏服务器的下一个实例将打开新的版本,旧的版本会继续使用旧版本的.dll,直到它们重新启动?
使用其中一种工具解锁文件并replace它是否安全?
其实,你可以和它通常没有任何问题(虽然不总是)
你所做的是重命名文件而不移动它,并将新文件移动到其上。 这将使文件的句柄保持有效并正常工作,以便预先存在的实例仍然能够正确访问文件,并且新实例(或新句柄)将转到新文件。
很显然,如果一个程序重新打开相同的dll文件,并希望它保持完全相同(例如,如果有资源要从DLL加载,并引用这些资源是从代码运行时提取的DLL加载),这会引起问题,但这绝对不是常态。
不可以。即使在应用程序运行时DLL 可能完全映射到物理内存中,但这绝对不能保证。 DLL的一些部分(甚至是可执行文件)可以映射到RAM中,而其他位则保留在磁盘上,并可以在以后读入。
当Windows有一部分映射到RAM中时,更改磁盘上的文件不会很好。 Windowslocking它有一个很好的理由。
编辑:我需要澄清的东西,因为有些人似乎意图责怪Windows实际上是应用程序devise问题,而不是操作系统devise问题。
您可以更新应用程序在Windows中使用的DLL,而无需终止进程,但是应用程序必须以可以用信号通知来卸载程序集,等待更新完成,然后重新加载DLL的方式编写。 这与您正在运行的操作系统无关。 这是一个应用程序devise问题。
编辑:另请参阅Stephane的解决scheme可能的工作,具体取决于您的具体应用程序如何响应其DLL的变化。 我认为他值得赞赏。
不,你不应该修改现有的文件句柄。
如果您可以控制程序集的加载,并指定使用FileShare.Delete打开它,则应该可以对其进行重命名。 现有的stream程将继续引用重命名的程序集。
https://stackoverflow.com/questions/7147577/programmatically-rename-open-file-on-windows 。
不,不幸的是,这是不可能的。
对不起,除非有后期绑定,这意味着应用程序使用该DLL时,运行该DLL中的代码的一部分,但它仍然是不可靠的。
你可以看看asp.net托pipe过程如何工作,并开发类似的东西。
它需要整个Web应用程序,并将其移动到实际加载应用程序的临时位置。 然后,它会保留一个进程来监视原始文件夹中的更改,如果检测到该更改,则会在新的临时位置中将该应用程序的新实例加速,并开始将新请求redirect到该应用程序。 一旦挂起的请求完成,旧的应用程序将被删除。
(Nitpicking,是的,这是一个简化的事情,在大多数情况下IIS排队的请求,直到新的应用程序能够接pipe)
大约十年前,我是一个幸福的用户http://www.eggcentric.com/ISAPILoader.htm哪些活IIS ISAPI DLL交换。 Egg先生仍然支持他的FOSS解决scheme。
NSIS安装程序有一个选项:移动到机器重新启动时,OS标记某个文件在下一次启动时移动到不同的位置,在下次机器启动时,这些标记的文件自动移动到您之前select的新位置。 在这方面进行一点search会让你高兴。