2009-12-08 15 views
5

Ich habe ein Problem mit Microsoft.Build.BuildEngine zu arbeiten, die behoben werden soll, meine exe.config-Datei zu ändern, um Folgendes hinzuzufügen.Programmatically Modify Assembly Binding

<?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> 

Mein Problem ist, ich kann die Datei nicht ändern, ich habe es zu beheben, indem Code, und ich denke, das möglich sein soll, nicht wahr?

Aber wie? Wie kann ich meine Anwendung so ändern, dass sie so ausgeführt wird, als ob die obigen Änderungen in der Konfigurationsdatei vorgenommen würden?

+0

danke David ... bitte sagen Sie, was Sie getan haben, um die korrekte Formatierung des XML zu beheben – sebagomez

+0

Um einen Block Code zu formatieren, benötigen Sie eine leere Zeile davor und dann mindestens vier Leerzeichen am Anfang jeder Zeile von Code. –

Antwort

10

Ich hatte gerade mit einem ähnlichen Problem zu kämpfen. Der Schlüssel ist die Verwendung des Ereignisses AppDomain.AssemblyResolve. Hier ist, was mein Code wie folgt aussieht:

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

Diese vollständig die Anzahl Version ignoriert und ersetzt die bereits geladene Bibliothek für jede Bibliothek Referenz namens „FooLibrary“. Sie können die anderen Attribute der Klasse AssemblyName verwenden, wenn Sie restriktiver sein möchten. FooClass kann eine beliebige Klasse in der FooLibrary-Assembly sein.

+0

Dies funktionierte perfekt mit MSTest unter TFS Build ausgeführt, die die Konfigurationsdatei nicht abholen. –

+0

Ich hatte einige Probleme im Debugger, wo dieses Ereignis nur für Ressourcen-Assemblies traf. In der Produktion funktioniert wie ein Charme. Vielen Dank! –

2

Eine Möglichkeit besteht darin, eine Bootstrapping-App zu erstellen, die beim Start die ursprüngliche App in einer separaten Anwendungsdomäne startet. Wenn Sie die neue Domäne einrichten, können Sie die Konfigurationsdatei programmgesteuert erstellen.

+0

was meinst du mit dem schreiben der config-datei? Ich möchte es nicht programmgesteuert ändern, ich möchte meine App so ausführen, als wäre meine Konfiguration bereits geändert worden. – sebagomez

+2

nicht ändern - bauen. Der Inhalt der Konfigurationsdatei ist einer der Parameter, die Sie an die AppDomain.CreateDomain-Methode (innerhalb der AppDomainSetup-Instanz) übergeben können. Auf diese Weise können Sie es im laufenden Betrieb erstellen – mfeingold