【问题标题】:Can I tell my application to load all assemblies (DLLs) from a specific location?我可以告诉我的应用程序从特定位置加载所有程序集 (DLL) 吗?
【发布时间】:2013-07-12 17:17:43
【问题描述】:

我的应用程序使用了第三方 SDK,该 SDK 安装在每台装有我的应用程序的机器上,我不想在我的应用程序部署中添加这些 SDK DLL,因为这会占用大量空间。由于其他原因,无法在 GAC 中注册 DLL。无论如何,有没有办法告诉我的应用程序所需的 DLL 在特定路径上可用?

【问题讨论】:

  • 你看过这个吗? support.microsoft.com/kb/837908 config 选项看起来有点吸引人。
  • 在多 TB 磁盘时代,DLL 占用“大量空间”的概念很奇怪。当然,它们在另一个目录中仍然占用相同数量的空间。
  • @HansPassant 该应用程序是使用 ClickOnce 部署的,在我的情况下,45 MB 的 DLL 是一个问题。我知道这不是一个真正的问题,但 ClickOnce 保留了所有部署版本的副本,并且每个版本都会有这 45 MB .. 有点困扰我..
  • 另外,这个SDK是用于指纹识别的,它默认安装在我处理的每台机器上,为什么我必须用应用程序再次部署它们..这是重点@HansPassant

标签: c# .net assemblies


【解决方案1】:

过去我们曾在 asp.net 应用程序中使用探测路径来做类似的事情:

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

在 asp.net 中有一个副作用,当应用程序运行时,这些位置的程序集不会自动加载,只有在 bin 中找不到它们时才会自动加载。

【讨论】:

  • 您没有想过在静态构造函数中添加对这些程序集的调用吗?
  • 这是用于第三方组件的可选功能,.net sdk 依赖于正在安装的 COM sdk,如果不存在则抛出一个 wobbler,因此我们不需要加载程序集,除非我们知道我们可以。授予不同的场景,但应该在这里工作。
  • +1。顺便说一句,这种副作用听起来与通常加载程序集的方式没有任何不同。 (程序的二进制目录只是搜索程序集的多个位置中的一个;但是在某些情况下,它可能是第一个搜索的。)另请参阅this SO answer 和从那里链接到的 MSDN 页面以了解有关程序集加载的详细信息过程。
【解决方案2】:

是的,共享文件(如果出于某种原因您不想将它们放在 GAC 中)可以部署在例如 Common Programs 文件夹中。

根据您的应用程序的工作方式,您可能需要使用从 Environment.GetSpecialFolder() 获得的路径(用于 Environment.SpecialFolders.CommonPrograms 或附加和事件处理程序以用于 AppDomain.AssemblyResolve 事件)使用 Assembly.LoadFrom() 显式加载它们。

让我们看一个原始而简单的例子:

// Put this in your initialization code
public static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveAssembly(MyResolveEventHandler);
}

private static Assembly ResolveAssembly(object sender, ResolveEventArgs e)
{
    // Clean, check, double check and verify path name to be sure it's a valid
    // assembly name and it's not a relative path itself, you may even check e.RequestingAssembly
    string path = ...; 

    return Assembly.LoadFrom(path);
}

如果你有目录并且你想在启动时加载它们(以防万一......):

private static LoadThemAll(folderPath)
{
    foreach (var path in Directory.GetFiles(folderPath, "*.dll"))
        Assembly.LoadFrom(path);
}

不要忘记添加适当的错误处理(对于非托管 DLL,可能会发生错误版本和其他所有情况,尤其是因为该程序集将加载到您的 AppDomain 中,并且每个人都可能在该文件夹中放置恶意程序集)。

当然,所有这些都可以应用于任何(可访问的)文件夹,哪个是最好的...这取决于您要加载的内容以及它的部署方式(您甚至可以在注册表中动态搜索找到支持文件的位置)。

最后,如果您引用的程序集是强签名的,并且它们位于已知、固定、不可变的位置,您可以在 .config 文件中使用 <codebase>

【讨论】:

    猜你喜欢
    • 2012-01-23
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    相关资源
    最近更新 更多