【问题标题】:PrivateBinPath outside ApplicationBaseApplicationBase 外的 PrivateBinPath
【发布时间】:2013-07-02 22:03:11
【问题描述】:

我的目录结构如下:

-- Host Program Base
  |- HostProgram.exe
  |- SharedLIB.dll
  |-- LoadedLibs
     |- HostedLib.dll

HostProgram.exe 正在尝试加载 HostedLib.dll,这取决于 SharedLib.dll

因此,SharedLib.dllApplicationBase 用于我正在创建以加载它的/Host Program Base/HostedLibs/,但它需要能够找到SharedLib.dll

我曾尝试将.. 添加到PrivateBinPathAppDomain 但根据MSDN

私有程序集部署在与应用程序相同的目录结构中。如果为 PrivateBinPath 指定的目录不在 ApplicationBase 下,则它们将被忽略。

由于PrivateBinPath 不在ApplicationBase 内,而是上一级目录,因此它不在ApplicationBase 内,因此被忽略。因此,在尝试将 DLL 加载到新的 AppDomain 时,我得到了一个 AssemblyResolveException

我还尝试将ApplicationBase 设置为Host Program Base 文件夹并将HostedLibs 添加为PrivateBinPath,但这会导致域根本无法解析HostedLib.dll

所以 -> 如何使用 AppDomainSetup 解析 ApplicationBase 之外的库

【问题讨论】:

  • 我不明白这个问题。将 ApplicationBase 保留在 EXE 目录下,将 PrivateBinPath 设为子目录。
  • 具有依赖关系的 DLL 文件位于子文件夹“HostedLibs”中。因此,ApplicationBase 必须是“HostedLibs”。 @HansPassant
  • 这就是重点,我不知道你为什么认为这是必要的。你至少试过了吗?
  • @HansPassant 是的,我已经尝试过了。当 ApplicationBase 设置为一个目录且 PrivateBinPath 设置为“LoadedLibs”时,尝试加载 HostedLib.dll 时出现未解决的错误
  • 这是一个 XY 问题。 Y 不起作用,我们不知道可能导致 X 的原因。重新提出问题并正确记录 X。贴一个代码 sn -p 和你从 Fuslogvw.exe 得到的失败的绑定日志

标签: c# .net appdomain appdomainsetup


【解决方案1】:

没有重新组织你的应用程序结构,你可以使用AppDomain.AssemblyResolve event.

基本上是这样工作的。

  1. 订阅 AppDomain 上的 AssemblyResolve 事件。
  2. 当事件触发时,您可以专门查找您的 SharedLib.dll 或简单地尝试在给定 ResolveEventArgs.Name 中指定的程序集名称的情况下在根文件夹中创建所需程序集的完整路径并使用 Assembly.LoadFrom(path)
  3. 如果程序集从路径加载成功,则返回AssemblyResolve handler,否则返回null

【讨论】:

    【解决方案2】:

    根据 Jim 的回答实施的解决方案:

    internal static class Program
    {
        static Program()
        {
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve;
        }
    
        private static void Main()
        {
            //Do your stuff
        }
    
        private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
        {
            try
            {
                AssemblyName name = new AssemblyName(args.Name);
    
                string expectedFileName = name.Name + ".dll";
                string rootDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    
                return LoadAssembly(rootDir, expectedFileName, "", "Dlls", "../Dlls");
            }
            catch
            {
                return null;
            }
        }
    
        private static Assembly LoadAssembly(string rootDir, string fileName, params string[] directories)
        {
            foreach (string directory in directories)
            {
                string path = Path.Combine(rootDir, directory, fileName);
                if (File.Exists(path))
                    return Assembly.LoadFrom(path);
            }
            return null;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 2021-10-06
      相关资源
      最近更新 更多