One of the great features in the .NET Framework 2.0 is the ability to define new or replacement cultures, known as custom cultures. One of the benefits of this feature is that it allows you to export cultures from newer operating systems to older operating systems. This allows you to reap the rewards of the new culture without having to upgrade. The exported cultures are not always an exact replica of the original (for example the target operating system may not support the sort orders required by the exported culture) but it is often better than forcing your users to upgrade. I cover the subject of Custom Cultures in depth in one of the free sample chapters
for .NET Internationalization
The purpose of this post, however, is to explain why it is not so straight forwards exporting cultures from Vista as it is for other operating systems and what you can do to overcome this difference.
The problem lies in the ieftLanguageTag. The ietfLanguageTag is the culture name formatted according to the RFC 3066 standard. It is relevant because the CultureAndRegionInfoBuilder (i.e. the class that builds custom cultures and can ’export’ them) does not save the ietfLanguageTag when it runs on Vista. If you export the English (United States) ("en-US") from Windows XP SP2 and look through the generated LDML file you will find the following line:-
If you do the same from Vista the line won’t be there. This is a problem because if you try to load the resulting LDML file in an older operating system an exception will be thrown and the culture will not be imported. Now naturaly there is no value in exporting the English (United States) culture because all operating systems include this culture but you can see that this is a problem if the whole reason for doing this is to export a Vista culture to Windows XP SP 2.
So the solution to the problem is to add the ietfLanguageTag element back into the LDML file:-
public static void SetIetfLanguageTag(string ldmlFilename, string ietfLanguageTag)
const string msLocaleNamespace = "http://schemas.microsoft.com/globalization/2004/08/carib/ldml";
// Vista is version 6
if (System.Environment.OSVersion.Version.Major >= 6)
XmlDocument xmlDocument = new XmlDocument();
using (FileStream fileStream = new FileStream(ldmlFilename, FileMode.Open))
XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
// Check to see if the LDML file is missing the IETF Language Tag.
XmlNode ietfLanguageTagXmlNode = xmlDocument.SelectSingleNode(
if (ietfLanguageTagXmlNode == null)
// the IEFT Language Tag is missing - add it back
XmlNode msLocaleXmlNode = xmlDocument.SelectSingleNode(
if (msLocaleXmlNode is XmlElement)
XmlElement ietfLanguageTagXmlElement =
xmlDocument.CreateElement("msLocale", "ietfLanguageTag", msLocaleNamespace);
Call this me