Installing supplemental langauge support programatically
by Michael S. Kaplan, published on 2006/02/10 17:16 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/02/10/529867.aspx
Paul Langton asked via the contact link:
Firstly, love the blog and though a lot of it is waaaay over my head its always a great read, I'd go so far to say the best of all the MSDN blogs that I've sampled.
OK suck up out of the way, I have a VB script that does the same function as ticking the two tickboxes in "Supplemental language support" - i.e. "Install files for complex script and right to left languages (including Thai)" and "Install Files for East Asian Languages":
Dim oShell ' Windows Scripting Host shell
Dim oFSO ' File system object
Dim sCurDir ' Script path
Dim sWinDir ' Windows root path
'On Error Resume Next
Set oShell = CreateObject("WScript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")
sCurDir = Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName, "\") - 1)
sWinDir = oShell.ExpandEnvironmentStrings ("%WinDir%")
' Install "Supplemental Language Support"
oShell.Run sWinDir & "\system32\rundll32.exe advpack.dll,LaunchINFSection " & sCurDir & "\intl.inf,LANGUAGE_COLLECTION.COMPLEX.INSTALL", 1, 1
oShell.Run sWinDir & "\system32\rundll32.exe advpack.dll,LaunchINFSection " & sCurDir & "\intl.inf,LANGUAGE_COLLECTION.EXTENDED.INSTALL", 1, 1
My question is - what is the best way to detect if these are already enabled so when it is run it doesn't reinstall all this stuff?
Ok, first of all -- Paul, don't ever do this!
The code that does the installation of these components does indeed perform these steps, but it also does more than that -- and if you do only these things then you will probably findout at some point that not everything works as you want it to.
This is obviously bad.
The way to get this done is to use the method given in KB article 289125. Just install one of the East Asian and one of the Complex script locales and it will perform ALL of the installation steps, rather than just the ones you want.
And now to the actual question -- how to know when to skip this due to the installation already happening?
Well, you can actually use the old IsValidLocale function on any of the locales that is within one of the language groups in question (e.g. 0x0411 which is Japanese or 0x041e which is Thau) using the LCID_INSTALLED flag, or the IsValidLanguageGroup function to check the actual language groups and see if they are installed.
Now all of this is useful to remember, especially in the context of What isn't in the default install for NLS and Language groups -- the vestigial tail of NLS, especially since they give some use for language groups. :-)
But please try to avoid depending on anything in the INFs, since that is undocumented, unsupported, subject to change, and is changing massively in Vista....
This post brought to you by "ૐ" (U+0ad0, a.k.a. GUJARATI OM)
# Paul Langton on 10 Feb 2006 7:26 PM:
Hmmm, not sure the link you gave me will help in my situation, that is for how to create an unattended installation of Windows that includes these things. I have various boxes already installed out there that need to have these two checkboxes enabled. Rebuilding them/reinstalling Windows isn't an option (of course, that would be waaaaay too easy).
I should also say, I'm not a vb programmer, I'm an "application packager" (MSI stuff) so vbscript is probably the extend of my coding "skills", so using the IsValidLocale is beyond my skill set (unless you can call it via VBscript, which it doesn't look like you can)
# Michael S. Kaplan on 10 Feb 2006 9:49 PM:
The link I gave you will work just fine -- the unattend syntax works for post-setup scenarios just fine -- try it if you don't believe me.... it works very well!
For the other, there are many programming languages that are supported in the MSI framework, and lots of them support LCIDs and locales -- you can look to many of VBScript's methods like SetLocale that will fail on invalid LCIDs (for example) to get the job done.
But stay away for the INF -- it simply is a really bad way to go!
# Paul on 12 Feb 2006 7:22 PM:
Sorry to bother you with this continually...
I've read various people trying this with success, but I'm not having any luck - I'm assuming that its because where I work, we don't give users direct access to the i386 directory (you'll notice in my vbscript I specify the path to the i386 directory). I have to assume this is the problem, as there are no errors presented, it just runs and does nothing.
Is there an extra option for the "rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:"c:\regopts.txt"" where I can tell it where to find the i386 directory?
# Michael S. Kaplan on 12 Feb 2006 7:38 PM:
You can use the /s param to give a pointer to the dir where the install files would be found....
# Paul on 12 Feb 2006 8:13 PM:
Again, sorry to bother you but I still can't get this working, whats the syntax you specify the path... I've tried with "" without "", UNC, non-UNC and still not having any luck. Do I point it to the root of the i386 directory or the directory that contains the i386 directory I've tried both of these too to no avail).
Does it keep a log somewhere of what its trying to do and any errors it encounters?
Also, I've noted that if the user has the Regional Settings control panel open then this command line totally fails, it just brings that window to the front. I really need an enterprise solution to this issue, and this seems like something that hasn't been thought through. Any more hints?
# Michael S. Kaplan on 12 Feb 2006 8:20 PM:
Paul, the files it is looking for are not in the i386 directory, they are in the lang subdirectory of the i386 directory. That is where you should point it to.
As for the rest, in the enterprise scenario it is done at logon or in unattended setup, none of which have an intl.cpl loaded already. So it is well thought out for the scenarios where it is intended
# Paul on 12 Feb 2006 9:57 PM:
I'm saying this with the utmost respect for your work, I really do love your blog and the effort and dedication you have for what you do is truly inspiring, and I do appreciate your very quick feedback to my lack of knowledge :)
But in my mind, to have the deployment options limited to logon or unattended setup, relying on (as far as I'm aware) undocumented command line options (I still haven't seen an example of the /s option) isn't exactly what I'd call an enterprise solution.
But its more than likely this stems from my own ignorance rather than any issue with the technology.
Thanks again for your help, I'll continue plugging away (still having issues with the /s option)
# Paul on 12 Feb 2006 10:16 PM:
Actually I'll provide exact details on what I'm doing and perhaps you can point out my stupidity to me :) I know I'm doing something really really wrong but I've no idea what.
I've created a text file called c:\regopts.txt that is trying to install Japanese (I got the input locale code from http://www.microsoft.com/globaldev/reference/winxp/xp-lcid.mspx
I have a copy of the i386 directory on I:\i386
the command lines I have tried are:
rundll32.exe shell32,Control_RunDLL intl.cpl,/s:"I:\I386\lang",/f:"c:\regopts.txt"
rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:"c:\regopts.txt",/s:"I:\Install\I386\lang"
rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:"c:\regopts.txt" /s:"I:\I386\lang"
rundll32.exe shell32,Control_RunDLL intl.cpl,/s:"\\server\share\I386\lang",/f:"c:\regopts.txt"
Plus lots of other various combinations, all with no luck. I've tried Filemon and regmon on the process to see if its trying to access a file/regkey but can't see anything obvious in there.
Or should I be taking this to Microsoft Support that my company pays for rather than bother you about this?
# Michael S. Kaplan on 12 Feb 2006 10:30 PM:
Well, to start with the system locale and user locale in your unattend file arae both invalid -- those are not locales -- try 00000411 here.
The input locale is correct.
But looking at the settings, you are not just installing EA lang sdupport -- you are setting it across the board to Japanese. This seldom szeems a good idea in a post-install enterprise scenario so I hope this is just you testing things out rather than the official plan....
Beyond that, as I said you only need to include one language group to cover EA langs and one to cover complex scripts (assuming it is XP or Server 2003). You never need to specify five of them.
Beyond THAT, I'd be more convinced about the respect thing if you assumed you had missed something before you questioned the professional nature of the product. :-)
Unattend files do not need to commonly use that particular param since with the exception of international support, most of what someone needs is always in the i386 dir. But it is not unheard of in any of these cases to need to specify a dir.
I guess if you are not convinced that this is the solution to use then you can just not get a solution that has been tested by the team that owns the component. I will leave the decision to you....
# Paul on 12 Feb 2006 11:23 PM:
I do apologise, I never meant my comments of the product to reflect on yourself. You have certainly gone out of your way to assist me and I am truly appreciative, and I've obviously failed to express that coherently. The errors I am experiencing are to do with my lack of skills rather than any shortcoming on either your part or that of your team.
I am convinced this is the solution I should be using, I'm just actually trying to use it. There is no doubt that you and your team are vastly more experienced and knowledgable in this matter than I, hence me asking for assistance (and I'll have to learn me some manners when asking for help!).
I'll soldier on.
# Michael S. Kaplan on 12 Feb 2006 11:27 PM:
No apology needed, Paul. Thats why I had that smiley thing on the "respect" line. Just having a little fun on a Sunday. :-)
I honestly should have thought to ask you for the contents of your unattend file first, since the last four times someone was having trouble that is where the trouble turned out to be (and where I think it is now)....
# Paul on 13 Feb 2006 12:00 AM:
# Michael S. Kaplan on 13 Feb 2006 12:13 AM:
Well, how about starting small -- like with one settingg. Maybe one that does not require files to be installed. And then work your way up from there?
The current file you listed is trying to do everything (which is probably not what you needed to do anyway). We can track down what is happening here....
# Paul on 13 Feb 2006 4:10 PM:
The other issue is definately my own ignorance, I have no idea what some of the settings in the setopts.txt file do...
From the KB article:
Language = locale ID
LanguageGroup = language group ID, language group ID
SystemLocale = locale ID
UserLocale = locale ID
InputLocale = locale ID:keyboard layout ID, locale ID:keyboard layout ID
UserLocale_DefaultUser = locale ID
InputLocale_DefaultUser = locale ID:keyboard layout ID
Language is reasonable obvious (even though I got it wrong)
LanguageGroup escapes me totally, it describes this as:
LanguageGroup - This setting specifies the language support that is installed on the computer. If this setting is specified, it provides the default settings for the InputLocale, SystemLocale, and UserLocale settings.
But what do I actually put in there? It seems to be numbers, but I've no idea how to tell it what numbers equal what language (or languages)
System locale I assume changes the default system locale?
User Locale I assume changes the locale for the user you are running the command as.
Input locale specifies the input and keyboard combinations, this is the setting I guess I want to add Japanese (or any other Asian language) and also a left to right language (arabic perhaps?)
The other settings look like I don't want to play with them.
So, what I would think, to add Japanese to a PC that has English Australian and English US installed I should have a regopts.txt file like so:
LanguageGroup=?? (as I didn't know what to do here, I put 1, 2, 3, 4 ,5)
And then run:
rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:"c:\regopts.txt"
With my myriad of combinations of /s.
How is that looking?
# Michael S. Kaplan on 13 Feb 2006 4:25 PM:
As I said, try setting ONE thing, not four of them, for starters. You do not need to set SystemLocale, UserLocale, and InputLocale, most likely -- such changes on an enterprise are a huge mistake.
for more on language groups, which includes info about the actual numbers and what they mean....
# Paul on 13 Feb 2006 4:39 PM:
Wow that link should be a KB article...
And I now know that the fileds in the regopts.txt are optional... another piece of the puzzle...
I assume going to English (New Zealand) won't install any files? (fingers crossed, its not easy for the layperson to actually tell what will and won't require access to the i386 directory)...
So I try the following:
I'm still a little in the dark as to what to put in for the input locale, I'm copying the above from http://www.microsoft.com/globaldev/reference/winxp/xp-lcid.mspx
The above didn't appear to work, so I'm obviously waaaay off track...
# Paul on 13 Feb 2006 4:41 PM:
But hold the phone... I changed the regopts.txt to:
And hooray, it worked. :) I now have English US, English Australian and English New Zealand installed.
# Paul on 13 Feb 2006 4:51 PM:
And changing it to:
And it worked! Installed Japanese (it prompted for the files though, but I'll play around with the /s setting).
Can't thank you enough, your patience has been extraordinary through this. I'm sure its been as annoying for you as it has been challenging for me :) If I could send an email of commendation to those above you I would.
Again, thanks for your assistance. That link explaining the language groups is incredibly useful, I really should have thought to have searched your blog for that information.
# Michael S. Kaplan on 13 Feb 2006 8:35 PM:
Hey, no problems -- and I was not annoyed. I just wanted to see you helped. :-)
(And your very kind message via Robert Scoble made it to my boss, so that worked out, too!).
Re: the /s option -- the one you want is the third one, where they are both in that last parameter.....
# Paul on 14 Feb 2006 5:12 PM:
Might be worth noting that this process does create a logfile, by default in c:\windows\regopt.log that has content like the following:
Region and Languages Options Unattended Mode Log
Switch /F detected!
Switch /S detected!
<--- Unattended file log start---->
<--- Unattended file log end ---->
Language group installation requested: 11
No valid Language settings found, look for individual keywords.
Input locale installation requested.
Keyboard Layout installation requested: 041e
The best thing is when you get it wrong (e.g. specify the wrong language group for the locale you are requesting etc) it actually tells you what you are doing wrong.
Also, with the /S switch, you point it at the i386 directory level, not the LANG level, it finds LANG etc by itself :)
Hope that comes of use to someone!
# Michael S. Kaplan on 14 Feb 2006 9:22 PM:
Oops! I forgot about that part. Sorry, that would have made things easier, I'm sure....
# Ivan Petrov on 15 Feb 2006 4:17 PM:
Hi Michael ;-)
I've a question!:
What will replace this 2 files:
'intl.inf' and 'font.inf',
in Windows Vista?
And also one more question:
Will it be possible to customize so easy the new system, that replaced this 2 files, like nowadays we can customize this 2 *.inf files!?
# Ivan Petrov on 16 Feb 2006 12:35 PM:
With the previous questions I meant:
If for example I've a CUSTOM c_?.nls file (Codepage conversion table created by me) and I want to add it to Windows, in Windows XP I've to:
1) copy the c_?.nls file to the System32 folder;
2) edit the 'intl.inf' file and make some modifications in it, one of which is in the [Strings] section of this file to add something like this:
CP? = "? (Some Description Here)"
which make it appear the codepage Description under the Advanced tab in Regional and Language Options in the Codepage conversion tables Checkbox List.
3) If I want the Command Prompt Window to support my c_?.nls encoding, I've to edit the 'font.inf' file and add some additional lines and copy some c_?.nls related custom *.fon fonts into the Fonts folder.
So, I'm wondering how will look now all this process in Windows Vista, as I saw that many entries from the 'intl.inf' file are disappeared from there!
# Michael S. Kaplan on 16 Feb 2006 12:45 PM:
Hmmm... you know that these updates are undocumented and unsupported, right?
So you are essentially asking me what is the new way to do something undocumented and unsupported if thed old way to do something undocumented and unsupported is broken by the new supported designs of the OS.
I think the answer is implied in the question, sorry. :-(
# Ivan Petrov on 16 Feb 2006 2:31 PM:
# Michael S. Kaplan on 16 Feb 2006 3:05 PM:
Never fear, I will be posting about this issue soon! :-)
# Ivan Petrov on 16 Feb 2006 3:23 PM:
Ok, 10x in advance Michael.
I'll be waiting for this posts with great interest and enthusiasm ;-)
# Paul C on 10 Apr 2006 9:52 AM:
As they say: "Learning from mistakes", this article pointed me the way (and the links) to finally get my unattended install configured in such a way that it automatically adds support for Korean and Thai without user interaction.
# Ivan Petrov on 10 Apr 2006 4:48 PM:
I'm still waiting to post something about this issue above.
# Michael S. Kaplan on 10 Apr 2006 7:03 PM:
Well, they haven't fired me yet, so hang in there....
# Ivan Petrov on 11 Apr 2006 2:41 AM:
Ok, I'll wait ...
Drewfus on 11 Feb 2010 1:17 PM:
regarding KB article 289125, if UserLocale_DefaultUser and InputLocale_DefaultUser create settings for the default user, what user's does UserLocale and InputLocale effect - all current accounts?
If UserLocale_DefaultUser and InputLocale_DefaultUser are not used in an unattended setup, UserLocale and InputLocale will update the default users settings regardless. Correct?
Although 289125 is a well written article, it doesn't seem quite clear to me in what contexts both pairs of settings should, or do not need to be supplied.
Michael S. Kaplan on 12 Feb 2010 3:17 PM:
The current user account is the one that is not the default user.
Drewfus on 13 Feb 2010 10:02 PM:
The section "Changing country/region and language options" explains it well enough...
The format of the answer file specified in a silent configuration is exactly the same as that used during setup. This means that all of the country/region setting options can be changed silently after the initial installation. The following is an example of a silent configuration that:
* Adds the "German to German" input language for the current user.
* Adds the "German to Swiss German" input language to the list of input languages for the default user.
* Configures the language for non-Unicode programs to German.
Copy Code [RegionalSettings]
If you specify multiple input languages for the InputLocale and InputLocale_DefaultUser keys, the first value specified will be set as the default for that particular user. In the following example, the InputLocale will set "German to German" as the default input language for the current user while making "German to Swiss German" available as an input language.
Copy Code [RegionalSettings]
Muhammad S. Attari on 4 Jun 2012 10:10 AM:
I want a code in a project sample of vb6 that automatically installs supplemental files (support for complex script and right-to-left languages in windows xp.
please help me.
Michael S. Kaplan on 4 Jun 2012 10:45 AM:
There is only one supported way to do that -- and it is covered here already....
Muhammad S. Attari on 4 Jun 2012 9:06 PM:
It is true that the topic covers in detail the problem, but I am unable to do that. If I copy and paste the code given above, it shows an error "cant find the INF file".
So please I request you to please send me a visual basic 6 project file with code for this purpose on my e-mail address:
I shall be thankful to you!
Michael S. Kaplan on 4 Jun 2012 9:44 PM:
Please READ the article,and read KB 289125. Do *not* run the code sample, as the blog explains, and do not use VB6 for this, it is the wrong tool for the job....
Muhammad S. Attari on 7 Jun 2012 8:25 PM:
Then what method should be used for this purpose, please?
Is there any activeX control, or any thing that may be embedded in the project to do this job?
M.Shakeel on 20 Jun 2012 5:24 PM:
Is there any other way for installing supplemental langauge support programatically?
Michael S. Kaplan on 20 Jun 2012 6:30 PM:
Via script, as described in that KB article.
garrenq on 8 Nov 2012 4:13 PM:
When I run this:
rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:"c:\temp\NORDIC.txt" /s:"W:\Software\Win2k3Standard\I386"
I get the install fine on the account I used to install it (Local Administrator, in this case). But when I login as a different user on the same system, it doesn't show the languages that I installed. How can I get the install to show for all users that login through this server?
NORDIC.txt has this in it:
go to newer or older post, or back to index or month or day