构建我的类库后,我的bin/Debug目录中有几个.dll(有些来自我自己的项目,而另一些来自第三方库(。例如
MyLibrary.dll
Newtonsoft.Json.dll
NLog.dll
我想重命名这些程序集,以便它们包含其版本号。例如
MyLibrary-1.0.0.0.dll
Newtonsoft.Json-10.0.3.0.dll
NLog-2.0.0.0.dll
最好的方法是什么?我不能只是重命名文件。我需要更改程序集名称本身,并将这些更改传播到依赖于它们的任何内容。
到目前为止,我已经找到了以下解决方案(见 https://stackoverflow.com/a/21753873/1383366(:
ildasm /all /out=MyLibrary.il MyLibrary.dll
ilasm /dll /out=MyLibrary-1.0.0.0.dll MyLibrary.il
我不仅不确定这是否足以正确更改程序集名称,而且我不知道传播名称更改的最佳方法。
我认为在用它们编译项目后重命名引用不是一个好主意,并且不确定为什么您认为需要这样做。这可能表明这是其他问题(XY问题?(的解决方案。也许更好的数据包管理器会有所帮助 - Paket?
无论如何,您可以使用 Mono.Ceccil 重命名引用。
一个快速而肮脏的例子如下:
string fileName = args[0];
string path = Path.GetDirectoryName(fileName);
var program = AssemblyDefinition.ReadAssembly(fileName);
foreach (var reference in program.Modules[0].AssemblyReferences)
{
var referenceFile = Path.Combine(path, reference.Name+".dll");
if (!File.Exists(referenceFile)) continue;
var assemblyReference = AssemblyDefinition.ReadAssembly(referenceFile);
var newReferenceName = $"{Path.GetFileNameWithoutExtension(referenceFile)}-{assemblyReference.Name.Version}";
var newReferenceFile = Path.Combine(path, $"{newReferenceName}{Path.GetExtension(referenceFile)}");
var assembly = assemblyReference.MainModule.Assembly;
assembly.MainModule.Name = Path.GetFileName(newReferenceFile);
assemblyReference.Write(newReferenceFile);
}
program.Write(Path.Combine(path, "rewritten.exe"));
我们所做的只是重命名文件名 - 添加一个版本并更改每个程序集指向磁盘的名称。保留与主程序集相同的文件夹的所有重命名,以仅包含本地引用。
在一个小例子上测试了一个项目引用和NuGet
(NLog
,Newtonsoft.Json
在你的例子中(,它在重写后工作,但请记住,它只是处理直接引用并进入引用的引用,如果存在,你需要扩展此示例以满足您的需求。