ApplicationBase外部的PrivateBinPath

时间:2013-07-02 22:03:11

标签: c# .net appdomain appdomainsetup

我的目录结构如下所示:

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

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

因此,SharedLib.dll ApplicationBase我要创建的AppDomain加载/Host Program Base/HostedLibs/SharedLib.dll,但它需要能够找到..

我已尝试将PrivateBinPath添加到AppDomain的{​​{1}},但根据MSDN

  

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

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

我还尝试将ApplicationBase设置为Host Program Base文件夹,并将HostedLibs添加为PrivateBinPath,但这会导致域无法解析{{ 1}}。

所以 - > 如何使用HostedLib.dll 解决ApplicationBase之外的库?

2 个答案:

答案 0 :(得分:1)

如果不重新组织您的应用程序结构,您可以使用AppDomain.AssemblyResolve event.

基本上是这样的。

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

答案 1 :(得分:0)

根据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;
    }
}