Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/System.Management.Automation/help/CommandHelpProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Dbg = System.Management.Automation.Diagnostics;
using System.Management.Automation.Help;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace System.Management.Automation
{
Expand Down Expand Up @@ -352,10 +353,12 @@ private HelpInfo GetHelpInfo(CommandInfo commandInfo, bool reportErrors, bool se
{
if (isCmdlet)
{
_originalHelpFiles.TryAdd(cmdletInfo, cmdletInfo.HelpFile);
cmdletInfo.HelpFile = helpFile;
}
else if (isFunction)
{
_originalHelpFiles.TryAdd(functionInfo, functionInfo.HelpFile);
functionInfo.HelpFile = helpFile;
}
}
Expand Down Expand Up @@ -491,6 +494,13 @@ private static string GetCmdletAssemblyPath(CmdletInfo cmdletInfo)
/// </summary>
private readonly Hashtable _helpFiles = new Hashtable();

/// <summary>
/// The original HelpFile property of the commands whose HelpFile was set to the file their help
/// was found in. A full path in HelpFile is loaded directly, so Reset() restores the original
/// values to search for the help again, e.g. in a new UI culture or after Update-Help.
/// </summary>
private readonly ConditionalWeakTable<CommandInfo, string> _originalHelpFiles = new ConditionalWeakTable<CommandInfo, string>();

private string GetHelpFile(string helpFile, CmdletInfo cmdletInfo)
{
string helpFileToLoad = helpFile;
Expand Down Expand Up @@ -1304,6 +1314,20 @@ internal override void Reset()
base.Reset();

_helpFiles.Clear();

foreach (KeyValuePair<CommandInfo, string> entry in _originalHelpFiles)
{
if (entry.Key is CmdletInfo cmdletInfo)
{
cmdletInfo.HelpFile = entry.Value;
}
else if (entry.Key is FunctionInfo functionInfo)
{
functionInfo.HelpFile = entry.Value;
}
}

_originalHelpFiles.Clear();
}

#endregion
Expand Down
41 changes: 41 additions & 0 deletions test/powershell/engine/Help/HelpSystem.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -713,3 +713,44 @@ Describe 'InputTypes accurately describe pipelinable input' {
$inputTypes | Should -Be "System.String"
}
}

Describe "Get-Help searches for help again after its cache is reset" -Tags 'CI' {
BeforeAll {
$moduleName = 'HelpCacheResetTest'
$moduleBase = Join-Path $TestDrive $moduleName
foreach ($culture in 'en-US', 'de-DE') {
$null = New-Item -ItemType Directory -Path (Join-Path $moduleBase $culture) -Force
Set-Content -Path (Join-Path $moduleBase $culture "$moduleName-Help.xml") -Value @"
<?xml version="1.0" encoding="utf-8"?>
<helpItems schema="maml" xmlns="http://msh">
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
<command:details>
<command:name>Get-HelpCacheResetTest</command:name>
<maml:description><maml:para>Help for $culture</maml:para></maml:description>
</command:details>
</command:command>
</helpItems>
"@
}

Set-Content -Path (Join-Path $moduleBase "$moduleName.psm1") -Value 'function Get-HelpCacheResetTest { }'
Import-Module (Join-Path $moduleBase "$moduleName.psm1")
$originalUICulture = [System.Globalization.CultureInfo]::CurrentUICulture
}

AfterAll {
[System.Globalization.CultureInfo]::CurrentUICulture = $originalUICulture
Remove-Module $moduleName -ErrorAction SilentlyContinue
}

It "Get-Help finds the help of the new UI culture after the help was found in another one" {
# Finding the help sets the HelpFile property of the command to the full path of the help file.
# A change of the UI culture resets the help cache, like Update-Help does, so the help has to be
# searched for again instead of loading that file.
[System.Globalization.CultureInfo]::CurrentUICulture = 'en-US'
(Get-Help Get-HelpCacheResetTest).Synopsis | Should -BeExactly 'Help for en-US'

[System.Globalization.CultureInfo]::CurrentUICulture = 'de-DE'
(Get-Help Get-HelpCacheResetTest).Synopsis | Should -BeExactly 'Help for de-DE'
}
}