Win32 MUI Run-Time DiagnosticsThis FAQ is a compilation of answers about resource location and language settings for Multilingual User Interface (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?

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?

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 were not able 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 support mui splitting in Windows Vista 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 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 has been fixed in Windows 7, where UpdateResource converts all strings to uppercase. To avoid this issue, format custom resource types and names as uppercase when using UpdateResource.

Resource loading and the Enumeration APIs are unable to discover a resource which the Update APIs successfully inserted into my binary. How do I avoid this behavior?
It is likely that the newly added resource was handed to the UpdateResource API starting with a '#' as the first character of the string, for example "#42". UpdateResource treats this as a string where the FindResource/Ex and Enumeration APIs treat this as a numerical resource type or name. Avoid using the Update APIs with '#' characters. Click here for more information.

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 if my LCID or Language Name is supported by Windows?
Although not strictly related to MUI, validating LCIDs is important when using MUI technology. To validate language names or LCIDs 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 in Vista has a limitation that .mui file paths cannot exceed the MAX_PATH variable (260 characters). This limit was changed in Windows 7 to be MAX_PATH + LOCALE_NAME_MAX_LENGTH + 5 (350 characters including the null terminator). For Vista, 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. For Windows 7 when applications use LoadLibrary/Ex this behavior is not possible. 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 Windows Vista.

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 is 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 am using a side-by-side Win32 assembly, such as Microsoft Common Controls version 6. If it is MUI compliant (resource splitting via muirct or rc compiler) I am unable to get the correct resources to load if I change the thread language before loading resources. What should I do?
If the assemblies are properly installed and being used correctly, the following may be happening: On XP, the resource loader will load the version of the resource matching the active language on program launch. On Vista, Common Controls version 6 may or may not load the correct resources. For other side-by-side assemblies, the wrong resources will be loaded if the thread's language is different from the process language. Changing the thread's language before loading a side-by-side assembly's resources is not a supported scenario. On Windows 7, it is safe to change the thread's language before loading resources. If these guidelines are followed and the program is unable to load resources, please ensure that at least one corresponding resource assembly for a language in the language fallback list is installed. Click here for additional information on language fallback. Click here for more information on assembly manifest creation. Click here or here for more information on SxS assembly installation.

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?
In general, MUI technology does not currently support custom locales in Windows Vista and Windows 7. Custom locale support is being evaluated for a future Windows release. For now, refrain from using custom locales in MUI language management APIs and 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 with the MUI_CONSOLE_FILTER specified. 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 | Windows 7 | | Can install any language pack on any language OS | | | l | 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 | 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 | 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 | l | | Tools provided to third parties to accomplish MUI splitting | | | l | l | | Maximum of four languages in.mui probing fallback list | l | l | | | | Maximum of eighteen languages in.mui probing fallback list | | | l | | | Theoretical Maximum of 45 languages in.mui probing fallback list | | | | l | | Centralized storage of .mui files for system | l | l | | | | Application-centric storage of .mui files | | | l | l | | Language pack installation via MSI | l | l | | | | Language pack installation via Vista 'CBS' Installer | | | l | l | | Language pack installation can be done offline | | | l | l | | Language neutral concept added – bulk of resources located only in satellite .mui files | | | l | l | | Fallback resource data (en-US) contained in code binary | l | l | l (drivers only) | l (drivers only) | | Windows Language Interface Packs (LIP) available for all SKUs | Not supported | Windows Home, Windows Professional | All | All Windows 7 editions. Not supported on Windows Server 2008 R2 | | MUI available per SKU | All | Windows XP Professional, all Windows Server versions | All Windows Server 2008 versions (except Home Server) | Ultimate |

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?

Application shortcuts or application/service names and descriptions are not changing even though the strings have been updated in the Win32 PE file

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.

Debugging my MUI enabled application is new to me, ; are there any helpful MUI related debugging utilities?

Calling the SetThreadPreferredUILanguages API requires every thread in my process to handle a process-wide preference. Can I call an API to change language settings process-wide?

Many locales in Windows 7 are part of or associated with multiple parent chains. How does MUI treat locales that fall under this category?
All MUI APIs were adjusted in Windows 7 to properly handle multiple parent chains. - The language fallback list includes all parents associated with any given language.
- The resource loading APIs also follows this list by default or when LOCALE_NEUTRAL is passed to APIs that accept a locale.
- The resource loading functions preserve legacy resource probing in main binary by looking for the Vista-style neutral after the new parent chain list.

If I move my application to the Vista style MUI model, can I continue to use special locales (0x007F, 0x0400 or 0x0800) to obtain resources from MUI binaries?
Windows support for various special locales (LOCALE_USER_DEFAULT, LOCALE_SYSTEM_DEFAULT) generally extends to MUI resource location, enumeration and updating. It is not supported in language management APIs. This support is provided primarily for backward compatibility. The practice is discouraged for new MUI development as use of explicit locales and LOCALE_NEUTRAL (0) are preferred. Marking resources using these default LANGIDs is also discouraged and not supported by many MUI API.

In my application, I am able to enumerate a resource that cannot be found by FindResource/Ex. How do I avoid this behavior?
Under various conditions it is possible to construct Win32 PE files in which the Enumeration APIs are able to discover a resource that resource locator APIs are unable to find (or vice-versa). To avoid these issues the following guidance is offered: - Use the latest MUI build tools to generate resource containing Win32 PE files.
Click here for more information on the Resource Compiler. Click here for more information on muirct.exe. Click here for access to the latest Windows SDK. - When creating or adding resources in .rc files or via UpdateResource always use valid locales.
Click here for more information on locale validation. - Ensure all MUI files remain mono-lingual.
Click here for more information on viewing resource data. - When possible, access resources by having Windows use the internally maintained fallback list.
Click here for more information on language settings. - When servicing, always update the main binary (exe, dll, sys, etc.) and all associated .mui files.
- Do not attempt to Enumerate resources in SxS stored binaries.
- Test your application and binaries on all platforms prior to release.
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 install a Windows 7 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 process 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.
To refresh the Shell string cache - Windows Vista and Windows 2008- If the strings are being loaded through the RegLoadMuiString API, delete the HKEY_CURRENT_USER\Software\Classes\Local Settings\RegMuiCache registry key.
~ OR ~ - If the strings are being loaded through the SHLoadIndirectString API, for each affected user on the system:
- Call the SHChangeNotify SHChangeNotify API with the SHCNE_ASSOCCHANGED flag. Click here for more information.
~ OR ~ - Delete the HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache registry key.
To refresh the Shell string cache - Windows 7- Install all Win32 resource containing binaries with MSI. Click here for more information on MSI.
~ OR ~ - When MSI installation is not an option, such as when using a different install technology, call SHChangeNotify API with SHCNE_ASSOCCHANGED to force a cache refresh. Click here for more information.
~ OR ~ - For private testing purposes only, delete the HKCU\Software\Classes\Local Settings\MuiCache registry key for each affected user on the system.
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: - Thread languages - This term refers to languages that an application explicitly specifies per thread. Thread languages are optional and configurable at the application level. See To adjust thread languages.
- Process languages - This term refers to languages that an application explicitly specifies per process. Process languages are optional and configurable at the application level. Process languages were added to Windows 7 and are not available in Windows Vista and Windows Server 2008. See To adjust process languages.
- Language specified as default - The user language is also optional and can be configured by the user or by the administrator. See To make language setting changes, To adjust user preferred UI language and To adjust machine preferred UI language.
- System Install language - The system install language is mandatory and enforced at boot time by the operating system. It is commonly set by default at system install time, but may also be chosen for some SKUs on first boot. This language cannot be changed after system install.
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. The splitting process 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 resources management and here for more information on MUI resources splitting. If you are using Visual Studio 2008 you can also evaluate the MuiIzer tool to help setup your project in a MUI compatible way. 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. | |