7

is it possible to tell if an assembly has changed?

I have a standard project that generates an assembly called MyAssembly.dll.

In a separate project i read the assembly and generate a hash.

When i generate a hash for the assembly it is different each time i recompile. I have set the assembly version to be static, are there any other attributes that i need to change?

class Program
{
    static void Main(string[] args)
    {
        var array = File.ReadAllBytes(@"MyAssembly.dll");
        SHA256Managed algo = new SHA256Managed();
        var hash = algo.ComputeHash(array);

        Console.WriteLine(Convert.ToBase64String(hash));
    }
}

Thanks

Rohan

Rohan West
  • 9,262
  • 3
  • 37
  • 64

6 Answers6

8

Every assembly has a ModuleVersionId GUID that works like a hash. If you change a single character, module id changes, but if you revert it you get the old id back. It's useful for comparing two versions of an assembly.

var assembly = Assembly.GetEntryAssembly();
var hashId = assembly.ManifestModule.ModuleVersionId;
Console.WriteLine(hashId);
40744db8-a8fe-4591-9b2c-d9e3e04a2f0a

https://learn.microsoft.com/en-us/dotnet/api/system.reflection.module.moduleversionid?view=net-5.0

abdusco
  • 9,700
  • 2
  • 27
  • 44
  • Why If using Blazor Webassembly this GUID change every time even If I did not change any code? – Andrea Rossi Jul 13 '22 at 09:24
  • 1
    @AndreaRossi Blazor files are translated to C# code (check out `obj` folder), which might include some non-deterministic comments for metadata (like a timestamp). This could explain why it keeps changing – abdusco Jul 13 '22 at 10:06
  • I understeand. There is any workaround for this? I'm a little bit confused about this: Assembly.GetExecutingAssembly().GetHashCode().ToString() always comes back the same hash (in my case '335105251') even If I rebuild and change something on code. – Andrea Rossi Jul 13 '22 at 14:18
  • GetHashCode is something else entirely. It has nothing to do with the assembly contents / file hash. You need to read assembly.ManifestModule.ModuleVersionId – abdusco Jul 13 '22 at 18:15
6

You are probably going to need to use the version number attribute. A hash will not work because any time you recompile an assembly, it's going to be different -- even if the code didn't change at all. The reason is that every time you compile, the compiler embeds a guid into the assembly, and it puts the same guid into the corresponding .pdb file. The guid will change every time the assembly is compiled.

This is how the debugger matches an assembly to the correct version of its .pdb file (it's also why you have to always save the .pdb's on anything you release, and you cannot rely upon being able to generate a pdb to match an existing assembly)

JMarsch
  • 21,484
  • 15
  • 77
  • 125
2

You could store the hash in a text file after it is generated, then check against it the next time you recompile.

1

Well, if it's an assembly you manage yourself I would suggest adding a versionnumber and auto-increase the version number each time you build that assembly.

Then you can check on versionnumber instead.

Community
  • 1
  • 1
Stormenet
  • 25,926
  • 9
  • 53
  • 65
  • The version number is the right way to check if an assembly has changed, is compatible – Peter Gfader Jun 30 '09 at 11:20
  • It is, but it could be the dll is from an external source that doesn't maintain it's versionnumbers (shame on them!). – Stormenet Jun 30 '09 at 12:12
  • Incrementing the version each time a build takes place wont tell me if the code has changed. Want i really want to do is check after a recomplie if an assembly has changed. I dont want to do selective build or create custom build scripts to only build projects that have changed. – Rohan West Jul 01 '09 at 04:59
1

This project seems to do the trick by disassembling each file and dropping the MVID GUID along with a few other bits before generating an MD5 hash. It has a dependency on ildasm.exe.

wolfyuk
  • 746
  • 1
  • 8
  • 26
0

At the moment its not trivial indeed - however - I have raised two tickets for .net platform itself, and also for ilSpy - to my best understanding those are best candidates where particular functionality could be implemented in future.

If you want to see alternatives of how it could be implemented at the moment, see ticket description.

Providing now here both links:

TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62