You need to programmatically compare the version information of two executable modules. An executable module is a file that contains executable code such as an EXE or DLL file. The ability to compare the version information of two executable modules can be very useful to an application if it is trying to determine if it has all of the “right” pieces present to execute or when deciding on an assembly to dynamically load through reflection. This trick is also useful when an application is looking for the newest version of a file or DLL from many files or DLLs spread out in the local filesystem or on a network.
Use the
CompareFileVersions
method to compare executable
module version information. This method accepts two filenames,
including their paths, as parameters. The version information of each
module is retrieved and compared. This file returns a
FileComparison
enumeration, defined as follows:
public enum FileComparison { Error = 0, File1IsNewer = 1, File2IsNewer = 2, FilesAreSame = 3 }
The code for the CompareFileVersions
method is:
public FileComparison CompareFileVersions(string file1, string file2) { FileComparison retValue = FileComparison.Error; // do both files exist? if (!File.Exists(file1)) { Console.WriteLine(file1 + " does not exist"); } else if (!File.Exists(file2)) { Console.WriteLine(file2 + " does not exist"); } else { // get the version information FileVersionInfo file1Version = FileVersionInfo.GetVersionInfo(file1); FileVersionInfo file2Version = FileVersionInfo.GetVersionInfo(file2); // check major if (file1Version.FileMajorPart > file2Version.FileMajorPart) { Console.WriteLine(file1 + " is a newer version"); retValue = FileComparison.File1IsNewer; } else if (file1Version.FileMajorPart < file2Version.FileMajorPart) { Console.WriteLine(file2 + " is a newer version"); retValue = FileComparison.File2IsNewer; } else // major version is equal, check next... { // check minor if (file1Version.FileMinorPart > file2Version.FileMinorPart) { Console.WriteLine(file1 + " is a newer version"); retValue = FileComparison.File1IsNewer; } else if (file1Version.FileMinorPart < file2Version.FileMinorPart) { Console.WriteLine(file2 + " is a newer version"); retValue = FileComparison.File2IsNewer; } else // minor version is equal, check next... { // check build if (file1Version.FileBuildPart > file2Version.FileBuildPart) { Console.WriteLine(file1 + " is a newer version"); retValue = FileComparison.File1IsNewer; } else if (file1Version.FileBuildPart < file2Version.FileBuildPart) { Console.WriteLine(file2 + " is a newer version"); retValue = FileComparison.File2IsNewer; } else // build version is equal, check next... { // check private if (file1Version.FilePrivatePart > file2Version.FilePrivatePart) { Console.WriteLine(file1 + " is a newer version"); retValue = FileComparison.File1IsNewer; } else if (file1Version.FilePrivatePart < file2Version.FilePrivatePart) { Console.WriteLine(file2 + " is a newer version"); retValue = FileComparison.File2IsNewer; } else { // identical versions. Console.WriteLine("The files have the same version"); retValue = FileComparison.FilesAreSame; } } } } } return retValue; }
Not all executable modules have version information. If you load a
module with no version information using the
FileVersionInfo
class,
you will not throw an exception, nor will you get
null
back for the object reference. Instead, you
will get a valid FileVersionInfo
object with all
data members in their initial state (which is null
for .NET objects).
Assemblies actually have two sets of version information: the version
information available in the assembly manifest and the PE (Portable
Executable) file version information.
FileVersionInfo
reads the assembly manifest
version information.
The first action this method takes is to determine whether the two
files passed in to the file1
and
file2
parameters actually exist. If so,
the static
GetVersionInfo
method
is called on the FileVersionInfo
class with each
file passed in as a parameter.
The CompareFileVersions
method attempts to compare
each portion of the file’s version number using the
following properties of the FileVersionInfo
object
returned by GetVersionInfo
:
FileMajorPart
The first 2 bytes of the version number.
FileMinorPart
The second 2 bytes of the version number.
FileBuildPart
The third 2 bytes of the version number.
FilePrivatePart
The final 2 bytes of the version number.
The full version number is comprised of these four parts, making up an 8-byte number representing the file’s version number.
The CompareFileVersions
method first compares the
FileMajorPart
version information of the two
files. If these are equal, the FileMinorPart
version information of the two files is compared. This continues
through the FileBuildPart
and finally the
FilePrivatePart
version information values. If all
four parts are equal, the files are considered to have the same
version number. If a file is found to have a higher number than the
other file, that first file is considered to be of an earlier version
than the one with the higher number.