I have the Problem, when I have WPF UserControls and I have the DLL where this UserControl is located in different Versions loaded into the Assembly, the UserControl could not find it's Resources any more. (Maybe because they are there with the same Name but in different Versioned DLLs) Any know how to fix it?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
I found a way myself, by changeing the "IntializeComponent" Method in the DLL. This Builds a URI, wich then loades the XAML. The Problem is, in the URI, the Version is not included! So I created a small App, wich I call after the compile Process, wich modifies the DLL so that the Version String it's included! For this, it's using Mono.Cecil...
Here is the code:
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);
}
}
}
}
回答2:
Similar to this: https://stackoverflow.com/a/26689750/195275
But the answer does not require changing IL code. You can pass /p:AssemblyVersion to the msbuild.
回答3:
I fixed it in SharpDevelop now this way: https://github.com/icsharpcode/SharpDevelop/commit/b3ea4a0efb7e3b8e083f8be40ea6f7e03ff44604