Skip to content

Commit 55af63a

Browse files
authored
Merge pull request #55 from santisq/54-add-lastwritetime-property-to-treeregistrykey-instances
Adds `LastWriteTime` to `TreeRegistryKey` Class
2 parents e6140d7 + 682c605 commit 55af63a

File tree

10 files changed

+75
-10
lines changed

10 files changed

+75
-10
lines changed

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# CHANGELOG
22

3+
- __09/25/2025__
4+
- Adds `LastWriteTime` Property to `TreeRegistryKey` class.
5+
36
- __09/16/2025__
4-
- **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.
5-
- **Sort Order for Registry Keys**: Similar to issue #9 but for the `Get-PSTreeRegistry` cmdlet. It now sorts Registry Keys in ascending order.
7+
- __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.
8+
- __Sort Order for Registry Keys__: Similar to issue #9 but for the `Get-PSTreeRegistry` cmdlet. It now sorts Registry Keys in ascending order.
69

710
- __04/19/2025__
811
- Adds parameter aliases for `Get-PSTree` and `Get-PSTreeRegistry`, issue #49.

docs/en-US/Get-PSTreeRegistry.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Get-PSTreeRegistry
2121
[-Depth <Int32>]
2222
[-Recurse]
2323
[-KeysOnly]
24+
[-Exclude <String[]>]
25+
[-Include <String[]>]
2426
[<CommonParameters>]
2527
```
2628

@@ -32,6 +34,8 @@ Get-PSTreeRegistry
3234
[-Depth <Int32>]
3335
[-Recurse]
3436
[-KeysOnly]
37+
[-Exclude <String[]>]
38+
[-Include <String[]>]
3539
[<CommonParameters>]
3640
```
3741

module/PSTree.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
}
1717

1818
# Version number of this module.
19-
ModuleVersion = '2.2.7'
19+
ModuleVersion = '2.2.8'
2020

2121
# Supported PSEditions
2222
# CompatiblePSEditions = @()

src/PSTree/Commands/GetPSTreeRegistryCommand.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics.CodeAnalysis;
4-
using System.Linq;
54
using System.Management.Automation;
65
using System.Security;
76
using Microsoft.Win32;

src/PSTree/Extensions/ExceptionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal static void ThrowInvalidSequence(this string vt) =>
3636

3737
internal static string ThrowIfInvalidExtension(this string extension)
3838
{
39-
#if NET6_0_OR_GREATER
39+
#if NET8_0_OR_GREATER
4040
if (extension.StartsWith('.'))
4141
{
4242
return extension;

src/PSTree/Extensions/TreeExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ internal static TreeRegistryBase[] Format(
189189
}
190190

191191
internal static IEnumerable<string> EnumerateKeys(this RegistryKey registryKey) =>
192-
#if NET6_0_OR_GREATER
192+
#if NET8_0_OR_GREATER
193193
registryKey.GetSubKeyNames().OrderDescending();
194194
#else
195195
registryKey.GetSubKeyNames().OrderByDescending(e => e);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#if WINDOWS
2+
using System;
3+
using System.Runtime.InteropServices;
4+
using Microsoft.Win32;
5+
using Microsoft.Win32.SafeHandles;
6+
7+
namespace PSTree.Native;
8+
9+
internal static partial class WinAPI
10+
{
11+
#if NET8_0_OR_GREATER
12+
[LibraryImport("advapi32.dll", EntryPoint = "RegQueryInfoKeyW")]
13+
private static partial int RegQueryInfoKey(
14+
#else
15+
[DllImport("advapi32.dll")]
16+
private static extern int RegQueryInfoKey(
17+
#endif
18+
SafeRegistryHandle hkey,
19+
IntPtr lpClass,
20+
ref uint lpcbClass,
21+
IntPtr lpReserved,
22+
IntPtr lpcSubKeys,
23+
IntPtr lpcbMaxSubKeyLen,
24+
IntPtr lpcbMaxClassLen,
25+
IntPtr lpcValues,
26+
IntPtr lpcbMaxValueNameLen,
27+
IntPtr lpcbMaxValueLen,
28+
IntPtr lpcbSecurityDescriptor,
29+
out long lpftLastWriteTime);
30+
31+
internal static DateTime? GetLastWriteTime(this RegistryKey key)
32+
{
33+
uint lpcbClass = 0;
34+
35+
int result = RegQueryInfoKey(
36+
hkey: key.Handle,
37+
lpClass: IntPtr.Zero,
38+
lpcbClass: ref lpcbClass,
39+
lpReserved: IntPtr.Zero,
40+
lpcSubKeys: IntPtr.Zero,
41+
lpcbMaxSubKeyLen: IntPtr.Zero,
42+
lpcbMaxClassLen: IntPtr.Zero,
43+
lpcValues: IntPtr.Zero,
44+
lpcbMaxValueNameLen: IntPtr.Zero,
45+
lpcbMaxValueLen: IntPtr.Zero,
46+
lpcbSecurityDescriptor: IntPtr.Zero,
47+
lpftLastWriteTime: out long lpftLastWriteTime);
48+
49+
return result == 0
50+
? DateTime.FromFileTime(lpftLastWriteTime) : null;
51+
}
52+
}
53+
#endif

src/PSTree/TreeRegistryKey.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#if WINDOWS
2+
using System;
23
using Microsoft.Win32;
34
using PSTree.Extensions;
5+
using PSTree.Native;
46
using PSTree.Style;
57

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

1820
public RegistryView View { get; }
1921

22+
public DateTime? LastWriteTime { get; }
23+
2024
internal TreeRegistryKey(
2125
RegistryKey key, string name, string source, int depth) :
2226
base(GetColoredName(name).Indent(depth), source, key.Name)
@@ -26,6 +30,7 @@ internal TreeRegistryKey(
2630
SubKeyCount = key.SubKeyCount;
2731
ValueCount = key.ValueCount;
2832
View = key.View;
33+
LastWriteTime = key.GetLastWriteTime();
2934
}
3035

3136
internal TreeRegistryKey(
@@ -36,6 +41,7 @@ internal TreeRegistryKey(
3641
SubKeyCount = key.SubKeyCount;
3742
ValueCount = key.ValueCount;
3843
View = key.View;
44+
LastWriteTime = key.GetLastWriteTime();
3945
}
4046

4147
private static string GetColoredName(string name) =>

tests/GetPSTreeCommand.tests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,6 @@ Describe 'Get-PSTree' {
196196
Start-Sleep 0.5
197197
$ps.Stop()
198198
try { $ps.EndInvoke($task) } catch { }
199-
} | Should -BeLessThan ([timespan] '00:00:01')
199+
} | Should -BeLessThan ([timespan] '00:00:02')
200200
}
201201
}

tests/GetPSTreeRegistryCommand.tests.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ Describe 'Get-PSTreeRegistry.Windows' {
122122

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

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

140140
It 'PSTreeRegistryValue has expected properties' {
@@ -173,7 +173,7 @@ Describe 'Get-PSTreeRegistry.Windows' {
173173
Start-Sleep 0.5
174174
$ps.Stop()
175175
try { $ps.EndInvoke($task) } catch { }
176-
} | Should -BeLessThan ([timespan] '00:00:01')
176+
} | Should -BeLessThan ([timespan] '00:00:02')
177177
}
178178
}
179179
}

0 commit comments

Comments
 (0)