diff --git a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs
index adc3d98c4..0c24fa002 100644
--- a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs
+++ b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs
@@ -16,35 +16,34 @@ namespace System.Management.Automation.Internal
// - Ignore files/directories when access is denied;
// - Search top directory only.
private static readonly System.IO.EnumerationOptions s_defaultEnumerationOptions =
- new System.IO.EnumerationOptions() { AttributesToSkip = 0 };
+ new System.IO.EnumerationOptions() { AttributesToSkip = FileAttributes.Hidden };
// Default option for UNC path enumeration. Same as above plus a large buffer size.
// For network shares, a large buffer may result in better performance as more results can be batched over the wire.
// The buffer size 16K is recommended in the comment of the 'BufferSize' property:
// "A "large" buffer, for example, would be 16K. Typical is 4K."
private static readonly System.IO.EnumerationOptions s_uncPathEnumerationOptions =
- new System.IO.EnumerationOptions() { AttributesToSkip = 0, BufferSize = 16384 };
+ new System.IO.EnumerationOptions() { AttributesToSkip = FileAttributes.Hidden, BufferSize = 16384 };
+
+ private static readonly string EnCulturePath = Path.DirectorySeparatorChar + "en";
+ private static readonly string EnUsCulturePath = Path.DirectorySeparatorChar + "en-us";
///
- /// Check if a directory could be a module folder.
+ /// Check if a directory is likely a localized resources folder.
///
- internal static bool IsPossibleModuleDirectory(string dir)
+ /// Directory to check if it is a possible resource folder.
+ /// True if the directory name matches a culture.
+ internal static bool IsPossibleResourceDirectory(string dir)
{
- // We shouldn't be searching in hidden directories.
- FileAttributes attributes = File.GetAttributes(dir);
- if (0 != (attributes & FileAttributes.Hidden))
- {
- return false;
- }
-
// Assume locale directories do not contain modules.
- if (dir.EndsWith(@"\en", StringComparison.OrdinalIgnoreCase) ||
- dir.EndsWith(@"\en-us", StringComparison.OrdinalIgnoreCase))
+ if (dir.EndsWith(EnCulturePath, StringComparison.OrdinalIgnoreCase) ||
+ dir.EndsWith(EnUsCulturePath, StringComparison.OrdinalIgnoreCase))
{
- return false;
+ return true;
}
dir = Path.GetFileName(dir);
+
// Use some simple pattern matching to avoid the call into GetCultureInfo when we know it will fail (and throw).
if ((dir.Length == 2 && char.IsLetter(dir[0]) && char.IsLetter(dir[1]))
||
@@ -55,12 +54,12 @@ namespace System.Management.Automation.Internal
// This might not throw on invalid culture still
// 4096 is considered the unknown locale - so assume that could be a module
var cultureInfo = new CultureInfo(dir);
- return cultureInfo.LCID == 4096;
+ return cultureInfo.LCID != 4096;
}
catch { }
}
- return true;
+ return false;
}
///
@@ -75,6 +74,7 @@ namespace System.Management.Automation.Internal
Queue directoriesToCheck = new Queue();
directoriesToCheck.Enqueue(topDirectoryToCheck);
+ bool firstSubDirs = true;
while (directoriesToCheck.Count > 0)
{
string directoryToCheck = directoriesToCheck.Dequeue();
@@ -83,7 +83,7 @@ namespace System.Management.Automation.Internal
string[] subDirectories = Directory.GetDirectories(directoryToCheck, "*", options);
foreach (string toAdd in subDirectories)
{
- if (IsPossibleModuleDirectory(toAdd))
+ if (firstSubDirs || !IsPossibleResourceDirectory(toAdd))
{
directoriesToCheck.Enqueue(toAdd);
}
@@ -92,6 +92,7 @@ namespace System.Management.Automation.Internal
catch (IOException) { }
catch (UnauthorizedAccessException) { }
+ firstSubDirs = false;
string[] files = Directory.GetFiles(directoryToCheck, "*", options);
foreach (string moduleFile in files)
{
@@ -304,17 +305,14 @@ namespace System.Management.Automation.Internal
{
foreach (var subdirectory in subdirectories)
{
- if (IsPossibleModuleDirectory(subdirectory))
+ if (subdirectory.EndsWith("Microsoft.PowerShell.Management", StringComparison.OrdinalIgnoreCase) ||
+ subdirectory.EndsWith("Microsoft.PowerShell.Utility", StringComparison.OrdinalIgnoreCase))
{
- if (subdirectory.EndsWith("Microsoft.PowerShell.Management", StringComparison.OrdinalIgnoreCase) ||
- subdirectory.EndsWith("Microsoft.PowerShell.Utility", StringComparison.OrdinalIgnoreCase))
- {
- directoriesToCheck.AddFirst(subdirectory);
- }
- else
- {
- directoriesToCheck.AddLast(subdirectory);
- }
+ directoriesToCheck.AddFirst(subdirectory);
+ }
+ else
+ {
+ directoriesToCheck.AddLast(subdirectory);
}
}
}
@@ -487,7 +485,7 @@ namespace System.Management.Automation.Internal
}
}
- string moduleShortName = System.IO.Path.GetFileNameWithoutExtension(modulePath);
+ string moduleShortName = Path.GetFileNameWithoutExtension(modulePath);
IDictionary exportedCommands = AnalysisCache.GetExportedCommands(modulePath, testOnly: false, context);
diff --git a/src/System.Management.Automation/help/HelpFileHelpProvider.cs b/src/System.Management.Automation/help/HelpFileHelpProvider.cs
index 60769b6de..32066611a 100644
--- a/src/System.Management.Automation/help/HelpFileHelpProvider.cs
+++ b/src/System.Management.Automation/help/HelpFileHelpProvider.cs
@@ -370,7 +370,7 @@ namespace System.Management.Automation
// * and SearchOption.AllDirectories gets all the version directories.
string[] directories = Directory.GetDirectories(psModulePath, "*", SearchOption.AllDirectories);
- var possibleModuleDirectories = directories.Where(directory => ModuleUtils.IsPossibleModuleDirectory(directory));
+ var possibleModuleDirectories = directories.Where(directory => !ModuleUtils.IsPossibleResourceDirectory(directory));
foreach (string directory in possibleModuleDirectories)
{
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Module.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Module.Tests.ps1
index b6ea7d8dc..bbff5b8d9 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Module.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Core/Get-Module.Tests.ps1
@@ -10,11 +10,13 @@ Describe "Get-Module -ListAvailable" -Tags "CI" {
New-Item -ItemType Directory -Path "$testdrive\Modules\Foo\2.0" -Force > $null
New-Item -ItemType Directory -Path "$testdrive\Modules\Bar\Download" -Force > $null
New-Item -ItemType Directory -Path "$testdrive\Modules\Zoo\Too" -Force > $null
+ New-Item -ItemType Directory -Path "$testdrive\Modules\Az" -Force > $null
New-ModuleManifest -Path "$testdrive\Modules\Foo\1.1\Foo.psd1" -ModuleVersion 1.1
New-ModuleManifest -Path "$testdrive\Modules\Foo\2.0\Foo.psd1" -ModuleVersion 2.0
New-ModuleManifest -Path "$testdrive\Modules\Bar\Bar.psd1"
New-ModuleManifest -Path "$testdrive\Modules\Zoo\Zoo.psd1"
+ New-ModuleManifest -Path "$testdrive\Modules\Az\Az.psd1" -ModuleVersion 1.1
New-Item -ItemType File -Path "$testdrive\Modules\Foo\1.1\Foo.psm1" > $null
New-Item -ItemType File -Path "$testdrive\Modules\Foo\2.0\Foo.psm1" > $null
@@ -22,6 +24,7 @@ Describe "Get-Module -ListAvailable" -Tags "CI" {
New-Item -ItemType File -Path "$testdrive\Modules\Bar\Download\Download.psm1" > $null
New-Item -ItemType File -Path "$testdrive\Modules\Zoo\Zoo.psm1" > $null
New-Item -ItemType File -Path "$testdrive\Modules\Zoo\Too\Zoo.psm1" > $null
+ New-Item -ItemType File -Path "$testdrive\Modules\Az\Az.psm1" > $null
$fullyQualifiedPathTestCases = @(
# The current behaviour in PowerShell is that version gets ignored when using Get-Module -FullyQualifiedName with a path
@@ -40,11 +43,13 @@ Describe "Get-Module -ListAvailable" -Tags "CI" {
It "Get-Module -ListAvailable" {
$modules = Get-Module -ListAvailable
- $modules.Count | Should -Be 4
+ $modules.Count | Should -Be 5
$modules = $modules | Sort-Object -Property Name, Version
- $modules.Name -join "," | Should -BeExactly "Bar,Foo,Foo,Zoo"
- $modules[1].Version | Should -Be "1.1"
- $modules[2].Version | Should -Be '2.0'
+ $modules.Name -join "," | Should -BeExactly "Az,Bar,Foo,Foo,Zoo"
+ $modules[0].Version | Should -Be "1.1"
+ $modules[1].Version | Should -Be "0.0.1"
+ $modules[2].Version | Should -Be '1.1'
+ $modules[3].Version | Should -Be '2.0'
}
It "Get-Module -ListAvailable" {
@@ -58,25 +63,27 @@ Describe "Get-Module -ListAvailable" -Tags "CI" {
It "Get-Module -ListAvailable -All" {
$modules = Get-Module -ListAvailable -All
- $modules.Count | Should -Be 10
+ $modules.Count | Should -Be 12
$modules = $modules | Sort-Object -Property Name, Path
- $modules.Name -join "," | Should -BeExactly "Bar,Bar,Download,Foo,Foo,Foo,Foo,Zoo,Zoo,Zoo"
+ $modules.Name -join "," | Should -BeExactly "Az,Az,Bar,Bar,Download,Foo,Foo,Foo,Foo,Zoo,Zoo,Zoo"
$modules[0].ModuleType | Should -BeExactly "Manifest"
$modules[1].ModuleType | Should -BeExactly "Script"
- $modules[2].ModuleType | Should -BeExactly "Script"
- $modules[3].ModuleType | Should -BeExactly "Manifest"
- $modules[3].Version | Should -Be "1.1"
+ $modules[2].ModuleType | Should -BeExactly "Manifest"
+ $modules[3].ModuleType | Should -BeExactly "Script"
$modules[4].ModuleType | Should -BeExactly "Script"
$modules[5].ModuleType | Should -BeExactly "Manifest"
- $modules[5].Version | Should -Be "2.0"
+ $modules[5].Version | Should -Be "1.1"
$modules[6].ModuleType | Should -BeExactly "Script"
- $modules[7].ModuleType | Should -BeExactly "Script"
- $modules[7].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Too\Zoo.psm1").Path
- $modules[8].ModuleType | Should -BeExactly "Manifest"
- $modules[8].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Zoo.psd1").Path
+ $modules[7].ModuleType | Should -BeExactly "Manifest"
+ $modules[7].Version | Should -Be "2.0"
+ $modules[8].ModuleType | Should -BeExactly "Script"
$modules[9].ModuleType | Should -BeExactly "Script"
- $modules[9].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Zoo.psm1").Path
+ $modules[9].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Too\Zoo.psm1").Path
+ $modules[10].ModuleType | Should -BeExactly "Manifest"
+ $modules[10].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Zoo.psd1").Path
+ $modules[11].ModuleType | Should -BeExactly "Script"
+ $modules[11].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Zoo.psm1").Path
}
It "Get-Module -ListAvailable -All" {
@@ -93,19 +100,19 @@ Describe "Get-Module -ListAvailable" -Tags "CI" {
It "Get-Module -ListAvailable" {
$modules = Get-Module "$testdrive\Modules\*" -ListAvailable
- $modules.Count | Should -Be 4
+ $modules.Count | Should -Be 5
$modules = $modules | Sort-Object -Property Name, Version
- $modules.Name -join "," | Should -BeExactly "Bar,Foo,Foo,Zoo"
- $modules[1].Version | Should -Be "1.1"
- $modules[2].Version | Should -Be '2.0'
+ $modules.Name -join "," | Should -BeExactly "Az,Bar,Foo,Foo,Zoo"
+ $modules[2].Version | Should -Be "1.1"
+ $modules[3].Version | Should -Be '2.0'
}
It "Get-Module -ListAvailable -All" {
$modules = Get-Module "$testdrive\Modules\*" -ListAvailable -All
- $modules.Count | Should -Be 5
+ $modules.Count | Should -Be 6
$modules = $modules | Sort-Object -Property Name, Path
- $modules.Name -join "," | Should -BeExactly "Bar,Foo,Foo,Zoo,Zoo"
- $modules[3].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Too\Zoo.psm1").Path
+ $modules.Name -join "," | Should -BeExactly "Az,Bar,Foo,Foo,Zoo,Zoo"
+ $modules[4].Path | Should -BeExactly (Resolve-Path "$testdrive\Modules\Zoo\Too\Zoo.psm1").Path
}
It "Get-Module -FullyQualifiedName -ListAvailable" {