2013-10-03 3 views
0

У меня проблема, когда у меня есть WPF UserControls, и у меня есть DLL, где этот UserControl находится в разных версиях, загруженных в сборку, UserControl больше не может найти свои ресурсы. (Может быть, потому, что они есть с тем же именем, но в разных версиях DLL версий). Любой знает, как это исправить?WPF - используйте разные версии DLL с UserControls

ответ

0

Я нашел способ самостоятельно, изменив метод «IntializeComponent» в DLL. Это создает URI, который затем загружает XAML. Проблема в том, что в URI версия не включена! Поэтому я создал небольшое приложение, которое я вызываю после процесса компиляции, который модифицирует DLL, чтобы он включал версию String! Для этого он использует Mono.Cecil ...

Вот код:

class Program 
{ 
    static void Main(string[] args) 
    {    
     var path = Environment.CurrentDirectory; 

     if (args != null && args.Count() > 0) 
      path = args[0]; 

     var dlls = Directory.GetFiles(path, "*.dll"); 

     foreach (var dll in dlls) 
     { 
      bool dllChanged = false; 

      var ver = AssemblyName.GetAssemblyName(dll).Version; 
      var nm = AssemblyName.GetAssemblyName(dll).Name; 
      var oldTxt = "/" + nm + ";"; 
      var newTxt = "/" + nm + ";v" + ver.ToString() + ";"; 

      var readerParameters = new ReaderParameters {ReadSymbols = true}; 
      var assemblyDefinition = AssemblyDefinition.ReadAssembly(dll, readerParameters); 

      var methodDefinition = 
       assemblyDefinition.MainModule.Types.SelectMany(x => x.Methods) 
        .Where(x => x.Name == "InitializeComponent"); 

      foreach (var def in methodDefinition) 
      { 
       for (int n = 0; n < def.Body.Instructions.Count; n++) 
       { 
        var instr = def.Body.Instructions[n]; 

        if (instr.OpCode == OpCodes.Ldstr && instr.Operand is string && 
         ((string) instr.Operand).StartsWith(oldTxt)) 
        { 
         var next = def.Body.Instructions[n + 1]; 

         if (next.OpCode == OpCodes.Ldc_I4_2) 
         { 
          var op = ((string) instr.Operand); 
          op = op.Replace(oldTxt, newTxt); 
          instr.Operand = op; 

          dllChanged = true; 
         } 
        } 
       } 
      } 

      if (dllChanged) 
      { 
       var writerParameters = new WriterParameters {WriteSymbols = true}; 
       assemblyDefinition.Write(dll, writerParameters); 
      } 
     } 
    } 
} 
Смежные вопросы