编译后如何正确重命名程序集?

How can I properly rename assemblies after they're been compiled?

构建我的 class 库后,我的 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

最好的方法是什么?我不能只重命名文件。我需要自己更改程序集名称,并将这些更改传播到依赖于它们的任何内容。

到目前为止,我找到了以下解决方案(参见 ):

ildasm /all /out=MyLibrary.il MyLibrary.dll
ilasm /dll /out=MyLibrary-1.0.0.0.dll MyLibrary.il

我不仅不确定这是否足以正确更改程序集名称,而且我不知道传播名称更改的最佳方式。

我认为在使用它们编译项目后重命名引用不是一个好主意,并且不确定您为什么认为需要这样做。它可能表明这是对其他一些问题的解决方案 (XY problem?). Maybe a better packet manager would help - Paket?

无论如何,您可以使用 Mono.Cecil 重命名引用。

下面是一个简单粗暴的示例:

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"));

我们正在做的只是重命名文件名——添加一个版本并更改每个程序集指向磁盘的名称。将所有重命名保留在与主程序集相同的文件夹中,以仅包含本地引用。

在一个带有项目参考和 NuGetNLogNewtonsoft.Json,如您的示例)的小示例上进行了测试,它在重写后有效,但请记住,它只是处理直接引用并进入引用的引用(如果存在),您需要扩展此示例以满足您的需要。