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
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# CHANGELOG

- __09/25/2025__
- Adds `LastWriteTime` Property to `TreeRegistryKey` class.

- __09/16/2025__
- **Ctrl+C Cancellation**: Added support for gracefully canceling operations using <kbd>Ctrl+C</kbd> when the cmdlets are traversing a hierarchy. Previously, the only way to stop the process was by restarting the session.
- **Sort Order for Registry Keys**: Similar to issue #9 but for the `Get-PSTreeRegistry` cmdlet. It now sorts Registry Keys in ascending order.
- __Ctrl+C Cancellation__: Added support for gracefully canceling operations using <kbd>Ctrl+C</kbd> when the cmdlets are traversing a hierarchy. Previously, the only way to stop the process was by restarting the session.
- __Sort Order for Registry Keys__: Similar to issue #9 but for the `Get-PSTreeRegistry` cmdlet. It now sorts Registry Keys in ascending order.

- __04/19/2025__
- Adds parameter aliases for `Get-PSTree` and `Get-PSTreeRegistry`, issue #49.
Expand Down
4 changes: 4 additions & 0 deletions docs/en-US/Get-PSTreeRegistry.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Get-PSTreeRegistry
[-Depth <Int32>]
[-Recurse]
[-KeysOnly]
[-Exclude <String[]>]
[-Include <String[]>]
[<CommonParameters>]
```

Expand All @@ -32,6 +34,8 @@ Get-PSTreeRegistry
[-Depth <Int32>]
[-Recurse]
[-KeysOnly]
[-Exclude <String[]>]
[-Include <String[]>]
[<CommonParameters>]
```

Expand Down
2 changes: 1 addition & 1 deletion module/PSTree.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}

# Version number of this module.
ModuleVersion = '2.2.7'
ModuleVersion = '2.2.8'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down
1 change: 0 additions & 1 deletion src/PSTree/Commands/GetPSTreeRegistryCommand.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Management.Automation;
using System.Security;
using Microsoft.Win32;
Expand Down
2 changes: 1 addition & 1 deletion src/PSTree/Extensions/ExceptionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal static void ThrowInvalidSequence(this string vt) =>

internal static string ThrowIfInvalidExtension(this string extension)
{
#if NET6_0_OR_GREATER
#if NET8_0_OR_GREATER
if (extension.StartsWith('.'))
{
return extension;
Expand Down
2 changes: 1 addition & 1 deletion src/PSTree/Extensions/TreeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ internal static TreeRegistryBase[] Format(
}

internal static IEnumerable<string> EnumerateKeys(this RegistryKey registryKey) =>
#if NET6_0_OR_GREATER
#if NET8_0_OR_GREATER
registryKey.GetSubKeyNames().OrderDescending();
#else
registryKey.GetSubKeyNames().OrderByDescending(e => e);
Expand Down
53 changes: 53 additions & 0 deletions src/PSTree/Native/RegQueryInfoKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#if WINDOWS
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;

namespace PSTree.Native;

internal static partial class WinAPI
{
#if NET8_0_OR_GREATER
[LibraryImport("advapi32.dll", EntryPoint = "RegQueryInfoKeyW")]
private static partial int RegQueryInfoKey(
#else
[DllImport("advapi32.dll")]
private static extern int RegQueryInfoKey(
#endif
SafeRegistryHandle hkey,
IntPtr lpClass,
ref uint lpcbClass,
IntPtr lpReserved,
IntPtr lpcSubKeys,
IntPtr lpcbMaxSubKeyLen,
IntPtr lpcbMaxClassLen,
IntPtr lpcValues,
IntPtr lpcbMaxValueNameLen,
IntPtr lpcbMaxValueLen,
IntPtr lpcbSecurityDescriptor,
out long lpftLastWriteTime);

internal static DateTime? GetLastWriteTime(this RegistryKey key)
{
uint lpcbClass = 0;

int result = RegQueryInfoKey(
hkey: key.Handle,
lpClass: IntPtr.Zero,
lpcbClass: ref lpcbClass,
lpReserved: IntPtr.Zero,
lpcSubKeys: IntPtr.Zero,
lpcbMaxSubKeyLen: IntPtr.Zero,
lpcbMaxClassLen: IntPtr.Zero,
lpcValues: IntPtr.Zero,
lpcbMaxValueNameLen: IntPtr.Zero,
lpcbMaxValueLen: IntPtr.Zero,
lpcbSecurityDescriptor: IntPtr.Zero,
lpftLastWriteTime: out long lpftLastWriteTime);

return result == 0
? DateTime.FromFileTime(lpftLastWriteTime) : null;
}
}
#endif
6 changes: 6 additions & 0 deletions src/PSTree/TreeRegistryKey.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#if WINDOWS
using System;
using Microsoft.Win32;
using PSTree.Extensions;
using PSTree.Native;
using PSTree.Style;

namespace PSTree;
Expand All @@ -17,6 +19,8 @@ public sealed class TreeRegistryKey : TreeRegistryBase

public RegistryView View { get; }

public DateTime? LastWriteTime { get; }

internal TreeRegistryKey(
RegistryKey key, string name, string source, int depth) :
base(GetColoredName(name).Indent(depth), source, key.Name)
Expand All @@ -26,6 +30,7 @@ internal TreeRegistryKey(
SubKeyCount = key.SubKeyCount;
ValueCount = key.ValueCount;
View = key.View;
LastWriteTime = key.GetLastWriteTime();
}

internal TreeRegistryKey(
Expand All @@ -36,6 +41,7 @@ internal TreeRegistryKey(
SubKeyCount = key.SubKeyCount;
ValueCount = key.ValueCount;
View = key.View;
LastWriteTime = key.GetLastWriteTime();
}

private static string GetColoredName(string name) =>
Expand Down
2 changes: 1 addition & 1 deletion tests/GetPSTreeCommand.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,6 @@ Describe 'Get-PSTree' {
Start-Sleep 0.5
$ps.Stop()
try { $ps.EndInvoke($task) } catch { }
} | Should -BeLessThan ([timespan] '00:00:01')
} | Should -BeLessThan ([timespan] '00:00:02')
}
}
6 changes: 3 additions & 3 deletions tests/GetPSTreeRegistryCommand.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ Describe 'Get-PSTreeRegistry.Windows' {

Context 'Output Types' {
It 'PSTreeRegistryKey has expected properties' {
$key = Get-PSTreeRegistry -Path 'HKLM:\Software' -EA 0 |
Where-Object { $_ -is [PSTree.TreeRegistryKey] } |
$key = Get-PSTreeRegistry -Path 'HKLM:\Software' -KeysOnly -EA 0 |
Select-Object -First 1

$key.Kind | Should -BeExactly RegistryKey
Expand All @@ -135,6 +134,7 @@ Describe 'Get-PSTreeRegistry.Windows' {
$key.PSParentPath | Should -BeOfType ([string])
$key.Hierarchy | Should -Not -BeNullOrEmpty
$key.Depth | Should -BeGreaterOrEqual 0
$key.LastWriteTime | Should -BeOfType ([datetime])
}

It 'PSTreeRegistryValue has expected properties' {
Expand Down Expand Up @@ -173,7 +173,7 @@ Describe 'Get-PSTreeRegistry.Windows' {
Start-Sleep 0.5
$ps.Stop()
try { $ps.EndInvoke($task) } catch { }
} | Should -BeLessThan ([timespan] '00:00:01')
} | Should -BeLessThan ([timespan] '00:00:02')
}
}
}
Loading