Warning: This technique will make it hard for an installer build by the Microsoft Locale Builder tool to overwrite the locale you're playing with.  You should use the locale builder installer to install and uninstall locales.  This technique is primarily interesting if you wanted to build a locale as part of another installer or something. 

*** Updated on 20 June 2006 to reflect changes in culture names ***

I've noticed some posts and comments about installing (or uninstalling) custom cultures by hand instead of using the CultureAndRegionInfoBuilder.Register() method.  (The Locale Builder beta tool for Vista uses the .Register() method.)  Note that any installation method besides .Register() are unsupported and will break if we change what Register() does, however personally I find this technique much simpler to use.

Also note that Custom Cultures/Locales are only supported by Microsoft .Net Framework v2.0 or Windows Vista or above.  (This won't work on XP/.Net 1.1)

What some of you have noticed is that custom culture files are installed in %windir%\globalization, and labeled with the culture name with a .nlp extension.  Ie: C:\Windows\Globalization\tlh-Latn-US.nlp.  You might be able to determine if a particular version of a custom locale is installed by doing a hash of that file and comparing that to your expected baseline.

In addition to creating this file, Register() makes one registry entry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CustomLocale\tlh-Latn-US is created and set to tlh-Latn-US.

In .Net 2.0 RTM another key was created.  Current versions, including .Net 2.0 with current updates, and .Net 2.0 on Windows Vista or Server 2008 this key is not created or used since the custom locale names are now the same as the IETF names.  See Change in .Net Framework Culture Names for Windows Vista.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\IetfLanguage\tlh-Latn-US used created and set to tlh-Latn-US on .Net 2.0 RTM machines only.  It is no longer used as the IETF name property was deprecated and the culture name is now identical to the IETF name.

As with any mucking with the Registry, note that these keys or their values and properties could change or be extended at any time, so the .Register() and .Unregister() methods are the safest (and only supported) way to install a custom culture.

*** 14 May 2009 ***

I just posted the opposite blog, how to uninstall a custom locale