Question

If I create a .NET 3.5 application and apply the following post-build event:

if $(ConfigurationName) == Release
    "C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe"
    /allowDup:DotfuscatorAttribute
    /ndebug
    /closed
    /out:"$(TargetPath)"
    "$(TargetPath)"
    "$(TargetDir)HelloWorld.dll"

where "HelloWorld.dll" contains a single static class with a single static method, the checksum of the resultant executable will change on subsequent builds.

Why?

Was it helpful?

Solution

This is closely related to the CLI and the PE format.

ECMA CLI Specification states that each module within an assembly (module is just another unit in the infrastructure - as far as I know, for regular C# VS projects there is one module per assembly, but that can also be changed) contains a Module Version ID metadatum MVID, which is different for each build.

Section II.22.30 says

The Mvid should be newly generated for every module, using the algorithm specified in ISO/IEC 11578:1996 (Annex A) or another compatible algorithm.

Furthermore the Portable Executable format contains a series of headers, some of which contain different timestamps (linking, file creation etc.). I don't know much about the details of the format, but this huge article may help if you're curious - it's a bit older (19 years? Wow), but I suppose the fundamentals of the format are still the same.

Those are just two thing that I found in a couple of minutes, there are likely other factors (I've also read the built file may contain some data specific to the machine which it was built on), which you cannot affect when building a .NET assembly.


If you need a reliable way to identify your assembly, take a look at Strong-Named Assemblies and how to create them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top