65 lines
2.6 KiB
C#
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; }
|
|
}
|
|
}
|