by Michael S. Kaplan, published on 2008/07/31 03:31 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2008/07/31/8792990.aspx
So thinking about the design of MUI, some interesting thoughts came up in a conversation the other day.
Let's take NOTEPAD.EXE for a second.
If we move to the WINDOWS directory and hit ALT+ENTER we get it's Properties:
Let's move over to that Details tab:
Hmmm. I thought that we were all language-neutral now. Why is the file' version resource claiming that the file has a language of English (United States), anyway?
Let's look over in the language-specific directory and see what the NOTEPAD.EXE.MUI file looks like there:
Wow, no VERSION properties at all!
Wait, maybe that is an issue with the filetype. Let's copy the file and remove the .MUI extension:
and try again:
Ah, there we go. So it has a VERSION resource and the language is tagged.
Of course this proves nothing -- the original file makes the same claim, even though all of its resources are gone (as we learned in Random irreverent thoughts about the Ultimate Fallback).
So let's look at some of the other language files, like Arabic:
or maybe Hebrew:
And maybe we could mix things up a bit.
Like looking at the Arabic file under a Hebrew user interface language:
or the Hebrew file under the Arabic user interface language:
Okay, so the language files are being marked.
The only weird thing left is that the language neutral file, the one that even Mark Russinovich discovered the hard way is language neutral (ref: Random irreverent thoughts about the Ultimate Fallback), is marked as having a language.
Well, it turns out that the language splitting functionality in the Resource Compiler (RC.EXE and RCDLL.DLL).
Now RC.EXE has several flags related to creating .MUI files:
RC creates one language-neutral .RES file and one language-dependent (MUI) .RES file using script-file. This option must be used together with the /fo resname option. RC names the language-neutral .RES file resname.res and names the language-dependent (MUI) .RES file mresname.res.
RC creates a .RES file named resname using script-file.
If the /fm mresname option is also set, RC creates one language-neutral .RES file and one language-dependent (MUI) .RES file.
If /g1, is set, RC generates a MUI file if the only localizable resource being included in the MUI file is a version resource. If /g1 is not set, RC will not generate a MUI file if the only localizable resource being included in the MUI file is a version resource.
Localizable resource types RC places into the language-dependent (MUI) .RES file. If the /q option is also set, this option is ignored, and the information in the RC Configuration file takes precedence.
Overlapping resource types that RC places into both the language-neutral .RES and the language-dependent (MUI).RES files. The resource types that are specified by the /k option must be a subset of those that are specified by the /j option. For example, –J2 –J3 –K3 specifies that RC places resource type 3 in both the language-neutral and language-dependent (MUI) files. If the /q option is also set, this option is ignored, and the information in the RC Configuration file takes precedence.
An RC configuration file that follows the RC Configuration File format. The RC Configuration File format enables components to self-describe resource information such as resource versioning, MUI file path, resource types and items. This file specifies which resources go into the language-neutral .RES file and which resources go into the language-dependent (MUI) .RES file. This option, and the information provided in the RC Configuration file, override the command line options /j and /k.
Notice that in none of that talk of splitting resources does it ever make any claims about changing the language of the "neutral" .RES file it creates as part of the splitting.
Not that it wouldn't make sense for it to do that (since it took the time cause a de facto change to the language of the resource by removing all of the language-specific information), but that work item would have some interesting consequences, which I can talk about more some other time, perhaps....
This post brought to you by ຝ and ພ (U+0e9d and U+0e9e, a.k.a. LAO LETTER FO TAM and LAO LETTER PHO TAM)
GregM on 31 Jul 2008 9:29 AM:
Since every resource has a language associated with it, is it even possible to have a language-neutral version resource. If so, what language would be used for the text fields in that version resource, or would they just not be filled in? In that case, how would you include a copyright notice?
Michael S. Kaplan on 31 Jul 2008 9:35 AM:
If you put in 0 (zero) then you get a language neutral version resource, so that part is easy....
Mihai on 1 Aug 2008 2:01 PM:
It is a bit more interesting than this.
If you look at Notepad.exe after you change the system UI language, the version info claims to be in that language.
This means that Explorer uses the old way of accessing resources to get the version info, and the MUI magic is at work.
I don't say this is bad, it's just a comment.
As end user I find it normal that notepad.exe is French, since I click on it and starts in French. Only a geek would expect to see neutral.
Michael S. Kaplan on 1 Aug 2008 2:40 PM:
Ah, but is this behavior right either? The system UI language actually has no hold at all on resources for this application. Isn't that slightly more broken, even if the user not expecting language neutral might find it more intuitive? :-)
Mihai on 1 Aug 2008 5:33 PM:
"Ah, but is this behavior right either?"
More thinking is probably needed :-)
It feels right for the end user, but technically is (probably) wrong.
I don't think it is "broken." Only MS will update Notepad.
But it gets more interesting if more and more applications move to MUI "Vista style."
Now installers should know how to check the version info (imagine an installer refusing to update the language neutral executable because the language does not match, when in reality is fine and the users just switched to French).
And all other kind of cans of worms :-)
Igor Levicki on 3 Aug 2008 9:31 PM:
If Notepad.exe has MUI resources for all languages including English then English should not be embedded as a fallback. Period.
Michael S. Kaplan on 3 Aug 2008 10:39 PM:
Did you read the original blog? It does not. All resources were removed. I personally don't like this, but it is what it is whether I (and aooarently you) like it or not....
Mihai on 4 Aug 2008 3:19 PM:
"All resources were removed. I personally don't like this"
I like it.
It is consistent with the "English is just another language" philosophy.
And enables some business scenarios that are tricky otherwise
Cody Cutrer on 20 Nov 2008 3:54 PM:
Interestingly, if you copy notepad.exe elsewhere, and rename it (so that Windows can't find the MUI files), and open it in Visual Studio to inspect the actual resources, it *does* have a version resource, in en-US. And the icon and RT_MANIFEST resources are also en-US marked (though they don't actually contain any user-visible en-US content).
If you open notepad.exe up in Visual Studio in its default location, it will happily show you the "merged" view with the .mui file. Oddly, the RT_MANIFEST resource is no longer visible. Finally, if you're using the es-ES MUI, you *can't* open notepad.exe in the resource editor in Visual Studio... you get a message (from the OS apparently, since it is in Spanish) complaining that it couldn't find the language resource in the image, afterwhich Visual Studio (in english) complains about not being able to enumerate resources in the executable.
Next question... when using the Resource Compiler with a resource configuration script, the "MUI" resource in the LN file will end up being marked as the language of the .mui file - why is this? It would make more sense to me to have it LANG_INVARIANT, LANG_NEUTRAL, or even en-US. So when the resource loader is looking for the "MUI" resource to find out which resources it should look for in .mui files, does it just choose the first one it can find? What if you put multiple "MUI" resource ID 1's in, but with different language identifiers? Could you theoretically instruct the MUI resource loader to look in the .mui file for a set of resources in one language, but a different set for another language?
While we're on the topic of the "MUI" resource, why is it required, anyway? Beyond being able to specify an ultimate fallback language (which is why I'm investigating it, because on a pl-PL version of Windows -- which my app isn't localized into -- my MUI-compatible shortcuts are showing up in de-DE instead of en-US because the resource loader is just choosing the first language it can find because en-US is not in the search list at all), and possibly the checksums to ensure you're using a .mui that corresponds to the LN file, what is the purpose? The "this resource is found in the MUI, and this one in the LN" seems pretty pointless to me, besides a very slight optimization to skip searching the .mui's resources if you already know that it will only be in the LN (which very few resources should be). Is there any documentation for this structure? It seems to roughly correspond to FILEMUIINFO, but appears to have a couple more pointers in it that I couldn't find any file that utilized. It also has the flag that says whether the ultimate fallback resources are internal or external (again... who cares? If the ultimate fallback exists externally use that, otherwise search the LN). Also, it seems that one flag marks all Windows components, and is vice versa for everything generated by rc.exe. Maybe MUIRCT generates that flag. I can't find anything on my system that uses Vista MUI that doesn't come with Vista itself.
Finally, what's the whole point of the Resource Configuration file in helping the resource compiler generate the LN and MUI resource objects? Why not just put things marked as LANG_INVARIANT or LANG_NEUTRAL in the LN .res, and everything else into an appropriate MUI .res based on the language it is tagged with?