Problems compiling resources in .Net 2.0 apps after updates.


[10 July 2007] The security patch of 10 July 2007 http://www.microsoft.com/technet/security/Bulletin/ms07-040.mspx changes culture names to use the new names on Windows XP/2003/2000 as well as Vista. 

In order to conform to RFC 4646 (replaces RFC 3066), we updated the names of some locales, which can cause applications using resources with the old names to fail to compile, usually with invalid culture or duplicate names.  The duplicates are caused because when the name isn’t recognized it is ignored.  Then the default resources end up conflicting.  There are two workarounds:

a) (preferred) rename the resource files to the correct RFC 4646 names:

Old Microsoft Name

RFC 4646 Name
en-CB -> en-029
az-AZ-Latn -> az-Latn-AZ
uz-UZ-Latn -> uz-Latn-UZ
sr-SP-Latn -> sr-Latn-CS
az-AZ-Cyrl -> az-Cyrl-AZ
uz-UZ-Cyrl -> uz-Cyrl-UZ
sr-SP-Cyrl -> sr-Cyrl-CS
bs-BA-Cyrl -> bs-Cyrl-BA
sr-BA-Latn -> sr-Latn-BA
sr-BA-Cyrl -> sr-Cyrl-BA
bs-BA-Latn -> bs-Latn-BA
iu-CA-Latn -> iu-Latn-CA
div-MV -> dv-MV
zh-CHT -> zh-Hant (Aliased, may not be necessary)
zh-CHS -> zh-Hans (Aliased, may not be necessary)

b) If you cannot rename the resources or still rely on the old names, then you can create custom cultures with the old names.  See Vista changes .Net 2.0 Locale Names, sample work around custom cultures/locales

Hope this helps,

Shawn

Comments (15)

  1. Marc Brooks says:

    Thanks for the information… one missing bit, after _which_ updates?  I assume this is mostly Vista’s .Net version, but what about service packs, .Net 3.0, etc?

    That said, since those old names _were_ unique, why can’t they simply be aliased forward?

  2. onovotny says:

    Is the name change just for Vista or does it apply to .NET 2.0 apps on XP?

    For applications that are expected to run on both Vista and XP, does that mean that they’ll need to have resources with both names on it?  How should it be handled?

  3. shawnste says:

    This applies mostly to the version shipped with Vista, although any other .Net 2.0 apps with most any current QFE applied could also have this behavior.

    There are difficulties with aliasing, for example, if you build a CultureInfo with the old non-standard name and then did a ToString would you expect the old or new name?  Our investigation showed that for the chinese neutrals aliasing was required.  For many cases aliasing could be just as bad or worse than not aliasing.

    Long term we’d like to have a better plan in case ISO changes tags (like when a country splits or changes), but in the meantime custom cultures should solve many problems when the expected names differ.  Serbia and Montenegro have that problem and others may.

    I’d also recommend that apps use names, but realize that the names might change due to ISO changes.  Hopefully the standards won’t change in so severe a manner in the future, however cases like Serbia and Montenegro will causes shifts in the ISO names.  I’ll blog more soon.

  4. hannes says:

    This is currently causing us major pain!

    Since our product has to localized for Serbia we have many resource files with the extension sr-SP-Latn. Now the first developer upgraded his machine to VISTA and all hell breaks loose. We had to change ALL extensions to .sr-Latn-CS (a few 100 files) only to find out, that the old version is now not compiling.

    We are currently trying the workarround mentioned in this article …. and a colleague just reported: it works! Thanks Shawn, at least your blog entry helped.

    BUT: Does Microsoft honestly not provide a solution to develop an application in a team consisting of 10+ developers in a mixed environment (XP + Vista).

    The solution would obviously be to provide a patch to add the new rfc names to an xp environment?

  5. shawnste says:

    I’m sorry that you’re experiencing pain.  We have a QFEs that fix this in .Net 2.0, and it will be fixed in the next version.  Note that these fixes change to the corrected names, so the old names won’t work unless you install a custom culture with the old names.

    That, of course, leaves the question of how to get the QFE with the fix for XP, which I’m not sure about.  I’ll try to figure that out and post back here.

  6. Pavan Naidu says:

    pls provide the solution for the same..urgent

  7. shawnste says:

    http://support.microsoft.com/kb/926776 should also include this change, however I didn’t see a download link.  The KB asks you to contact PSS, which might be able to assist you.

  8. suryakant says:

    when I am creating more than two resx files ,on compilation it gives above error.I have tried it by storing resx files in bin directory but it istnt work

    Pls give me solution for this I hvae tried it

    Error:Error 1 The namespace ‘Resources’ already contains a definition for ‘local’ c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Filessatelite69b687dd6f0b631dApp_GlobalResources.i2akytfe.3.cs 12

  9. shawnste says:

    If .Net doesn’t recognize one of the locales (because for example its custom and customs aren’t installed), then it ends up using the default locale (Invariant).  Since apps typically already have default resources you get an error.

    I’m not sure if this is what is happening to you, but try a short program that tries to create a new CultureInfo("en-US") for each locale you’re trying to use.  If it doesn’t work try creating a custom locale for that missing locale (use the CultureAndRegionInfoBuilder like in the workaround link above).

  10. Martin Oddman says:

    In RFC 4646 they give examples of specific codes like zh-Hant-CN zh-Hant-TW

    http://www.ietf.org/rfc/rfc4646.txt

    Why are not those codes included in the list, when for example codes like bs-Latn-BA and sr-Cyrl-CS are?

  11. shawnste says:

    We didn’t change the names for zh-CN or zh-TW (or zh-HK, etc.).  I believe that our forms are a legal variant of the zh-Latn-CN/zh-Latn-TW form, although RFC 4646 would prefer the longer form (including a script).

  12. Martin Oddman says:

    But the things I want to do is to have a CultureInfo that either says Traditional Chinese or Simplified Chinese and at the same time  specify that this culture belongs to for example China. I find no way to do this in .NET 2.0. The most logical way to do it, I think would be to use the codes zh-Hant-CN and zh-Hans-CN, but .NET would not accept those even if the RFC:s seems to say that those are the correct ones.

  13. shawnste says:

    You could use the Microsoft Locale Builder tool (or CultureAndRegionInfoBuilder) to make a locale with the zh-Hant-CN/zh-Hans-CN name.

    In practice however, "zh-Hant-CN" should be rare because Traditional Chinese isn’t used in mainland China (which invented Simplified Chinese).  zh-Hant-HK is more likely because if it’s political history.

    It would’ve probably been better to use the full names, but we didn’t.

  14. Dave says:

    Has it occurred to anyone at Microsoft that it'd be nice to have a method in the System.Globalization namespace that returns an ordered list of cultures to search for? You can walk the CultureInfo.Parent chain to get from zh-CN to zh-Hans to the default, but obsolete siblings (such as zh-CHS) should appear in this list as well. Things like this are important for backward compatibility, and would let apps continue to run unbroken in the face of updates.

  15. shawnste says:

    Sort of the opposite happens if I remember, zh-CHS has zh-Hans as it's parent.  This was a 1-time change some years ago, and a new API wouldn't help back-compat (because it's new :)).  Using the existing parent chain we had to make a trade-off of whether zh-Hans (the standard name) should be the parent, or if zh-CHS should be the parent.  Can't have both or you'd get stuck in a loop.  This helps some scenarios, but makes others harder.