Files
PatchProbe-Server/PatchProbe.Cli/Collectors/PendingRebootCollector.cs
2026-05-25 10:29:38 +08:00

65 lines
2.6 KiB
C#

using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using PatchProbe.Shared.Contracts;
using PatchProbe.Shared.Models;
namespace PatchProbe.Cli.Collectors;
public sealed class PendingRebootCollector(ILogger<PendingRebootCollector> logger) : ICollector<PendingRebootInfo>
{
public Task<PendingRebootInfo> CollectAsync(CancellationToken cancellationToken = default)
{
logger.LogInformation("Collecting pending reboot indicators");
var info = new PendingRebootInfo
{
CbsRebootPending = KeyExists(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending")
|| KeyExists(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress"),
WindowsUpdateRebootRequired = KeyExists(@"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"),
SessionManagerRebootRequired = HasPendingFileRenameOperations(),
ComputerRenameRequired = HasPendingComputerRename(),
};
logger.LogInformation("Pending reboot: {AnyPending} (CBS={Cbs}, WU={Wu}, SessionMgr={Sm}, Rename={Rename})",
info.AnyPending, info.CbsRebootPending, info.WindowsUpdateRebootRequired,
info.SessionManagerRebootRequired, info.ComputerRenameRequired);
return Task.FromResult(info);
}
private static bool KeyExists(string subKeyPath)
{
try
{
using var key = Registry.LocalMachine.OpenSubKey(subKeyPath);
return key != null;
}
catch { return false; }
}
private static bool HasPendingFileRenameOperations()
{
try
{
using var key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager");
var value = key?.GetValue("PendingFileRenameOperations");
if (value is string[] arr) return arr.Length > 0;
}
catch { }
return false;
}
private static bool HasPendingComputerRename()
{
try
{
using var key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName");
using var pendingKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName");
var active = key?.GetValue("ComputerName")?.ToString();
var pending = pendingKey?.GetValue("ComputerName")?.ToString();
return !string.Equals(active, pending, StringComparison.OrdinalIgnoreCase);
}
catch { return false; }
}
}