After building my class library, I have several .dlls in my bin/Debug directory (some are from my own project while others are from third-party libraries). For example,
MyLibrary.dll
Newtonsoft.Json.dll
NLog.dll
I would like to rename these assemblies so that they include their version number. For example,
MyLibrary-1.0.0.0.dll
Newtonsoft.Json-10.0.3.0.dll
NLog-2.0.0.0.dll
What's the best way to do this? I can't just rename the files. I need to change the assembly names themselves, and propagate those changes to whatever depends on them.
So far, I've found the following solution (see https://stackoverflow.com/a/21753873/1383366):
ildasm /all /out=MyLibrary.il MyLibrary.dll
ilasm /dll /out=MyLibrary-1.0.0.0.dll MyLibrary.il
I'm not just not sure whether this is enough to properly change the assembly name, and I don't know the best way to propagate the name change.
I don't think it's a good idea to rename references after your project is compiled with them and not sure why you think this is needed to do. It might indicate that this is a solution to some other problem (XY problem?). Maybe a better packet manager would help - Paket?
Anyway, you can rename references using Mono.Cecil.
A quick & dirty example how you could do it is the following:
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"));
What we are doing is just renaming the filenames - adding a version and changing the name where each assembly is pointing to the disk. Keeping all the renaming with the same folder as you main assembly to include only local references.
Tested on a small example with a project reference and NuGet
(NLog
, Newtonsoft.Json
as in your example) and it worked after the rewrite but keep in mind that it's just dealing with direct references and going into the references of references, if such exists, you would need to extend this example to your needs.