mscorlib(4.0.0.0) API with additions
FileVersionInfo.cs
1 using Microsoft.Win32;
3 using System.IO;
6 using System.Text;
7 
8 namespace System.Diagnostics
9 {
11  [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
12  public sealed class FileVersionInfo
13  {
14  private string fileName;
15 
16  private string companyName;
17 
18  private string fileDescription;
19 
20  private string fileVersion;
21 
22  private string internalName;
23 
24  private string legalCopyright;
25 
26  private string originalFilename;
27 
28  private string productName;
29 
30  private string productVersion;
31 
32  private string comments;
33 
34  private string legalTrademarks;
35 
36  private string privateBuild;
37 
38  private string specialBuild;
39 
40  private string language;
41 
42  private int fileMajor;
43 
44  private int fileMinor;
45 
46  private int fileBuild;
47 
48  private int filePrivate;
49 
50  private int productMajor;
51 
52  private int productMinor;
53 
54  private int productBuild;
55 
56  private int productPrivate;
57 
58  private int fileFlags;
59 
62  public string Comments => comments;
63 
66  public string CompanyName => companyName;
67 
70  public int FileBuildPart => fileBuild;
71 
74  public string FileDescription => fileDescription;
75 
78  public int FileMajorPart => fileMajor;
79 
82  public int FileMinorPart => fileMinor;
83 
86  public string FileName
87  {
88  get
89  {
90  new FileIOPermission(FileIOPermissionAccess.PathDiscovery, fileName).Demand();
91  return fileName;
92  }
93  }
94 
97  public int FilePrivatePart => filePrivate;
98 
101  public string FileVersion => fileVersion;
102 
105  public string InternalName => internalName;
106 
110  public bool IsDebug => (fileFlags & 1) != 0;
111 
115  public bool IsPatched => (fileFlags & 4) != 0;
116 
120  public bool IsPrivateBuild => (fileFlags & 8) != 0;
121 
125  public bool IsPreRelease => (fileFlags & 2) != 0;
126 
130  public bool IsSpecialBuild => (fileFlags & 0x20) != 0;
131 
134  public string Language => language;
135 
138  public string LegalCopyright => legalCopyright;
139 
142  public string LegalTrademarks => legalTrademarks;
143 
146  public string OriginalFilename => originalFilename;
147 
150  public string PrivateBuild => privateBuild;
151 
154  public int ProductBuildPart => productBuild;
155 
158  public int ProductMajorPart => productMajor;
159 
162  public int ProductMinorPart => productMinor;
163 
166  public string ProductName => productName;
167 
170  public int ProductPrivatePart => productPrivate;
171 
174  public string ProductVersion => productVersion;
175 
178  public string SpecialBuild => specialBuild;
179 
180  private FileVersionInfo(string fileName)
181  {
182  this.fileName = fileName;
183  }
184 
185  private static string ConvertTo8DigitHex(int value)
186  {
187  string text = Convert.ToString(value, 16);
188  text = text.ToUpper(CultureInfo.InvariantCulture);
189  if (text.Length == 8)
190  {
191  return text;
192  }
193  StringBuilder stringBuilder = new StringBuilder(8);
194  for (int i = text.Length; i < 8; i++)
195  {
196  stringBuilder.Append("0");
197  }
198  stringBuilder.Append(text);
199  return stringBuilder.ToString();
200  }
201 
202  private static Microsoft.Win32.NativeMethods.VS_FIXEDFILEINFO GetFixedFileInfo(IntPtr memPtr)
203  {
204  IntPtr lplpBuffer = IntPtr.Zero;
205  if (Microsoft.Win32.UnsafeNativeMethods.VerQueryValue(new HandleRef(null, memPtr), "\\", ref lplpBuffer, out int _))
206  {
207  Microsoft.Win32.NativeMethods.VS_FIXEDFILEINFO vS_FIXEDFILEINFO = new Microsoft.Win32.NativeMethods.VS_FIXEDFILEINFO();
208  Marshal.PtrToStructure(lplpBuffer, (object)vS_FIXEDFILEINFO);
209  return vS_FIXEDFILEINFO;
210  }
211  return new Microsoft.Win32.NativeMethods.VS_FIXEDFILEINFO();
212  }
213 
214  private static string GetFileVersionLanguage(IntPtr memPtr)
215  {
216  int langID = GetVarEntry(memPtr) >> 16;
217  StringBuilder stringBuilder = new StringBuilder(256);
218  Microsoft.Win32.UnsafeNativeMethods.VerLanguageName(langID, stringBuilder, stringBuilder.Capacity);
219  return stringBuilder.ToString();
220  }
221 
222  private static string GetFileVersionString(IntPtr memPtr, string name)
223  {
224  string result = "";
225  IntPtr lplpBuffer = IntPtr.Zero;
226  if (Microsoft.Win32.UnsafeNativeMethods.VerQueryValue(new HandleRef(null, memPtr), name, ref lplpBuffer, out int _) && lplpBuffer != IntPtr.Zero)
227  {
228  result = Marshal.PtrToStringAuto(lplpBuffer);
229  }
230  return result;
231  }
232 
233  private static int GetVarEntry(IntPtr memPtr)
234  {
235  IntPtr lplpBuffer = IntPtr.Zero;
236  if (Microsoft.Win32.UnsafeNativeMethods.VerQueryValue(new HandleRef(null, memPtr), "\\VarFileInfo\\Translation", ref lplpBuffer, out int _))
237  {
238  return (Marshal.ReadInt16(lplpBuffer) << 16) + Marshal.ReadInt16((IntPtr)((long)lplpBuffer + 2));
239  }
240  return 67699940;
241  }
242 
243  private bool GetVersionInfoForCodePage(IntPtr memIntPtr, string codepage)
244  {
245  string format = "\\\\StringFileInfo\\\\{0}\\\\{1}";
246  companyName = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
247  {
248  codepage,
249  "CompanyName"
250  }));
251  fileDescription = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
252  {
253  codepage,
254  "FileDescription"
255  }));
256  fileVersion = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
257  {
258  codepage,
259  "FileVersion"
260  }));
261  internalName = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
262  {
263  codepage,
264  "InternalName"
265  }));
266  legalCopyright = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
267  {
268  codepage,
269  "LegalCopyright"
270  }));
271  originalFilename = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
272  {
273  codepage,
274  "OriginalFilename"
275  }));
276  productName = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
277  {
278  codepage,
279  "ProductName"
280  }));
281  productVersion = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
282  {
283  codepage,
284  "ProductVersion"
285  }));
286  comments = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
287  {
288  codepage,
289  "Comments"
290  }));
291  legalTrademarks = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
292  {
293  codepage,
294  "LegalTrademarks"
295  }));
296  privateBuild = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
297  {
298  codepage,
299  "PrivateBuild"
300  }));
301  specialBuild = GetFileVersionString(memIntPtr, string.Format(CultureInfo.InvariantCulture, format, new object[2]
302  {
303  codepage,
304  "SpecialBuild"
305  }));
306  language = GetFileVersionLanguage(memIntPtr);
307  Microsoft.Win32.NativeMethods.VS_FIXEDFILEINFO fixedFileInfo = GetFixedFileInfo(memIntPtr);
308  fileMajor = HIWORD(fixedFileInfo.dwFileVersionMS);
309  fileMinor = LOWORD(fixedFileInfo.dwFileVersionMS);
310  fileBuild = HIWORD(fixedFileInfo.dwFileVersionLS);
311  filePrivate = LOWORD(fixedFileInfo.dwFileVersionLS);
312  productMajor = HIWORD(fixedFileInfo.dwProductVersionMS);
313  productMinor = LOWORD(fixedFileInfo.dwProductVersionMS);
314  productBuild = HIWORD(fixedFileInfo.dwProductVersionLS);
315  productPrivate = LOWORD(fixedFileInfo.dwProductVersionLS);
316  fileFlags = fixedFileInfo.dwFileFlags;
317  return fileVersion != string.Empty;
318  }
319 
320  [FileIOPermission(SecurityAction.Assert, AllFiles = FileIOPermissionAccess.PathDiscovery)]
321  private static string GetFullPathWithAssert(string fileName)
322  {
323  return Path.GetFullPath(fileName);
324  }
325 
330  public unsafe static FileVersionInfo GetVersionInfo(string fileName)
331  {
332  if (!File.Exists(fileName))
333  {
334  string fullPathWithAssert = GetFullPathWithAssert(fileName);
335  new FileIOPermission(FileIOPermissionAccess.Read, fullPathWithAssert).Demand();
336  throw new FileNotFoundException(fileName);
337  }
338  int handle;
339  int fileVersionInfoSize = Microsoft.Win32.UnsafeNativeMethods.GetFileVersionInfoSize(fileName, out handle);
340  FileVersionInfo fileVersionInfo = new FileVersionInfo(fileName);
341  if (fileVersionInfoSize != 0)
342  {
343  byte[] array = new byte[fileVersionInfoSize];
344  byte[] array2 = array;
345  fixed (byte* value = array2)
346  {
347  IntPtr intPtr = new IntPtr(value);
348  if (Microsoft.Win32.UnsafeNativeMethods.GetFileVersionInfo(fileName, 0, fileVersionInfoSize, new HandleRef(null, intPtr)))
349  {
350  int varEntry = GetVarEntry(intPtr);
351  if (!fileVersionInfo.GetVersionInfoForCodePage(intPtr, ConvertTo8DigitHex(varEntry)))
352  {
353  int[] array3 = new int[3]
354  {
355  67699888,
356  67699940,
357  67698688
358  };
359  int[] array4 = array3;
360  foreach (int num in array4)
361  {
362  if (num != varEntry && fileVersionInfo.GetVersionInfoForCodePage(intPtr, ConvertTo8DigitHex(num)))
363  {
364  break;
365  }
366  }
367  }
368  }
369  }
370  }
371  return fileVersionInfo;
372  }
373 
374  private static int HIWORD(int dword)
375  {
376  return Microsoft.Win32.NativeMethods.Util.HIWORD(dword);
377  }
378 
379  private static int LOWORD(int dword)
380  {
381  return Microsoft.Win32.NativeMethods.Util.LOWORD(dword);
382  }
383 
388  public override string ToString()
389  {
390  StringBuilder stringBuilder = new StringBuilder(128);
391  string value = "\r\n";
392  stringBuilder.Append("File: ");
393  stringBuilder.Append(FileName);
394  stringBuilder.Append(value);
395  stringBuilder.Append("InternalName: ");
396  stringBuilder.Append(InternalName);
397  stringBuilder.Append(value);
398  stringBuilder.Append("OriginalFilename: ");
399  stringBuilder.Append(OriginalFilename);
400  stringBuilder.Append(value);
401  stringBuilder.Append("FileVersion: ");
402  stringBuilder.Append(FileVersion);
403  stringBuilder.Append(value);
404  stringBuilder.Append("FileDescription: ");
405  stringBuilder.Append(FileDescription);
406  stringBuilder.Append(value);
407  stringBuilder.Append("Product: ");
408  stringBuilder.Append(ProductName);
409  stringBuilder.Append(value);
410  stringBuilder.Append("ProductVersion: ");
411  stringBuilder.Append(ProductVersion);
412  stringBuilder.Append(value);
413  stringBuilder.Append("Debug: ");
414  stringBuilder.Append(IsDebug.ToString());
415  stringBuilder.Append(value);
416  stringBuilder.Append("Patched: ");
417  stringBuilder.Append(IsPatched.ToString());
418  stringBuilder.Append(value);
419  stringBuilder.Append("PreRelease: ");
420  stringBuilder.Append(IsPreRelease.ToString());
421  stringBuilder.Append(value);
422  stringBuilder.Append("PrivateBuild: ");
423  stringBuilder.Append(IsPrivateBuild.ToString());
424  stringBuilder.Append(value);
425  stringBuilder.Append("SpecialBuild: ");
426  stringBuilder.Append(IsSpecialBuild.ToString());
427  stringBuilder.Append(value);
428  stringBuilder.Append("Language: ");
429  stringBuilder.Append(Language);
430  stringBuilder.Append(value);
431  return stringBuilder.ToString();
432  }
433  }
434 }
Converts a base data type to another base data type.
Definition: Convert.cs:10
static CultureInfo InvariantCulture
Gets the T:System.Globalization.CultureInfo object that is culture-independent (invariant).
Definition: CultureInfo.cs:263
bool IsPreRelease
Gets a value that specifies whether the file is a development version, rather than a commercially rel...
string FileDescription
Gets the description of the file.
string InternalName
Gets the internal name of the file, if one exists.
FileIOPermissionAccess
Specifies the type of file access requested.
string FileName
Gets the name of the file that this instance of T:System.Diagnostics.FileVersionInfo describes.
static bool Exists(string path)
Determines whether the specified file exists.
Definition: File.cs:435
int ProductMajorPart
Gets the major part of the version number for the product this file is associated with.
unsafe override string ToString()
Converts the value of this instance to a T:System.String.
int ProductPrivatePart
Gets the private part number of the product this file is associated with.
string PrivateBuild
Gets information about a private version of the file.
Definition: __Canon.cs:3
Wraps a managed object holding a handle to a resource that is passed to unmanaged code using platform...
Definition: HandleRef.cs:5
string LegalCopyright
Gets all copyright notices that apply to the specified file.
string CompanyName
Gets the name of the company that produced the file.
int FileMinorPart
Gets the minor part of the version number of the file.
string LegalTrademarks
Gets the trademarks and registered trademarks that apply to the file.
string ProductVersion
Gets the version of the product this file is distributed with.
int FileMajorPart
Gets the major part of the version number.
string FileVersion
Gets the file version number.
SecurityAction
Specifies the security actions that can be performed using declarative security.
string OriginalFilename
Gets the name the file was created with.
StringBuilder Append(char value, int repeatCount)
Appends a specified number of copies of the string representation of a Unicode character to this inst...
int ProductBuildPart
Gets the build number of the product this file is associated with.
int FilePrivatePart
Gets the file private part number.
A platform-specific type that is used to represent a pointer or a handle.
Definition: IntPtr.cs:14
static string PtrToStringAuto(IntPtr ptr, int len)
Allocates a managed T:System.String and copies the specified number of characters from a string store...
Definition: Marshal.cs:123
static unsafe FileVersionInfo GetVersionInfo(string fileName)
Returns a T:System.Diagnostics.FileVersionInfo representing the version information associated with t...
string Language
Gets the default language string for the version info block.
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
static string GetFullPath(string path)
Returns the absolute path for the specified path string.
Definition: Path.cs:446
bool IsPatched
Gets a value that specifies whether the file has been modified and is not identical to the original s...
bool IsSpecialBuild
Gets a value that specifies whether the file is a special build.
Provides version information for a physical file on disk.
Represents a mutable string of characters. This class cannot be inherited.To browse the ....
void Demand()
Forces a T:System.Security.SecurityException at run time if all callers higher in the call stack have...
bool IsDebug
Gets a value that specifies whether the file contains debugging information or is compiled with debug...
The exception that is thrown when an attempt to access a file that does not exist on disk fails.
int Capacity
Gets or sets the maximum number of characters that can be contained in the memory allocated by the cu...
static void PtrToStructure(IntPtr ptr, object structure)
Marshals data from an unmanaged block of memory to a managed object.
Definition: Marshal.cs:1198
string Comments
Gets the comments associated with the file.
string ProductName
Gets the name of the product this file is distributed with.
string SpecialBuild
Gets the special build information for the file.
override string ToString()
Returns a partial list of properties in the T:System.Diagnostics.FileVersionInfo and their values.
static short ReadInt16([In] [MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
Reads a 16-bit signed integer at a given offset from unmanaged memory.
static string ToString(object value)
Converts the value of the specified object to its equivalent string representation.
Definition: Convert.cs:3793
int FileBuildPart
Gets the build number of the file.
Provides static methods for the creation, copying, deletion, moving, and opening of a single file,...
Definition: File.cs:14
Provides information about a specific culture (called a locale for unmanaged code development)....
Definition: CultureInfo.cs:16
Controls the ability to access files and folders. This class cannot be inherited.
bool IsPrivateBuild
Gets a value that specifies whether the file was built using standard release procedures.
int ProductMinorPart
Gets the minor part of the version number for the product the file is associated with.
Performs operations on T:System.String instances that contain file or directory path information....
Definition: Path.cs:13