Win32 MUI Run-Time DiagnosticsThis FAQ is a compilation of answers about resource location and language settings for Multilingual Resource Languages (MUI) technology. This article also explains how to fix or work around various known MUI issues, and it contains background information on Win32 MUI run-time diagnostics concepts, MUI language settings, and an introduction to Satellite MUI files. On This Page Frequently Asked Questions
Remedial How-To Procedures
Win32 MUI Run-Time Diagnostics Background and Concepts
Frequently Asked Questions
 My Windows Vista-style application fails to start up properly or no UI appears. This seems to be MUI-related. Where do I start looking for the problem?
Confirm that .mui files and code binary are matched. See To confirm match of .mui files and code binary.
 My application only displays English (en-US). How can I get my application to display the language that I expect? Do I have to change the User UI Language?
Confirm that the .mui file in the language folder of the language you wish to display is placed properly and is matched with the code binary. See To confirm proper placement of .mui files and To confirm match of .mui files and code binary.
 How do I get my Windows Vista MUI application to work on down-level platforms?
MUI resource splitting is a new Windows Vista feature. Earlier versions of Windows do not know how to connect the code binary with the .mui file for resource location. As a result, the Windows Vista SDK ships with several APIs that make it possible for you to use Windows Vista-style binaries with pre-Windows Vista OS versions: After installing, be sure and confirm that .mui files are placed properly.
 Why can’t I get the MUI down-level APIs to find all my resources when run on a down-level platform? Everything works fine when run on Windows Vista.
Some of your resources may be considered non-localizable. A localizable Windows Vista resource will be found in the satellite .mui binary. Resources in the Windows Vista code binary are considered non-localizable. In the Windows Vista deployment scenario, the Windows Vista Resource Loader understands this difference and loads from either binary as appropriate. In the down-level scenario, using LoadMUILibrary will lock resource loading into one binary or the other (but not both). The only workaround for this scenario is to load the resources you know to be resident in the main binary (as you would do for Windows XP) and load the localizable resources using the LoadMUILibrary API. Alternately, some APIs in Windows Vista (such as GetFileVersionInfo) act upon pieces of a dual split resource. Specific resource types may contain both localizable and non-localizable information. For example, the version resource type can sometimes fit this pattern where much of the resource is obtained from the non-localizable code binary, but localizable parts (such as a string) are obtained from the .mui satellite file. When using LoadMUILibrary on a down-level OS, a single portable executable (PE) file will be searched. APIs that have knowledge in Windows Vista of .mui splitting will work differently. The only true workaround for this scenario is to formulate your own code that will appropriately load the pieces of the resources you need from each binary.
 The initial version of my MUI-enabled application works great when loading a specific resource in a specific language, but it breaks after it has been serviced. What went wrong?
In the event that resource changes were made to your application between its initial release and a subsequent update, it is possible that you have improperly serviced your application. This scenario occurs most often in applications that do not service all supported languages at the same time. Based on the current servicing model chosen for Windows Vista, all resource changes were disallowed after Windows Vista RTM by procedure. Now only resource additions are allowed. Depending on the type of resource being used, what might appear to be an addition (e.g., a new resource) is actually a resource change. This issue is most prevalent with RT_STRING types because of the internal format of how individual strings are stored together in groups (or blocks of 16) as a single resource. Additionally, any major changes of version or filename can break resource loading. During the build step, the PE file’s embedded major version and the OriginalFilename are used by the RC Compiler (and muirct.exe in post-build) to generate a checksum that validates that the main binaries and .mui binaries belong to each other (validation done at runtime). Resource-loading APIs allow resources to be loaded out of satellite .mui files only after this validation step is performed. Click here for more information about OriginalFilename or major version. The MSDN Version Information reference page describes other functions that help read and manipulate the data contained within the version resource. Potential workarounds - Add new localized resources to your application only when at least one language in the merged fallback list and the MUI_MERGE_SYSTEM_FALLBACK and MUI_USER_FALLBACK flag is guaranteed to have been serviced (e.g., replaced with the new one). Click here for more information on the merged fallback list.
- Adjust your chosen servicing model. Always ship every language supported by your component (Windows Vista has ~100 languages) and install every language the user has on their system.
- Always service all the main binaries and all .mui files.
 Why doesn’t my MUI application work when started from a sym link, but works fine from a shortcut or the actual executable file?
Symbolic links added to the Windows Vista kernel are not fully supported by the Resource Loader in Windows Vista RTM. Click here for mklink.exe. Therefore, it is possible that some types of symbolic links will not produce proper resource loads. This is issue is primarily related to scenarios where .mui files are not located directly at the location of the link. This issue will be fixed in a future release of Windows. Symbolic links work-around - Refrain from resource loading APIs and symbolic links until the release of Windows Vista SP1 or Windows Server 2008.
- Read the Symbolic links documentation to determine conditions where sym links will work with resource loading in Windows Vista RTM.
 Why can’t I load a custom resource that I added using UpdateResource APIs?
Traditionally and by convention, resource names and type strings have been capitalized in resource PE binaries. In Windows Vista, the UpdateResource API has a bug where it will allow mixed case to be assigned to a type (custom type) or name. When attempting to locate this resource, the Resource Loader converts the name of the string to uppercase and then cannot find the resource. This issue will be fixed in a future version of Windows. To avoid this issue, format custom resource types and names as uppercase when using UpdateResource.
 Why do some resources load correctly on X86 and AMD64 builds, but fail to load on IA64?
One issue encountered during application compatibility testing for Windows Vista is that resource sections of third-party applications can become misaligned prior to resource loading. Although X86 and AMD64 platforms are lenient when it comes to properly aligning memory (performance is apparently the only penalty), IA64 is more strict about misaligned memory and will not load the resources. To mitigate this problem, use the UpdateResource-related APIs (for non-split binaries only) or Microsoft-provided compilers (RC Compiler) to assure your resources are properly aligned. Click here for more information. Pay special attention to the internal structure of any custom resource. They can become misaligned, depending on how they are used. Click here for more information on alignment.
 Why does my application only receive version text in one language?
The version resource (type #16) is unique. Normally, it is required to be present in all Microsoft compiler-built applications. It is added by default to the code binary in the default language (normally English). Because the version resource contains some text that may be displayed to the user, the GetVersionInfo API was modified in Windows Vista to be able to get pieces of the version from both a localized type #16 present in the .mui file and the remaining data from the neutral type #16 in the code binary. Some component owners may wish to localize portions of the version resource, such as: - Copyright information
- Servicing information
To enable localization of version information
 How do I determine the proper language name for an LCID?
Although not strictly related to MUI, the LCID to Language Name mapping is widely used in MUI technology. To map language names appropriately
 How do I determine what language my .mui file is localized for?
Sometimes it is important to determine that you have the correct .mui file in the properly named folder. At runtime, the Resource Loader confirms that the .mui file is properly placed. If the file validation fails, the Resource Loader ignores the misplaced file. To confirm proper localization - Use muirct.exe and point it at the .mui file of interest. See To view MUI resource configuration settings for more information.
- Confirm that the Language field has the appropriate language name.
- Use the resource editor in Visual Studio (or comparable third-party application) to compare the contents of the resource section.
 What resources are in my .mui file and what ones are in the code binary?
Sometimes it is useful to confirm how resources are split between .mui and code binary PE files. To confirm how resources are split between .mui and code binary PE files - Copy the .mui file to its own folder.
Example c:\folder\mui_file\<PE filename>.mui - Copy the PE file to its own folder.
Example c:\ folder\pe_file\<PE filename> - Change the .mui file extension from .dll.mui to .mui.dll.
- Open both files in the Visual Studio (or similar) resource editor.
- Review the data in both files.
 Why can’t I get resources to load from a binary which has a long file path?
Resource Loader functionality currently has a limitation that .mui file paths cannot exceed the MAX_PATH variable (260 characters). This is scheduled to be fixed in a future version of Windows. For now, it is possible that a component can get into a situation where the main / code binary is able to load properly (with LoadLibrary/Ex), yet fail to load resources out of a satellite binary. This can occur because the code binary is located within a path/file name configuration that is too long. Two situations present the most likely scenarios. Although this string size varies based on the language name length being supported, a code binary file path length of 240 or more characters may encounter this situation. In a hypothetical Custom Locale resource loading scenario, it is possible that this issue can be encountered where the code binary file path length is MAX_PATH - LOCALE_NAME_MAX_LENGTH – 5 + 1 (or 171 characters). To avoid this situation, place all code binaries in configurations where the filename path length does not exceed 240 characters for Windows supported languages and 170 characters if your application is going to support custom locales.
 No matter what I do, my application only loads old resources. It will not reflect my newly adjusted resources. What is going wrong?
If you are properly adjusting your resources (see previous question), there are three primary possibilities: - You have a .local mui and/or PE file is in the directory where the application resides. This is a common Windows debugging feature that allows placement and first-chance loading of files named with the .local extension. If this situation applies to you, you will find a .local named .mui file in the directory where the application resides.
- Your binary is being managed by Side By Side (unlikely). Click here for more information.
- Various common Windows components are being added to the CMF (a system-wide MUI caching technology). As such, it is possible that the .mui file where resources are being loaded from is coming from the CMF rather than the actual .mui file that resides on disk (exceedingly unlikely). This is an OS feature and should be transparent to non-Windows components.
To determine if your resource is loading out of the CMF - Determine the file path associated with the loaded resource. Do this by using the handle retrieved from LoadResource and passing it to GetMappedFileName.
- If the file name contains %windir\rescache\*.cmf., your resource came from the CMF.
- If GetMappedFileName fails and LoadResource is successful, it is also possible that the resource came from the CMF.
- In either of these cases, please discuss the issue with your Microsoft contact.
 My application uses impersonation and the UI shows up in a different language than the current users’ environment. How can I fix the mixed UI?
When using impersonation, mixed UI language can occur for several reasons. In most cases, the primary reason relates to the fallback language list not being set properly. The most common fix is to have the impersonated thread use the SetThreadUILanguage or SetThreadPreferredUILanguages APIs (or) prior to any resource loading. A second reason may be that the system on which the impersonated thread is running lacks the appropriate language resources - .mui files are missing or were never installed. To fix this issue, install the appropriate .mui files. As a note, many services and server-type applications hit this scenario and have only a subset of all languages they will see when a client connects with its thread language settings. The norm is that a block of resource languages are known to be installed. When the thread language(s) are set, one of the languages known to be installed is always set. This way, the application’s preferences are kept (rather than OS preferences).
 I use common controls (e.g., comctl32.dll) in my application, but I can’t get them to display in the thread language that I set before loading the resource. What should I do?
This is caused by a current bug in Windows Vista that will be fixed in a future release of Windows. Currently, there is no known workaround for this issue other than not using common controls.
 How do I determine which language resources were loaded by the Resource Loader?
In some cases, applications must identify the language that the Resource Loader API found during resource discovery. To verify language resources loaded by the Resource Loader - Confirm that your version resource is being split and localized.
- Confirm that your split version resource has a localized field that will contain the language the .mui file was localized into.
- Use the GetFileVersionInfo API to obtain the file version.
- Use the VerQueryValue API to obtain the appropriate language-specific information about the binary being located.
To determine which language resources are loaded by Resource Loader (alternate procedure) - Add a dummy custom resource to the appropriate component or find a resource in the component that you are sure is in all .mui files.
- Call FindResource or FindResourceEx on the component, seeking the dummy resource.
- Use the GetModuleFileName function passing it the returned handle from FindResource/Ex to determine the file path of the .mui file.
- Parse the last folder name out of the file path. The last folder name represents the language found by the Resource Loader.
 I have a valid custom locale that is working and the language is being provisioned on the thread language list. However, Win32 resources are never loaded from the appropriate custom locale .mui file. What is wrong?
MUI support for custom locale can be erratic. This issue will be addressed in a future Windows release. For now, refrain from using custom locales and MUI Win32 resource loading.
 How do I get my command line application to not show ‘??’ characters in some OS language environments?
The most common cause of ?? characters in the command shell (cmd.exe) is due to the application attempting to display characters that cmd.exe is not configured to display or is unable to display. To configure your application to display correctly in the current console at run-time, use the SetThreadPreferredUILanguages API. Click here for more information on console filtering (see the Remarks section). Similar functionality is available in SetThreadUILanguage API for Windows XP.
 How can I get my driver to load resources in a different language than the OS installed language?
 What is the difference between run-time MUI technology for Windows Server 2008, Windows Vista, XP, Windows Server 2003, and Windows 2000?
Occasionally the MUI team is asked how the various versions of MUI support differ across Microsoft OS offerings. The table below highlights the primary differences and features provided in the past three Windows MUI offerings. Feature and/or Functionality Difference | Windows 2000 or Windows 2000 Server | Windows XP or Windows 2003 Server | Windows Vista or Windows 2008 Server | Can install any language pack on any language OS | | | l | Can install MUI package on en-US language OS only | l | l (some LIPs allowed on non-English) | | Uses .mui files for localization | l | l | l | .mui files stored in mui\<hex LCID> folder naming convention (e.g., mui\0C0A\) | l | l | | .mui files stored in <language name> folder naming convention (e.g., \fr-FR\) | | | l | Use of registry keys to confirm appropriate resource data | | l | | Use of additional resource type in code binary to confirm appropriate resource data (type MUI added) | | | l | Tools provided to third parties to accomplish MUI splitting | | | l | Maximum of four languages in.mui probing fallback list | l | l | | Maximum of eighteen languages in.mui probing fallback list | | | l | Centralized storage of .mui files for system | l | l | | Application-centric storage of .mui files | | | l | Language pack installation via MSI | l | l | | Language pack installation via Vista Installer | | | l | Language pack installation can be done offline | | | l | Language neutral concept added – bulk of resources located only in satellite .mui files | | | l | Fallback resource data (en-US) contained in code binary | l | l | l (drivers only) | Windows Language Interface Packs (LIP) available for all SKUs | Not supported | Windows Home, Windows Professional | All | MUI available per SKU | All | Windows XP Professional, all Windows Server versions | All Windows Server 2008 versions (except Home Server) |
 I pull strings out of the registry and display them in my application. How should I properly use the registry while retaining access to localized data?
This situation is addressed in RegLoadMUIString (new to Windows Vista API). Use this API to properly load UI strings from the registry.
 My application seems to be using an UltimateFallbackLanguage attribute and I don’t want it to do so. How does one adjust the ultimate fallback language in the language-neutral binary?
If you use the muirct.exe in your build process to do MUI splitting, click here for information on the UltimateFallbackLanguage attribute. If you use the RC compiler in your build process to do MUI splitting, click here for information on the UltimateFallbackLanguage attribute.
To confirm proper placement of .mui files- Determine that the.mui file (module.dll.mui) exists in the appropriate language named directories (e.g., en-US, fr-FR, ru-RU, ja-JP) within the directory where the code binary resides. Click here for more information on placing Win32 MUI resource files.
- Determine that at least one of the language named folders containing the .mui file is in the resource loading fallback list for your component.
- Strictly speaking, the correct way to determine this is to have your application dump out and display the result from GetThreadPreferredUILanguages when using the MUI_MERGE_SYSTEM_FALLBACK | MUI_MERGE_USER_FALLBACK flags.
- Use the latest Windows Vista !mui debugger extensions to dump out the fallback list. Install debugging tools for Windows 32-bit version, and then search for !mui in windbg’s help.
- Make sure the .mui file exists in the installed language folder. Use REGEDIT to determine the installed language to look at:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Language\InstallLanguage
This key will be in LCID form. Click here to view a mapping of LCID to language names. - Verify that the .mui file exists in the user language folder. Click here to determine the selected user language.
To confirm match of .mui files and code binary- Dump out the MUI resource configuration info on both code and .mui binaries.
See To view MUI resource configuration settings in PE files. - Compare the code and .mui binary RTM checksum values. Resources will not be found in any .mui file where this checksum does not match. You can solve any mismatch by re-running the binaries through your localization process.
- Compare each .mui file Language field to the directory in which it is contained. If these do not match (case-insensitive), resources will not be loaded from this file. To correct this, place the .mui file in a properly named folder.
- Confirm that MuiNameTypes or MuiIDTypes have one or more entries in total. If you have no entries here, the .mui file probing will not be performed for that resource type. To adjust, rerun your binaries through your localization process.
To install a Windows Vista language packTo make language setting changesTo make language setting changes, adjust the Windows Vista language settings – Thread, User/Machine, and Installed Languages. These settings define the list of languages that the Resource Loader will probe for satellite .mui localized resource data. Click here for additional information on language settings. To adjust thread languagesAdjust thread languages using API calls from the running application. Click here for more information on thread language APIs. To adjust user-preferred UI language (UPL)- Follow the instructions for Change the display language.
~ OR ~ - Use Unattended Mode to adjust the international settings and UI language when Windows Vista is already installed. Click here for more information.
~ OR ~ - Use the intlcfg.exe OPK tool in Windows Vista Multilanguage image (off-line) to adjust the international settings and UI languages. Click here for more information.
To adjust machine preferred UI language (MPL)To adjust language installed on operating systemTo avoid an intended licensing-induced blue screen, do not modify the OS language settings in the registry. Instead, reinstall the operating system with a different language SKU. To view MUI resource configuration settings in PE files- Obtain MUIRCT.exe (available from the Windows Vista SDK).
- In a command window, change to the directory to muirct.exe is located.
- Identify the path and filename of the MUI resource configuration you want to view.
- Execute the following command muirct.exe –d <PE filename>.
To view basic resource data in PE files- In Visual Studio (or comparable third-party application), copy the .mui and LN file to the same directory.
- Rename the .mui file as .mui.dll.
- Open both files in the Visual Studio Resource Explorer to view the resource data in the PE file.
Win32 MUI Run-Time Diagnostics Background and ConceptsMUI localization technology is built on three primary concepts: MUI Language SettingsThe language setting design used for Windows Vista MUI consists of three primary tiers of languages: Introduction to Satellite MUI FilesSplitting resources from the code binary into the satellite .mui file is a key pillar of Windows Vista MUI localization technology. Splitting places the resources in a file that is easier and less costly to localize. Translation can occur separately from the components code, which simplifies the localization and deployment process. Click here for more information on MUI splitting. The key take-away is that the .mui file is created for each language that your application supports. Placement of .mui files according to language allows per-language resource lookup. It also makes it easier to install new languages as they are localized. Click here for more information on MUI file placement. MUI Resource LoadingMUI files and language settings enable dynamic, per-language resource loading. Think of the Resource Loader as a collection of inter-connected APIs that underpin the FindResource/Ex and LoadResource APIs, as well as APIs that generally follow their lead. When locating a particular resource, the Resource Loader uses the merged fallback list to guide its order of satellite file probing. The merged fallback list is a combination of the three language groupings – MUI_MERGE_SYSTEM_FALLBACK and MUI_USER_FALLBACK to the GetThreadPreferedUILanguages API. Click here for more information. Once a particular language .mui file is discovered and validated, the requested resource is returned to the caller. In the event that a valid .mui file is not found, follow-on languages in the merged fallback list are probed. Prior to resource loading failure, the Resource Loader attempts to look toward an ultimate fallback language and any resource data that might be present within the main code binary. | |