Programmatically modify Assembly Binding
Asked Answered
M

2

6

I have an issue working with Microsoft.Build.BuildEngine which supposed to get fixed modifing my .exe.config file to add the following.

<?xml version ="1.0"?>
<configuration>
        <runtime>
           <assemblyBinding xmlns="urnchemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="3.5.0.0"/>
            </dependentAssembly>
                <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="3.5.0.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

My problem is, I can't modify the file, I have to fix it by code, and I think that's supposed to be possible, right?

But how?, how can I modify my application so it runs as if the above changes were made on the config file?

Marnamarne answered 8/12, 2009 at 20:7 Comment(2)
thanks David... please tell what you did to fix the correct formatting of the xmlMarnamarne
To format a block of code, you need a blank line before it, and then at least four spaces at the beginning of each line of code.Lan
L
12

I was just struggling with a similar problem. The key is to use the AppDomain.AssemblyResolve event. Here's what my code looks like:

    public void LoadStuff(string assemblyFile)
    {
        AppDomain.CurrentDomain.AssemblyResolve += 
            new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        var assembly = Assembly.LoadFrom(assemblyFile);

        // Now load a bunch of types from the assembly...
    }

    Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var name = new AssemblyName(args.Name);
        if (name.Name == "FooLibrary")
        {
            return typeof(FooClass).Assembly;
        }
        return null;
    }

This completely ignores the version number and substitutes the already loaded library for any library reference named "FooLibrary". You can use the other attributes of the AssemblyName class if you want to be more restrictive. FooClass can be any class in the FooLibrary assembly.

Lan answered 26/2, 2010 at 20:27 Comment(2)
This worked perfectly with MSTest running under TFS Build that does not pick up the config file.Curettage
I had some problems in debugger, where this event hit only for resource assemblies. In production works like a charm. Thanks!Akron
S
2

One way of doing it is to create a bootstrapping app which when launched would start your original app in a separate appdomain. When you set up the new domain you will be able to build the config file programmatically.

Sarchet answered 8/12, 2009 at 20:36 Comment(2)
what do you mean by writing the config file? I don't want to programmatically modify it, I want to run my app as if my config was already modified.Marnamarne
not modify - build. The content of the config file is one of the parameters you can pass to AppDomain.CreateDomain method (inside the AppDomainSetup instance). This way you can build it on the flySarchet

© 2022 - 2024 — McMap. All rights reserved.