Skip to content

Add Import-LocalizedStringData cmdlet #5390

Closed

Description

@sdecker

The steps to reproduce is difficult but we have wasted multiple man days chasing issues with Import-Module/Import-LocalizedData with servers running En-GB culture. We've seen it with smbshare and powershell.archive. An example of the issue is captured in #4180. While that bug was closed and the user told to file a bug in the Archive specific location the ultimate issue is with Import-LocalizedData or Import-Module. If a language specific localization is not found it MUST NOT fail to load the module.

Activity

  1. added
    WG-Enginecore PowerShell engine, interpreter, and runtime
    Resolution-ExternalThe issue is caused by external component(s).
    and removed
    WG-Enginecore PowerShell engine, interpreter, and runtime
    on Nov 9, 2017
  2. SteveL-MSFT commented on Nov 9, 2017

    @SteveL-MSFT
    Member

    The problem is that import-module doesn’t know why the psm1 script failed, only that an error was thrown. The issue is in the module. I’ll submit a PR to fix Archive module

  3. sdecker commented on Nov 9, 2017

    @sdecker
    Author

    We've also seen this in the SmbShare. I'm sure we saw it with another module but it was a while ago and I'm having trouble finding. This has moved from an anomaly to a recurring problem. How is this not a Import-LocalizedData bug? Why is it throwing instead of warning?

  4. sdecker commented on Nov 9, 2017

    @sdecker
    Author

    Another way to put this. Adding a work around to the Archive module is fixing the symptom not the disease.

  5. Jaykul commented on Nov 9, 2017

    @Jaykul
    Contributor

    I gotta agree with sdecker on this, Steve Lee (@SteveL-MSFT) -- if Import-LocalizedData ever throws because the user is in a culture that the author hasn't thought of, that's makes Import-LocalizedData HARMFUL ...

    The design of the module is that it has the fallback strings in a data section, and it's trying to call Import-LocalizedData to load better strings if they're available. Is that not the way Import-LocalizedData works?

  6. changed the title [-]Import-Module/Import-LocalizedData must NEVER cause module import to load if culture not found[/-] [+]Import-LocalizedData must NEVER error if culture not found[/+] on Nov 9, 2017
  7. SteveL-MSFT commented on Nov 9, 2017

    @SteveL-MSFT
    Member

    I've updated the title to focus on Import-LocalizedData. I'm open to discussing having some fallback capability to Import-LocalizedData.

  8. Jaykul commented on Nov 9, 2017

    @Jaykul
    Contributor

    As I see it, the problem is two things:

    1. Import-LocalizedData writes an error when it can't find a localization
    2. Even benign errors break module dependency

    If a module calls Import-LocalizedData without suppressing the inevitable error, that doesn't techincally stop the module from being imported and used. As a result, of TWENTY THREE modules in $PSHome\Modules which use Import-LocalizedData (on my Windows 10, PS5.1 system) only two use -ErrorAction to suppress the errors. I don't know how many of these modules are actually localized, but if there's a betting pool, I'm taking ZERO.

    This is a problem because if another module or script specifies a dependency on any of these modules (e.g. via RequiredModules in the manifest or via #requires -module or just by calling Import-Module -ErrorAction Stop ... then those modules or scripts break whenever they are used in a locale that isn't explicitly localized.

    The only reason I can think of that this hasn't come up before is that module authors basically never document their dependency on "in the box" modules, and nobody but Microsoft bothers to localize at all...

    If I just use a cmdlet from a module with a localization problem, you'll see the localization error from the autoloading, but the cmdlet will run and produce results with no problems. It's only when I put the module in my RequiredModules or use a #requires that it causes a terminating error.

  9. 1 remaining item

  10. Jaykul commented on Nov 9, 2017

    @Jaykul
    Contributor

    I should note that many of these modules (e.g. Appx, BitLocker, etc) don't even have the fallback data section in the file -- sdecker has been lucky so far, Archive and SmbShare module do have default values in a data section, so this localization error isn't fatal to the module except when the module import happens when ErrorActionPreference is set to Stop. For these other modules like Appx and Bitlocker, the Import-LocalizedData failure will result in further errors whenever anything tries to access that LocalizedData.

    Clearly Microsoft isn't setting a good example for how to localize modules, so there should be no surprise that nobody else is doing it.

    From my perspective, the most immediate change that would help would be for the help to be changed to highlight the fact that when the localization files are missing it will produce an error, and that the caller really must decide how to handle that and do something.

    A single useful example should show the right way to do it, combining the default data in Example 5 and error handling! Perhaps the example could turn the error into a warning that English messages will be used instead...

  11. Jaykul commented on Nov 10, 2017

    @Jaykul
    Contributor

    If you want my 2c on a better long-term design for Import-LocalizedData:

    Make a Import-LocalizedStringData which:

    1. Doesn't have a SupportedCommand parameter
    2. Expects the file to have just the content that ConvertFrom-StringData supports
    3. Guarantees the output is a [dictionary[string,string]] rather than a hashtable

    String dictionaries are clearly the main use case for localization, the other features of Import-LocalizedData aren't generally used for translation, and they make it more complicated to use for it's primary purpose: almost every use of Import-LocalizedData has an internal ConvertFrom-StringData which would be unnecessary with Import-LocalizedStringData.

    1. Requires a DefaultData string dictionary parameter
    2. Guarantees that the output will have a value for every string in the DefaultData parameter

    This would ensure that the command never needs to produce an error -- it can fall back to the DefaultData -- it would also allow partial localizations to use the default strings for untranslated content.

    1. Has a fallback folder for localizations that is user-editable (e.g. in AppData or ~.config)
    2. Respects a PreferenceVariable for whether or not to generate a language file in the user location is no localized data is found for the current culture

    This would allow knowledgeable users to easily produce translations for themselves, without waiting for Microsoft to get around to supporting UK English 😉

  12. FriedrichWeinmann commented on Nov 10, 2017

    @FriedrichWeinmann

    Totally agree. This has been awkward for a long time and caused plenty of issues so far. Great write-up for a solution.

  13. SteveL-MSFT commented on Nov 10, 2017

    @SteveL-MSFT
    Member

    Joel Bennett (@Jaykul) I like your proposal and something we can look into for 6.1.0. If we go that route, then we wouldn't make any changes to Import-LocalizedData.

  14. Jaykul commented on Nov 10, 2017

    @Jaykul
    Contributor

    Agreed Steve Lee (@SteveL-MSFT), given the varied uses of Import-LocalizedData like mine for non-localization, and my count of the modules in $PSHome that wouldn't work even if you made it warn instead of error -- I'd be reluctant to change it much -- especially to suppress an error which can already be suppressed with -ErrorAction

    Focus on improving the documentation, and on fixing whatever testing process is allowing you to release "localized" modules that crash on anything other than en-US -- and of course, on fixing the actual modules. For now, I'm at the point where it's clearly problematic for us to add a dependency on any module that's localized.

    We currently work around the Archive module bug like this:

    function DoNothing {}
    Set-Alias Import-LocalizedData DoNothing
    Import-Module Microsoft.PowerShell.Archive
    Remove-Alias Import-LocalizedData
    Remove-Item function:DoNothing

    Although we could, arguably, use $PSDefaultParameterValues to force en-US instead (which might work for some of these other modules) ...

  15. changed the title [-]Import-LocalizedData must NEVER error if culture not found[/-] [+]Add Import-LocalizedStringData cmdlet[/+] on Nov 10, 2017
  16. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  17. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  18. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  19. microsoft-github-policy-service commented on Nov 23, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugResolution-No ActivityIssue has had no activity for 6 months or moreWG-Cmdletsgeneral cmdlet issues

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions