在.NET中按需下载和安装dll的最佳方法是什么?

时间:2009-04-06 18:26:52

标签: c#

我们有一个应用程序,我们希望只安装一个基本的shell。当用户使用它时,它将下载并安装必要的dll以执行需要执行的操作(想象一下具有多个可能路径的向导应用程序场景)。目前,通过shell应用程序为所有可能的路径安装了所有内容。

在一年中的大约3个月中,用于可能路径的dll会经历更高的流失率,因此我们希望开始确保用户拥有这些dll的最新版本。我们的想法是,在完成所有选择之后,我们会进行网络检查以查看选择所需的dll,并检查以确保它们具有这些文件的最新版本。

所有这一切我们都有一个如何做的计划。我正在解决的问题是什么是“安装”这些文件的最合适的方法。 ClickOnce不是一个选项......这里有太多传统的东西。我们的应用程序安装在“程序文件”中,显然有限制将随机文件写入Vista及更高版本的程序安装文件夹中。

现在我看到以下选项:

  1. 在安装时将安装目录标记为“Everyone”组可写。我还没有真正测试过看看它是否可行,或者Vista是否在这种情况下做了不同的事情。
  2. 将下载部分拆分为第二个应用程序,我们可以提示我们提升权限,以便下载并安装这些文件。
  3. 我倾向于第二个选项,因为它维护了Program Files文件夹的安全性方面。小组中的其他人倾向于第一种选择,因为他们只是不想担心事情。或者我还缺少其他选择吗?

    该应用程序是一个.NET应用程序,但它有一些非托管程序集的第三方dll的要求。

3 个答案:

答案 0 :(得分:1)

只要管理要加载的dll,就有几种方法可以执行此操作。

一种方法是指定一个Environment.SpecialFolder路径,例如AppData,并从那里动态地将程序集加载到您的appdomain中。 RssBandit为插件执行此操作,有一个特殊的目录可以加载dll并搜索特定的接口实现,将它们加载到临时appdomain中,然后从应用程序中调用它们。您可以通过使用ninjectstructuremap等IoC库来更进一步。

你也可以尝试MEF,C#4中出现了新的可扩展性框架。

答案 1 :(得分:1)

就个人而言,我喜欢Firefox / xul应用程序的功能。我想,这是你提出的两个解决方案的混合体。他们有一个updater.exe,它位于安装目录中。我认为这意味着安装目录在安装期间可写,以便它们可以运行更新应用程序。但是,从未以这种方式部署过应用程序,我无法告诉你它有多少令人头痛(或不是)。

您没有提及,也可能不知道的替代方案是使用.Net下载缓存。当您尝试加载程序集时,可以为其加载代码库。如果您将代码库设置为网址(即http://mywebhost/mycoolapp/)。。Net将从该网址下载该程序集(如果在下载缓存中找不到该程序集)。它还将从web url中获取最新版本的程序集(如果有的话)。

如果您的应用需要提升权限,则可能需要处理CAS安全问题,这种方法可能很麻烦。但是,不必编写代码来为您下载最新版本的程序集。如果您想了解更多信息,我可以找到一些资源并提供更详细的示例。

答案 2 :(得分:0)

我处理它的方法是将update.exe安装到主.exe文件旁边的程序文件中。

然后,在应用启动时,我让应用程序从Web下载xml文件并将其保存在App Data文件夹中。此文件包含最新版本的dll,并具有简单的文件名,版本结构。

运行文件名列表,如果您没有本地dll或者您有旧版本,请将所需的dll添加到更新列表。

生成更新列表后。使用要更新的文件的命令行列表触发Updater.exe。您不必将它们写入程序文件,但我确实如此。在Vista上,我的更新程序正确弹出UAC提示符(因为它应该保持Program Files的安全性)。

更新程序然后将文件下载到Program Files并重新启动主应用程序。

触发第二个应用程序的一个问题是你必须在其中设置一个带有“AsAdministrator”的清单。

这并不难,但是一旦更新程序完成并重新触发主应用程序,它就无法以正常权限启动主应用程序。以管理员身份运行的exe只能以管理员身份启动其他exe,即使在清单中设置了“AsInvoker”也是如此。我不知道为什么你不能将它限制回正常权利......你只能出于某种原因提升权限......