在c#中执行然后删除DLL

时间:2008-10-07 17:12:08

标签: mono appdomain self-updating

我正在创建一个自我更新的应用程序,其中我将大部分代码放在一个单独的DLL中。这是命令行,最终将在Mono上运行。我只是试图让这段代码在命令行的Windows上使用C#。

如何创建一个c#应用程序,我可以在运行时删除支持的dll?

AppDomain domain = AppDomain.CreateDomain("MyDomain");
ObjectHandle instance = domain.CreateInstance( "VersionUpdater.Core", "VersionUpdater.Core.VersionInfo");
object unwrap = instance.Unwrap();
Console.WriteLine(((ICommand)unwrap).Run());
AppDomain.Unload(domain);
Console.ReadLine();

在ReadLine中,VersionUpdater.Core.dll仍然被锁定而无法删除

ICommand接口位于VersionUpdater.Common.dll中,该命令行应用程序和VersionUpdater.Core.dll都引用了

4 个答案:

答案 0 :(得分:6)

我曾经管理类似的东西的唯一方法是将DLL放在一个单独的AppDomain中,然后尝试删除它。我卸载其他AppDomain,然后从磁盘中删除DLL。

如果您正在寻找一种方法来执行更新,那么我会选择一个存根exe来生成真正的AppDomain。然后,当该存根exe检测到要应用更新时,它将退出其他AppDomain,然后执行更新魔术。

编辑:更新程序无法与正在更新的事物共享DLL,否则它将锁定这些DLL,从而阻止它们被删除。我怀疑这就是你仍然得到例外的原因。更新程序必须是独立的,不依赖于其他AppDomain使用的任何内容,反之亦然。

答案 1 :(得分:1)

Unwrap会将对象类型的程序集加载到调用它的appdomain中。解决此问题的一种方法是在“基础”程序集中创建一个调用command.run的类型,然后将其加载到新的appdomain中。这样,您就不必从另一个程序集中的类型调用对象的解包,并且可以删除磁盘上的程序集。

答案 2 :(得分:1)

当我构建一个自我更新的应用程序时,我使用了存根的想法,但存根是应用程序本身。

应用程序将启动,查找更新。如果发现更新,它会将新应用程序的副本下载到临时存储,然后使用命令行选项启动它(System.Diagnostics.Process.Start()),该选项表示“您正在更新”。然后原来的exe退出。

生成的exe启动,发现它是一个更新,并将自身复制到原始的app目录。然后它从该新位置启动应用程序。然后产生的exe结束。

原始应用安装位置新启动的exe启动 - 查看临时文件并删除它。然后恢复正常执行。

答案 3 :(得分:1)

您可以随时使用MOVEFILE_DELAY_UNTIL_REBOOT在重新启动时删除。这很可能是最简单的hackey方式,通过hackey,我通常会看到类似的东西;加载新的DLL或注入explorer.exe甚至修补系统dll以加载到另一个进程等...

MoveFileEx From MSDN;

  

lpNewFileName [in, optional ]新的   上的文件或目录的名称   本地电脑。

     

移动文件时,目的地   可以在不同的文件系统或   体积。如果目的地已开启   另一个驱动器,你必须设置   dwFlags中的MOVEFILE_COPY_ALLOWED标志。

     

移动目录时,   目的地必须在同一个驱动器上。

     

如果dwFlags指定   MOVEFILE_DELAY_UNTIL_REBOOT和   lpNewFileName是 NULL MoveFileEx   注册lpExistingFileName文件   系统时删除   重新启动。如果lpExistingFileName引用   到一个目录,系统删除   只有在重启时才能重启目录   目录是空的。