Skip to content
Merged
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
73 changes: 69 additions & 4 deletions src/System.Management.Automation/engine/SessionStateContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1593,7 +1593,7 @@ internal void GetChildItems(
}

int unUsedChildrenNotMatchingFilterCriteria = 0;
ProcessPathItems(providerInstance, providerPath, recurse, context, out unUsedChildrenNotMatchingFilterCriteria, ProcessMode.Enumerate);
ProcessPathItems(providerInstance, providerPath, recurse, depth, context, out unUsedChildrenNotMatchingFilterCriteria, ProcessMode.Enumerate);
}
}
else
Expand Down Expand Up @@ -1861,6 +1861,72 @@ private void ProcessPathItems(
out int childrenNotMatchingFilterCriteria,
ProcessMode processMode = ProcessMode.Enumerate,
bool skipIsItemContainerCheck = false)
{
// Call ProcessPathItems with 'depth' set to maximum value for infinite recursion when needed.
ProcessPathItems(providerInstance, path, recurse, uint.MaxValue, context, out childrenNotMatchingFilterCriteria, processMode, skipIsItemContainerCheck);
} // ProcessPathItems

/// <summary>
/// Since we can't do include and exclude filtering on items we have to
/// do the recursion ourselves. We get each child name and see if it matches
/// the include and exclude filters. If the child is a container we recurse
/// into that container.
/// </summary>
///
/// <param name="providerInstance">
/// The instance of the provider to use.
/// </param>
///
/// <param name="path">
/// The path to the item to get the children from.
/// </param>
///
/// <param name="recurse">
/// Recurse into sub-containers when getting children.
/// </param>
///
/// <param name="depth">
/// Limits the depth of recursion; uint.MaxValue performs full recursion.
/// </param>
///
/// <param name="context">
/// The context under which the command is running.
/// </param>
///
/// <param name="childrenNotMatchingFilterCriteria">
/// The count of items that do not match any include/exclude criteria.
/// </param>
///
/// <param name="processMode">Indicates if this is a Enumerate/Remove operation</param>
///
/// <param name="skipIsItemContainerCheck">a hint used to skip IsItemContainer checks</param>
///
/// <exception cref="ProviderNotFoundException">
/// If the <paramref name="path"/> refers to a provider that could not be found.
/// </exception>
///
/// <exception cref="DriveNotFoundException">
/// If the <paramref name="path"/> refers to a drive that could not be found.
/// </exception>
///
/// <exception cref="NotSupportedException">
/// If the provider that the <paramref name="path"/> refers to does
/// not support this operation.
/// </exception>
///
/// <exception cref="ProviderInvocationException">
/// If the provider threw an exception.
/// </exception>
///
private void ProcessPathItems(
CmdletProvider providerInstance,
string path,
bool recurse,
uint depth,
CmdletProviderContext context,
out int childrenNotMatchingFilterCriteria,
ProcessMode processMode = ProcessMode.Enumerate,
bool skipIsItemContainerCheck = false)
{
ContainerCmdletProvider containerCmdletProvider = GetContainerProviderInstance(providerInstance);
childrenNotMatchingFilterCriteria = 0;
Expand Down Expand Up @@ -2016,15 +2082,15 @@ private void ProcessPathItems(
}

// Now recurse if it is a container
if (recurse && IsPathContainer(providerInstance, qualifiedPath, context))
if (recurse && IsPathContainer(providerInstance, qualifiedPath, context) && depth > 0)
{
// Making sure to obey the StopProcessing.
if (context.Stopping)
{
return;
}
// The item is a container so recurse into it.
ProcessPathItems(providerInstance, qualifiedPath, recurse, context, out childrenNotMatchingFilterCriteria, processMode, skipIsItemContainerCheck: true);
ProcessPathItems(providerInstance, qualifiedPath, recurse, depth - 1, context, out childrenNotMatchingFilterCriteria, processMode, skipIsItemContainerCheck: true);
}
} // for each childName
}
Expand Down Expand Up @@ -2066,7 +2132,6 @@ private void ProcessPathItems(
}
} // ProcessPathItems


/// <summary>
/// Gets the dynamic parameters for the get-childitem cmdlet.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ Describe "Get-ChildItem" -Tags "CI" {
$item_c = "c283d143-2116-4809-bf11-4f7d61613f92"
$item_D = "D39B4FD9-3E1D-4DD5-8718-22FE2C934CE3"
$item_E = "EE150FEB-0F21-4AFF-8066-AF59E925810C"
$item_F = ".F81D8514-8862-4227-B041-0529B1656A43"
$item_F = ".F81D8514-8862-4227-B041-0529B1656A43"
$item_G = "5560A62F-74F1-4FAE-9A23-F4EBD90D2676"
$null = New-Item -Path $TestDrive -Name $item_a -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name $item_B -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name $item_c -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name $item_D -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name $item_E -ItemType "Directory" -Force
$null = New-Item -Path $TestDrive -Name $item_F -ItemType "File" -Force | ForEach-Object {$_.Attributes = "hidden"}
$null = New-Item -Path (Join-Path -Path $TestDrive -ChildPath $item_E) -Name $item_G -ItemType "File" -Force
}

It "Should list the contents of the current folder" {
Expand Down Expand Up @@ -66,6 +68,18 @@ Describe "Get-ChildItem" -Tags "CI" {
$file.Count | Should be 1
$file.Name | Should be $item_F
}

It "Should list items in current directory only with depth set to 0" {
(Get-ChildItem -Path $TestDrive -Depth 0).Count | Should Be 5
(Get-ChildItem -Path $TestDrive -Depth 0 -Include *).Count | Should Be 5
(Get-ChildItem -Path $TestDrive -Depth 0 -Exclude IntentionallyNonexistent).Count | Should Be 5
}

It "Should return items recursively when using 'Include' or 'Exclude' parameters" {
(Get-ChildItem -Path $TestDrive -Depth 1).Count | Should Be 6
(Get-ChildItem -Path $TestDrive -Depth 1 -Include $item_G).Count | Should Be 1
(Get-ChildItem -Path $TestDrive -Depth 1 -Exclude $item_a).Count | Should Be 5
}
}

Context 'Env: Provider' {
Expand Down