开发者

Resolve assembly references from another folder

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"];

        As开发者_StackOverflow中文版sembly 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);
};


Use SN.exe : SN -T VendorAssembly.dll, this will return a hex number that is the public key token, then, reference the assembly from app.config. To get the version right click your vendor assembly and use that for the codeBase version value, the href=path you mentioned.

  <configuration>
       <runtime>
          <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
             <dependentAssembly>
                <assemblyIdentity name="VendorAssembly"  culture="neutral" publicKeyToken="307041694a995978"/>
                <codeBase version="1.1.1.1" href="FILE://D:/ProgramFiles/VendorName/ProductName/Support/API/Bin64/VendorAssembly.dll"/>
             </dependentAssembly>
          </assemblyBinding>
       </runtime>
    </configuration>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜