Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
FileVersionInfo.cs
Go to the documentation of this file.
1using System.IO;
4using System.Text;
5
6namespace System.Diagnostics;
7
8public sealed class FileVersionInfo
9{
10 private readonly string _fileName;
11
12 private string _companyName;
13
14 private string _fileDescription;
15
16 private string _fileVersion;
17
18 private string _internalName;
19
20 private string _legalCopyright;
21
22 private string _originalFilename;
23
24 private string _productName;
25
26 private string _productVersion;
27
28 private string _comments;
29
30 private string _legalTrademarks;
31
32 private string _privateBuild;
33
34 private string _specialBuild;
35
36 private string _language;
37
38 private int _fileMajor;
39
40 private int _fileMinor;
41
42 private int _fileBuild;
43
44 private int _filePrivate;
45
46 private int _productMajor;
47
48 private int _productMinor;
49
50 private int _productBuild;
51
52 private int _productPrivate;
53
54 private bool _isDebug;
55
56 private bool _isPatched;
57
58 private bool _isPrivateBuild;
59
60 private bool _isPreRelease;
61
62 private bool _isSpecialBuild;
63
64 private static readonly uint[] s_fallbackLanguageCodePages = new uint[3] { 67699888u, 67699940u, 67698688u };
65
66 public string? Comments => _comments;
67
68 public string? CompanyName => _companyName;
69
71
73
75
77
78 public string FileName => _fileName;
79
81
82 public string? FileVersion => _fileVersion;
83
84 public string? InternalName => _internalName;
85
86 public bool IsDebug => _isDebug;
87
88 public bool IsPatched => _isPatched;
89
91
93
95
96 public string? Language => _language;
97
99
101
103
104 public string? PrivateBuild => _privateBuild;
105
107
109
111
112 public string? ProductName => _productName;
113
115
117
118 public string? SpecialBuild => _specialBuild;
119
120 public static FileVersionInfo GetVersionInfo(string fileName)
121 {
122 if (!Path.IsPathFullyQualified(fileName))
123 {
124 fileName = Path.GetFullPath(fileName);
125 }
126 if (!File.Exists(fileName))
127 {
128 throw new FileNotFoundException(fileName);
129 }
130 return new FileVersionInfo(fileName);
131 }
132
133 public override string ToString()
134 {
135 StringBuilder stringBuilder = new StringBuilder(512);
136 stringBuilder.Append("File: ").AppendLine(FileName);
137 stringBuilder.Append("InternalName: ").AppendLine(InternalName);
138 stringBuilder.Append("OriginalFilename: ").AppendLine(OriginalFilename);
139 stringBuilder.Append("FileVersion: ").AppendLine(FileVersion);
140 stringBuilder.Append("FileDescription: ").AppendLine(FileDescription);
141 stringBuilder.Append("Product: ").AppendLine(ProductName);
142 stringBuilder.Append("ProductVersion: ").AppendLine(ProductVersion);
143 stringBuilder.Append("Debug: ").AppendLine(IsDebug.ToString());
144 stringBuilder.Append("Patched: ").AppendLine(IsPatched.ToString());
145 stringBuilder.Append("PreRelease: ").AppendLine(IsPreRelease.ToString());
146 stringBuilder.Append("PrivateBuild: ").AppendLine(IsPrivateBuild.ToString());
147 stringBuilder.Append("SpecialBuild: ").AppendLine(IsSpecialBuild.ToString());
148 stringBuilder.Append("Language: ").AppendLine(Language);
149 return stringBuilder.ToString();
150 }
151
152 private unsafe FileVersionInfo(string fileName)
153 {
154 _fileName = fileName;
155 uint lpdwHandle;
156 uint fileVersionInfoSizeEx = global::Interop.Version.GetFileVersionInfoSizeEx(1u, _fileName, out lpdwHandle);
157 if (fileVersionInfoSizeEx == 0)
158 {
159 return;
160 }
161 byte[] array = new byte[fileVersionInfoSizeEx];
162 fixed (byte* value = &array[0])
163 {
164 IntPtr intPtr = new IntPtr(value);
165 if (!global::Interop.Version.GetFileVersionInfoEx(3u, _fileName, 0u, fileVersionInfoSizeEx, intPtr))
166 {
167 return;
168 }
169 uint varEntry = GetVarEntry(intPtr);
170 if (GetVersionInfoForCodePage(intPtr, ConvertTo8DigitHex(varEntry)))
171 {
172 return;
173 }
174 uint[] array2 = s_fallbackLanguageCodePages;
175 foreach (uint num in array2)
176 {
177 if (num != varEntry && GetVersionInfoForCodePage(intPtr, ConvertTo8DigitHex(num)))
178 {
179 break;
180 }
181 }
182 }
183 }
184
185 private static string ConvertTo8DigitHex(uint value)
186 {
187 return value.ToString("X8");
188 }
189
190 private static global::Interop.Version.VS_FIXEDFILEINFO GetFixedFileInfo(IntPtr memPtr)
191 {
192 IntPtr lplpBuffer = IntPtr.Zero;
193 if (global::Interop.Version.VerQueryValue(memPtr, "\\", out lplpBuffer, out var _))
194 {
195 return Marshal.PtrToStructure<global::Interop.Version.VS_FIXEDFILEINFO>(lplpBuffer);
196 }
197 return default(global::Interop.Version.VS_FIXEDFILEINFO);
198 }
199
200 private unsafe static string GetFileVersionLanguage(IntPtr memPtr)
201 {
202 uint wLang = GetVarEntry(memPtr) >> 16;
203 char* ptr = stackalloc char[256];
204 int length = global::Interop.Kernel32.VerLanguageName(wLang, ptr, 256u);
205 return new string(ptr, 0, length);
206 }
207
208 private static string GetFileVersionString(IntPtr memPtr, string name)
209 {
210 IntPtr lplpBuffer = IntPtr.Zero;
211 if (global::Interop.Version.VerQueryValue(memPtr, name, out lplpBuffer, out var _) && lplpBuffer != IntPtr.Zero)
212 {
213 return Marshal.PtrToStringUni(lplpBuffer);
214 }
215 return string.Empty;
216 }
217
218 private static uint GetVarEntry(IntPtr memPtr)
219 {
220 IntPtr lplpBuffer = IntPtr.Zero;
221 if (global::Interop.Version.VerQueryValue(memPtr, "\\VarFileInfo\\Translation", out lplpBuffer, out var _))
222 {
223 return (uint)((Marshal.ReadInt16(lplpBuffer) << 16) + Marshal.ReadInt16((IntPtr)((long)lplpBuffer + 2)));
224 }
225 return 67699940u;
226 }
227
228 private bool GetVersionInfoForCodePage(IntPtr memIntPtr, string codepage)
229 {
230 Span<char> span = stackalloc char[256];
231 IFormatProvider formatProvider = null;
232 IFormatProvider provider = formatProvider;
233 Span<char> span2 = span;
234 Span<char> initialBuffer = span2;
235 DefaultInterpolatedStringHandler handler = new DefaultInterpolatedStringHandler(31, 1, formatProvider, span2);
236 handler.AppendLiteral("\\\\StringFileInfo\\\\");
237 handler.AppendFormatted(codepage);
238 handler.AppendLiteral("\\\\CompanyName");
239 _companyName = GetFileVersionString(memIntPtr, string.Create(provider, initialBuffer, ref handler));
240 formatProvider = null;
241 IFormatProvider provider2 = formatProvider;
242 span2 = span;
243 Span<char> initialBuffer2 = span2;
244 DefaultInterpolatedStringHandler handler2 = new DefaultInterpolatedStringHandler(35, 1, formatProvider, span2);
245 handler2.AppendLiteral("\\\\StringFileInfo\\\\");
246 handler2.AppendFormatted(codepage);
247 handler2.AppendLiteral("\\\\FileDescription");
248 _fileDescription = GetFileVersionString(memIntPtr, string.Create(provider2, initialBuffer2, ref handler2));
249 formatProvider = null;
250 IFormatProvider provider3 = formatProvider;
251 span2 = span;
252 Span<char> initialBuffer3 = span2;
253 DefaultInterpolatedStringHandler handler3 = new DefaultInterpolatedStringHandler(31, 1, formatProvider, span2);
254 handler3.AppendLiteral("\\\\StringFileInfo\\\\");
255 handler3.AppendFormatted(codepage);
256 handler3.AppendLiteral("\\\\FileVersion");
257 _fileVersion = GetFileVersionString(memIntPtr, string.Create(provider3, initialBuffer3, ref handler3));
258 formatProvider = null;
259 IFormatProvider provider4 = formatProvider;
260 span2 = span;
261 Span<char> initialBuffer4 = span2;
262 DefaultInterpolatedStringHandler handler4 = new DefaultInterpolatedStringHandler(32, 1, formatProvider, span2);
263 handler4.AppendLiteral("\\\\StringFileInfo\\\\");
264 handler4.AppendFormatted(codepage);
265 handler4.AppendLiteral("\\\\InternalName");
266 _internalName = GetFileVersionString(memIntPtr, string.Create(provider4, initialBuffer4, ref handler4));
267 formatProvider = null;
268 IFormatProvider provider5 = formatProvider;
269 span2 = span;
270 Span<char> initialBuffer5 = span2;
271 DefaultInterpolatedStringHandler handler5 = new DefaultInterpolatedStringHandler(34, 1, formatProvider, span2);
272 handler5.AppendLiteral("\\\\StringFileInfo\\\\");
273 handler5.AppendFormatted(codepage);
274 handler5.AppendLiteral("\\\\LegalCopyright");
275 _legalCopyright = GetFileVersionString(memIntPtr, string.Create(provider5, initialBuffer5, ref handler5));
276 formatProvider = null;
277 IFormatProvider provider6 = formatProvider;
278 span2 = span;
279 Span<char> initialBuffer6 = span2;
280 DefaultInterpolatedStringHandler handler6 = new DefaultInterpolatedStringHandler(36, 1, formatProvider, span2);
281 handler6.AppendLiteral("\\\\StringFileInfo\\\\");
282 handler6.AppendFormatted(codepage);
283 handler6.AppendLiteral("\\\\OriginalFilename");
284 _originalFilename = GetFileVersionString(memIntPtr, string.Create(provider6, initialBuffer6, ref handler6));
285 formatProvider = null;
286 IFormatProvider provider7 = formatProvider;
287 span2 = span;
288 Span<char> initialBuffer7 = span2;
289 DefaultInterpolatedStringHandler handler7 = new DefaultInterpolatedStringHandler(31, 1, formatProvider, span2);
290 handler7.AppendLiteral("\\\\StringFileInfo\\\\");
291 handler7.AppendFormatted(codepage);
292 handler7.AppendLiteral("\\\\ProductName");
293 _productName = GetFileVersionString(memIntPtr, string.Create(provider7, initialBuffer7, ref handler7));
294 formatProvider = null;
295 IFormatProvider provider8 = formatProvider;
296 span2 = span;
297 Span<char> initialBuffer8 = span2;
298 DefaultInterpolatedStringHandler handler8 = new DefaultInterpolatedStringHandler(34, 1, formatProvider, span2);
299 handler8.AppendLiteral("\\\\StringFileInfo\\\\");
300 handler8.AppendFormatted(codepage);
301 handler8.AppendLiteral("\\\\ProductVersion");
302 _productVersion = GetFileVersionString(memIntPtr, string.Create(provider8, initialBuffer8, ref handler8));
303 formatProvider = null;
304 IFormatProvider provider9 = formatProvider;
305 span2 = span;
306 Span<char> initialBuffer9 = span2;
307 DefaultInterpolatedStringHandler handler9 = new DefaultInterpolatedStringHandler(28, 1, formatProvider, span2);
308 handler9.AppendLiteral("\\\\StringFileInfo\\\\");
309 handler9.AppendFormatted(codepage);
310 handler9.AppendLiteral("\\\\Comments");
311 _comments = GetFileVersionString(memIntPtr, string.Create(provider9, initialBuffer9, ref handler9));
312 formatProvider = null;
313 IFormatProvider provider10 = formatProvider;
314 span2 = span;
315 Span<char> initialBuffer10 = span2;
316 DefaultInterpolatedStringHandler handler10 = new DefaultInterpolatedStringHandler(35, 1, formatProvider, span2);
317 handler10.AppendLiteral("\\\\StringFileInfo\\\\");
318 handler10.AppendFormatted(codepage);
319 handler10.AppendLiteral("\\\\LegalTrademarks");
320 _legalTrademarks = GetFileVersionString(memIntPtr, string.Create(provider10, initialBuffer10, ref handler10));
321 formatProvider = null;
322 IFormatProvider provider11 = formatProvider;
323 span2 = span;
324 Span<char> initialBuffer11 = span2;
325 DefaultInterpolatedStringHandler handler11 = new DefaultInterpolatedStringHandler(32, 1, formatProvider, span2);
326 handler11.AppendLiteral("\\\\StringFileInfo\\\\");
327 handler11.AppendFormatted(codepage);
328 handler11.AppendLiteral("\\\\PrivateBuild");
329 _privateBuild = GetFileVersionString(memIntPtr, string.Create(provider11, initialBuffer11, ref handler11));
330 formatProvider = null;
331 IFormatProvider provider12 = formatProvider;
332 span2 = span;
333 Span<char> initialBuffer12 = span2;
334 DefaultInterpolatedStringHandler handler12 = new DefaultInterpolatedStringHandler(32, 1, formatProvider, span2);
335 handler12.AppendLiteral("\\\\StringFileInfo\\\\");
336 handler12.AppendFormatted(codepage);
337 handler12.AppendLiteral("\\\\SpecialBuild");
338 _specialBuild = GetFileVersionString(memIntPtr, string.Create(provider12, initialBuffer12, ref handler12));
340 global::Interop.Version.VS_FIXEDFILEINFO fixedFileInfo = GetFixedFileInfo(memIntPtr);
341 _fileMajor = (int)HIWORD(fixedFileInfo.dwFileVersionMS);
342 _fileMinor = (int)LOWORD(fixedFileInfo.dwFileVersionMS);
343 _fileBuild = (int)HIWORD(fixedFileInfo.dwFileVersionLS);
344 _filePrivate = (int)LOWORD(fixedFileInfo.dwFileVersionLS);
345 _productMajor = (int)HIWORD(fixedFileInfo.dwProductVersionMS);
346 _productMinor = (int)LOWORD(fixedFileInfo.dwProductVersionMS);
347 _productBuild = (int)HIWORD(fixedFileInfo.dwProductVersionLS);
348 _productPrivate = (int)LOWORD(fixedFileInfo.dwProductVersionLS);
349 _isDebug = (fixedFileInfo.dwFileFlags & 1) != 0;
350 _isPatched = (fixedFileInfo.dwFileFlags & 4) != 0;
351 _isPrivateBuild = (fixedFileInfo.dwFileFlags & 8) != 0;
352 _isPreRelease = (fixedFileInfo.dwFileFlags & 2) != 0;
353 _isSpecialBuild = (fixedFileInfo.dwFileFlags & 0x20) != 0;
354 return _fileVersion != string.Empty;
355 }
356
357 private static uint HIWORD(uint dword)
358 {
359 return (dword >> 16) & 0xFFFFu;
360 }
361
362 private static uint LOWORD(uint dword)
363 {
364 return dword & 0xFFFFu;
365 }
366}
static string GetFileVersionString(IntPtr memPtr, string name)
static unsafe string GetFileVersionLanguage(IntPtr memPtr)
static uint GetVarEntry(IntPtr memPtr)
static string ConvertTo8DigitHex(uint value)
static global::Interop.Version.VS_FIXEDFILEINFO GetFixedFileInfo(IntPtr memPtr)
static readonly uint[] s_fallbackLanguageCodePages
static FileVersionInfo GetVersionInfo(string fileName)
unsafe FileVersionInfo(string fileName)
bool GetVersionInfoForCodePage(IntPtr memIntPtr, string codepage)
static bool Exists([NotNullWhen(true)] string? path)
Definition File.cs:97
static string GetFullPath(string path)
Definition Path.cs:881
static bool IsPathFullyQualified(string path)
Definition Path.cs:264
static unsafe? string PtrToStringUni(IntPtr ptr)
Definition Marshal.cs:652
static short ReadInt16(object ptr, int ofs)
Definition Marshal.cs:54
static ? object PtrToStructure(IntPtr ptr, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors|DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type structureType)
Definition Marshal.cs:1164
override string ToString()
StringBuilder Append(char value, int repeatCount)
static readonly IntPtr Zero
Definition IntPtr.cs:18