From 76b2986fbaf6a1b28a55403f2a51940dda3d002d Mon Sep 17 00:00:00 2001
From: xtqqczze <45661989+xtqqczze@users.noreply.github.com>
Date: Sun, 5 Oct 2025 22:08:35 +0100
Subject: [PATCH 1/3] Use `Environment.TickCount64` in `GetUptimeCommand`
Use the .NET Core 3.0 API `Environment.TickCount64` instead of `Stopwatch`
---
.../commands/utility/GetUptime.cs | 33 ++++++-------------
1 file changed, 10 insertions(+), 23 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs
index e8dcfbe254a..4c21820ddc7 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs
@@ -28,31 +28,18 @@ public class GetUptimeCommand : PSCmdlet
///
protected override void ProcessRecord()
{
- // Get-Uptime throw if IsHighResolution = false
- // because stopwatch.GetTimestamp() return DateTime.UtcNow.Ticks
- // instead of ticks from system startup.
- // InternalTestHooks.StopwatchIsNotHighResolution is used as test hook.
- if (Stopwatch.IsHighResolution && !InternalTestHooks.StopwatchIsNotHighResolution)
- {
- TimeSpan uptime = TimeSpan.FromSeconds(Stopwatch.GetTimestamp() / Stopwatch.Frequency);
+ TimeSpan uptime = TimeSpan.FromMilliseconds(Environment.TickCount64);
- switch (ParameterSetName)
- {
- case TimespanParameterSet:
- // return TimeSpan of time since the system started up
- WriteObject(uptime);
- break;
- case SinceParameterSet:
- // return Datetime when the system started up
- WriteObject(DateTime.Now.Subtract(uptime));
- break;
- }
- }
- else
+ switch (ParameterSetName)
{
- WriteDebug("System.Diagnostics.Stopwatch.IsHighResolution returns 'False'.");
- Exception exc = new NotSupportedException(GetUptimeStrings.GetUptimePlatformIsNotSupported);
- ThrowTerminatingError(new ErrorRecord(exc, "GetUptimePlatformIsNotSupported", ErrorCategory.NotImplemented, null));
+ case TimespanParameterSet:
+ // return TimeSpan of time since the system started up
+ WriteObject(uptime);
+ break;
+ case SinceParameterSet:
+ // return Datetime when the system started up
+ WriteObject(DateTime.Now.Subtract(uptime));
+ break;
}
}
From 351c0d81b04de0e1b44749f09641da5195555410 Mon Sep 17 00:00:00 2001
From: xtqqczze <45661989+xtqqczze@users.noreply.github.com>
Date: Sun, 5 Oct 2025 22:33:33 +0100
Subject: [PATCH 2/3] Extract into seperate methods
---
.../commands/utility/GetUptime.cs | 32 +++++++++++++++----
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs
index 4c21820ddc7..ca721bf9341 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs
@@ -28,21 +28,41 @@ public class GetUptimeCommand : PSCmdlet
///
protected override void ProcessRecord()
{
- TimeSpan uptime = TimeSpan.FromMilliseconds(Environment.TickCount64);
-
switch (ParameterSetName)
{
case TimespanParameterSet:
- // return TimeSpan of time since the system started up
- WriteObject(uptime);
+ ProcessTimespanParameterSet();
break;
case SinceParameterSet:
- // return Datetime when the system started up
- WriteObject(DateTime.Now.Subtract(uptime));
+ ProcessSinceParameterSet();
break;
}
}
+ ///
+ /// Process the Timespan parameter set.
+ ///
+ ///
+ /// Outputs the time of the last system boot as a .
+ ///
+ private void ProcessTimespanParameterSet()
+ {
+ TimeSpan result = TimeSpan.FromMilliseconds(Environment.TickCount64);
+ WriteObject(result);
+ }
+
+ ///
+ /// Process the Since parameter set.
+ ///
+ ///
+ /// Outputs the time elapsed since the last system boot as a .
+ ///
+ private void ProcessSinceParameterSet()
+ {
+ DateTime result = DateTime.Now.Subtract(TimeSpan.FromMilliseconds(Environment.TickCount64));
+ WriteObject(result);
+ }
+
///
/// Parameter set name for Timespan OutputType.
///
From 91dfb2e0ac1c5a55f5038e2a916ddc7fe5de2662 Mon Sep 17 00:00:00 2001
From: xtqqczze <45661989+xtqqczze@users.noreply.github.com>
Date: Sun, 5 Oct 2025 23:14:22 +0100
Subject: [PATCH 3/3] Remove redundant tests etc
---
.../resources/GetUptimeStrings.resx | 123 ------------------
.../engine/Utils.cs | 2 -
.../Get-Uptime.Tests.ps1 | 27 ----
3 files changed, 152 deletions(-)
delete mode 100644 src/Microsoft.PowerShell.Commands.Utility/resources/GetUptimeStrings.resx
diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/GetUptimeStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/GetUptimeStrings.resx
deleted file mode 100644
index f59439da714..00000000000
--- a/src/Microsoft.PowerShell.Commands.Utility/resources/GetUptimeStrings.resx
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- "The platform is not supported (System.Diagnostics.Stopwatch.IsHighResolution is false)."
-
-
diff --git a/src/System.Management.Automation/engine/Utils.cs b/src/System.Management.Automation/engine/Utils.cs
index 0de9fe0d5cc..8bbce66c487 100644
--- a/src/System.Management.Automation/engine/Utils.cs
+++ b/src/System.Management.Automation/engine/Utils.cs
@@ -1644,8 +1644,6 @@ public static class InternalTestHooks
// It's useful to test that we don't depend on the ScriptBlock and AST objects and can use a re-parsed version.
internal static bool IgnoreScriptBlockCache;
- // Simulate 'System.Diagnostics.Stopwatch.IsHighResolution is false' to test Get-Uptime throw
- internal static bool StopwatchIsNotHighResolution;
internal static bool DisableGACLoading;
internal static bool SetConsoleWidthToZero;
internal static bool SetConsoleHeightToZero;
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Uptime.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Uptime.Tests.ps1
index aff5e4d50af..1bdf4198f75 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Uptime.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Uptime.Tests.ps1
@@ -1,22 +1,6 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe "Get-Uptime" -Tags "CI" {
- BeforeAll {
- $IsHighResolution = [system.diagnostics.stopwatch]::IsHighResolution
- # Skip Get-Uptime test if IsHighResolution = false
- # because stopwatch.GetTimestamp() return DateTime.UtcNow.Ticks
- # instead of ticks from system startup
- if ( ! $IsHighResolution )
- {
- $origDefaults = $PSDefaultParameterValues.Clone()
- $PSDefaultParameterValues['it:skip'] = $true
- }
- }
- AfterAll {
- if ( ! $IsHighResolution ){
- $global:PSDefaultParameterValues = $origDefaults
- }
- }
It "Get-Uptime return timespan (default -Timespan)" {
$upt = Get-Uptime
$upt | Should -BeOfType Timespan
@@ -25,15 +9,4 @@ Describe "Get-Uptime" -Tags "CI" {
$upt = Get-Uptime -Since
$upt | Should -BeOfType DateTime
}
- It "Get-Uptime throw if IsHighResolution == false" {
- # Enable the test hook
- [system.management.automation.internal.internaltesthooks]::SetTestHook('StopwatchIsNotHighResolution', $true)
-
- try {
- { Get-Uptime } | Should -Throw -ErrorId "GetUptimePlatformIsNotSupported,Microsoft.PowerShell.Commands.GetUptimeCommand"
- } finally {
- # Disable the test hook
- [system.management.automation.internal.internaltesthooks]::SetTestHook('StopwatchIsHighResolutionIsFalse', $false)
- }
- }
}