/// <summary> /// Helper function for retrieving a localized string resource via MUI. /// The function expects a string in the form: "@resource.dll, -123" /// /// "resource.dll" is a language-neutral portable executable (LNPE) file in /// the %windir%\system32 directory. The OS is queried to find the best-fit /// localized resource file for this LNPE (ex: %windir%\system32\en-us\resource.dll.mui). /// If a localized resource file exists, we LoadString resource ID "123" and /// return it to our caller. /// </summary> private static string TryGetLocalizedNameByMuiNativeResource(string resource) { if (string.IsNullOrEmpty(resource)) { return(string.Empty); } // parse "@tzres.dll, -100" // // filePath = "C:\Windows\System32\tzres.dll" // resourceId = -100 // string[] resources = resource.Split(','); if (resources.Length != 2) { return(string.Empty); } string filePath; int resourceId; // get the path to Windows\System32 string system32 = Environment.UnsafeGetFolderPath(Environment.SpecialFolder.System); // trim the string "@tzres.dll" => "tzres.dll" string tzresDll = resources[0].TrimStart('@'); try { filePath = Path.Combine(system32, tzresDll); } catch (ArgumentException) { // there were probably illegal characters in the path return(string.Empty); } if (!int.TryParse(resources[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out resourceId)) { return(string.Empty); } resourceId = -resourceId; try { StringBuilder fileMuiPath = StringBuilderCache.Acquire(Path.MaxPath); fileMuiPath.Length = Path.MaxPath; int fileMuiPathLength = Path.MaxPath; int languageLength = 0; long enumerator = 0; bool succeeded = UnsafeNativeMethods.GetFileMUIPath( Win32Native.MUI_PREFERRED_UI_LANGUAGES, filePath, null /* language */, ref languageLength, fileMuiPath, ref fileMuiPathLength, ref enumerator); if (!succeeded) { StringBuilderCache.Release(fileMuiPath); return(string.Empty); } return(TryGetLocalizedNameByNativeResource(StringBuilderCache.GetStringAndRelease(fileMuiPath), resourceId)); } catch (EntryPointNotFoundException) { return(string.Empty); } }