Recipe12.25.Comparing Version Information of Two Executable Modules


Recipe 12.25. Comparing Version Information of Two Executable Modules

Problem

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 in situations such as:

  • Trying to determine if it has all of the "right" pieces present to execute

  • Deciding on an assembly to dynamically load through reflection

  • Looking for the newest version of a file or .dll from many files spread out in the local filesystem or on a network

Solution

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 {     Same = 0,     Newer = 1, // File1 is newer than File2     Older = 2, // File1 is older than File2     Error = 3 } 

The code for the CompareFileVersions method is shown in Example 12-14.

Example 12-14. CompareFileVersions method

 public static 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.Newer;         }         else if (file1Version.FileMajorPart < file2Version.FileMajorPart)         {             Console.WriteLine(file2 + " is a newer version");             retValue = FileComparison.Older;         }         else // Major version is equal, check next…         {             // Check minor.             if (file1Version.FileMinorPart > file2Version.FileMinorPart)             {                 Console.WriteLine(file1 + " is a newer version");                 retValue = FileComparison.Newer;             }             else if (file1Version.FileMinorPart < file2Version.FileMinorPart)             {                 Console.WriteLine(file2 + " is a newer version");                 retValue = FileComparison.Older;             }             else // Minor version is equal, check next…             {                 // Check build.                 if (file1Version.FileBuildPart > file2Version.FileBuildPart)                 {                     Console.WriteLine(file1 + " is a newer version");                     retValue = FileComparison.Newer;                 }                 else if (file1Version.FileBuildPart < file2Version.FileBuildPart)                 {                     Console.WriteLine(file2 + " is a newer version");                     retValue = FileComparison.Older;                 }                 else // Build version is equal, check next…                 {                     // Check private.                     if (file1Version.FilePrivatePart >                           file2Version.FilePrivatePart)                     {                         Console.WriteLine(file1 + " is a newer version");                         retValue = FileComparison.Newer;                     }                     else if (file1Version.FilePrivatePart <                               file2Version.FilePrivatePart)                     {                         Console.WriteLine(file2 + " is a newer version");                         retValue = FileComparison.Older;                     }                     else                     {                         // Identical versions                         Console.WriteLine("The files have the same version");                         retValue = FileComparison.Same;                     }                 }             }         }     }     return retValue; } 

Discussion

Not all executable modules have version information. If you load a module with no version information using the FileVersionInfo class, you will not provoke 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 of the FileVersionInfo class is called to get version information for the two files.

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 either file is found to have a higher number than the other file, it is considered to be the latest version.

See Also

See the "FileVersionInfo Class" topic in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net