解决从另一个文件夹集引用 [英] Resolve assembly references from another folder

查看:144
本文介绍了解决从另一个文件夹集引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在开发的参考,并使用从某一个供应商的一些第三方组件的应用程序;在发展中我有这3个组件的参考文件夹在我的源代码树,我可以引用他们和构建应用程序,应用程序构建但不运行,因为整个服务器应用程序未安装,但这是好的。

在这里我想复制此自定义应用程序并运行所有程序集,我引用的文件夹类似服务器:

  D:\程序文件\ VendorName的\名称\支持\ API \ bin64适用
 

如果我复制我小的可执行文件夹中,然后运行它,它完美的作品,但如果我把我的.exe更合适的文件夹,就像我想要的:

  D:\程序文件\ MyCompanyName \ myProduct的\ BIN \ ...
 

这是行不通的,因为它不能解析的程序集。

我知道我可以使用探测中的app.config来指定文件夹中的exe文件必须寻找参考,但IMY情况下,组件是不是在一个子文件夹,更在一个完全不同的位置。

我不希望复制在我的应用程序文件夹中所有的供应商组件和我不能放在那里只有3的人,我引用,因为他们也装载其他组件和除非我有所有的人(很多... ...)这是行不通的。

我没有做什么特别的东西,而不是创建应用程序域,并通过反射不加载程序集,只想CLR解析引用,因为它们需要在应用程序启动或执行。

感谢。

编辑:这里的最终工作code

 静态System.Reflection.Assembly currentDomain_AssemblyResolve(对象发件人,ResolveEventArgs参数)
{
    记录仪记录仪=新记录仪();

    尝试
    {
        字符串RMSAssemblyFolder = ConfigurationManager.AppSettings [RMSAssemblyFolder];

        大会MyAssembly程序= NULL;
        字符串strTempAssmbPath =的String.Empty;

        装配objExecutingAssemblies = Assembly.GetExecutingAssembly();
        的AssemblyName [] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

        的AssemblyName myAssemblyName = Array.Find<的AssemblyName>(arrReferencedAssmbNames,A => a.Name == args.Name);

        如果(myAssemblyName!= NULL)
        {
            MyAssembly程序= Assembly.LoadFrom(myAssemblyName codeBase的。);
        }
        其他
        {
            strTempAssmbPath = Path.Combine(RMSAssemblyFolder,args.Name.Substring(0,args.Name.IndexOf(,))+的.dll);

            如果(!string.IsNullOrEmpty(strTempAssmbPath))
            {
                如果(File.Exists(strTempAssmbPath))
                {
                    logger.Information(大会负载:{0}  - 文件中发现:{1},args.Name,strTempAssmbPath);

                    //加载从指定路径的程序集。
                    MyAssembly程序= Assembly.LoadFrom(strTempAssmbPath);
                }
            }
        }

        //返回加载的程序集。
        返回MyAssembly程序;
    }
    赶上(例外EXC)
    {
        logger.Error(极好);
        返回null;
    }
}
 

解决方案

您应该先找到在哪里论文DLL安装然后使用该文件夹<一href="http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx"><$c$c>AppDomain.AssemblyResolve勾号决议,并尝试从这个文件夹加载所请求的组件。

它看起来像这样(没有测试过,你需要检查什么 args.Name 包含正好,可以包含与类型名称的版本和强名称):

  VAR otherCompanyDlls =新的DirectoryInfo(companyFolder).GetFiles(* DLL。);

AppDomain.CurrentDomain.AssemblyResolve + =(发件人,参数)=&GT;
{
    VAR DLL = otherCompanyDlls.FirstOrDefault(FI =&GT; fi.Name == args.Name);
    如果(DLL == NULL)
    {
        返回null;
    }

    返回的Assembly.Load(dll.FullName);
};
 

I am developing an application which references and uses some third party assemblies from a certain Vendor; in development box I have these 3 assemblies in a reference folder in my source tree and I can reference them and build the application, application builds but does not run because the whole server application is not installed, but this is fine.

On the server where I want to copy this custom application and run all assemblies I am referencing are in folder something like:

D:\ProgramFiles\VendorName\ProductName\Support\API\Bin64

and if I copy my small executable in that folder and run it, it works perfectly, but if I put my .exe in a more appropriate folder like I want:

D:\ProgramFiles\MyCompanyName\MyProduct\bin\...

it does not work because it cannot resolve those assemblies.

I know I can use probing in app.config to specify in which folders my exe has to look for references but imy case the assemblies are not in a subfolder, more in a completely different location.

I don't want to copy all vendor assemblies in my app folder and I cannot put there only the 3 ones I am referencing because they are also loading other assemblies and unless I have all of them (many...), it does not work.

I am not doing anything special, not creating app domains and not loading assemblies via reflection, just want the CLR to resolve the references as they are needed on application start or execution.

Thanks.

Edit: here the final working code

static System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    Logger logger = new Logger();

    try
    {
        string RMSAssemblyFolder = ConfigurationManager.AppSettings["RMSAssemblyFolder"];

        Assembly MyAssembly = null;
        string strTempAssmbPath = string.Empty;

        Assembly objExecutingAssemblies = Assembly.GetExecutingAssembly();
        AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

        AssemblyName myAssemblyName = Array.Find<AssemblyName>(arrReferencedAssmbNames, a => a.Name == args.Name);

        if (myAssemblyName != null)
        {
            MyAssembly = Assembly.LoadFrom(myAssemblyName.CodeBase);
        }
        else
        {
            strTempAssmbPath = Path.Combine(RMSAssemblyFolder, args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");

            if (!string.IsNullOrEmpty(strTempAssmbPath))
            {
                if (File.Exists(strTempAssmbPath))
                {
                    logger.Information("Assembly to load: {0} - File was found in: {1}", args.Name, strTempAssmbPath);

                    // Loads the assembly from the specified path.                  
                    MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
                }
            }
        }

        // Returns the loaded assembly.
        return MyAssembly;
    }
    catch (Exception exc)
    {
        logger.Error(exc);
        return null;
    }
}

解决方案

You should first find the folder where theses dlls are installed then use AppDomain.AssemblyResolve to hook assembly resolution and try to load the requested assemblies from this folder.

It will look something like this (not tested, and you need to check what args.Name contain exactly, could contain the version and the strong name along with type name) :

var otherCompanyDlls = new DirectoryInfo(companyFolder).GetFiles("*.dll");

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    var dll = otherCompanyDlls.FirstOrDefault(fi => fi.Name == args.Name);
    if (dll == null)
    {
        return null;
    }

    return Assembly.Load(dll.FullName);
};

这篇关于解决从另一个文件夹集引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆