Initial Commit

This commit is contained in:
2026-05-25 10:29:38 +08:00
commit c42c9aea2a
64 changed files with 5919 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
namespace PatchProbe.Shared.Contracts;
public interface ICollector<T>
{
Task<T> CollectAsync(CancellationToken cancellationToken = default);
}

View File

@@ -0,0 +1,8 @@
using PatchProbe.Shared.Models;
namespace PatchProbe.Shared.Contracts;
public interface IPayloadUploader
{
Task UploadAsync(PatchProbePayload payload, CancellationToken cancellationToken = default);
}

View File

@@ -0,0 +1,14 @@
namespace PatchProbe.Shared.Models;
public sealed class ApplicableUpdate
{
public string? UpdateId { get; init; }
public string? Title { get; init; }
public string? KbArticleId { get; init; }
public string? Category { get; init; }
public string? Severity { get; init; }
public bool RebootRequired { get; init; }
public bool IsDownloaded { get; init; }
public string? Description { get; init; }
public string? SupportUrl { get; init; }
}

View File

@@ -0,0 +1,9 @@
namespace PatchProbe.Shared.Models;
public sealed class CbsPackage
{
public string? PackageIdentity { get; init; }
public string? State { get; init; }
public string? ReleaseType { get; init; }
public string? InstallTime { get; init; }
}

View File

@@ -0,0 +1,10 @@
namespace PatchProbe.Shared.Models;
public sealed class CollectorMeta
{
public string SchemaVersion { get; init; } = "0.1";
public string CollectorVersion { get; init; } = "1.0.0";
public DateTimeOffset CollectedAt { get; init; } = DateTimeOffset.UtcNow;
public string? MachineName { get; init; }
public bool RanAsAdministrator { get; init; }
}

View File

@@ -0,0 +1,17 @@
namespace PatchProbe.Shared.Models;
public sealed class DeviceInfo
{
public string? Hostname { get; init; }
public string? Manufacturer { get; init; }
public string? Model { get; init; }
public string? SerialNumber { get; init; }
public string? BiosVersion { get; init; }
public string? BiosDate { get; init; }
public bool TpmPresent { get; init; }
public string? TpmVersion { get; init; }
public ulong RamBytes { get; init; }
public string? Domain { get; init; }
public string? Workgroup { get; init; }
public string? SystemType { get; init; }
}

View File

@@ -0,0 +1,13 @@
namespace PatchProbe.Shared.Models;
public sealed class DriverInfo
{
public string? DeviceName { get; init; }
public string? DriverVersion { get; init; }
public string? Manufacturer { get; init; }
public string? InfName { get; init; }
public string? HardwareId { get; init; }
public string? DeviceClass { get; init; }
public DateTimeOffset? DriverDate { get; init; }
public bool IsSigned { get; init; }
}

View File

@@ -0,0 +1,9 @@
namespace PatchProbe.Shared.Models;
public sealed class InstalledHotfix
{
public string? HotFixId { get; init; }
public string? Description { get; init; }
public string? InstalledBy { get; init; }
public DateTimeOffset? InstalledOn { get; init; }
}

View File

@@ -0,0 +1,14 @@
namespace PatchProbe.Shared.Models;
public sealed class OsInfo
{
public string? ProductName { get; init; }
public string? EditionId { get; init; }
public string? DisplayVersion { get; init; }
public string? ReleaseId { get; init; }
public string? BuildNumber { get; init; }
public int Ubr { get; init; }
public string? Architecture { get; init; }
public DateTimeOffset? InstallDate { get; init; }
public DateTimeOffset? LastBoot { get; init; }
}

View File

@@ -0,0 +1,14 @@
namespace PatchProbe.Shared.Models;
public sealed class PatchProbePayload
{
public CollectorMeta Collector { get; init; } = new();
public DeviceInfo? Device { get; init; }
public OsInfo? Os { get; init; }
public PendingRebootInfo? PendingReboot { get; init; }
public WindowsUpdateInfo? WindowsUpdate { get; init; }
public List<InstalledHotfix> InstalledHotfixes { get; init; } = [];
public List<CbsPackage> CbsPackages { get; init; } = [];
public List<DriverInfo> Drivers { get; init; } = [];
public List<UpdateEvent> RecentUpdateEvents { get; init; } = [];
}

View File

@@ -0,0 +1,10 @@
namespace PatchProbe.Shared.Models;
public sealed class PendingRebootInfo
{
public bool CbsRebootPending { get; init; }
public bool WindowsUpdateRebootRequired { get; init; }
public bool SessionManagerRebootRequired { get; init; }
public bool ComputerRenameRequired { get; init; }
public bool AnyPending => CbsRebootPending || WindowsUpdateRebootRequired || SessionManagerRebootRequired || ComputerRenameRequired;
}

View File

@@ -0,0 +1,11 @@
namespace PatchProbe.Shared.Models;
public sealed class UpdateEvent
{
public long EventId { get; init; }
public string? Source { get; init; }
public string? LogName { get; init; }
public string? Level { get; init; }
public DateTimeOffset? TimeCreated { get; init; }
public string? Message { get; init; }
}

View File

@@ -0,0 +1,13 @@
namespace PatchProbe.Shared.Models;
public sealed class UpdateHistoryEntry
{
public string? UpdateId { get; init; }
public string? Title { get; init; }
public string? KbArticleId { get; init; }
public int ResultCode { get; init; }
public int HResult { get; init; }
public DateTimeOffset? Date { get; init; }
public string? Operation { get; init; }
public string? ServerSelection { get; init; }
}

View File

@@ -0,0 +1,9 @@
namespace PatchProbe.Shared.Models;
public sealed class WindowsUpdateInfo
{
public List<ApplicableUpdate> ApplicableUpdates { get; init; } = [];
public List<UpdateHistoryEntry> History { get; init; } = [];
public WindowsUpdatePolicy? Policy { get; init; }
public string? SearchError { get; init; }
}

View File

@@ -0,0 +1,16 @@
namespace PatchProbe.Shared.Models;
public sealed class WindowsUpdatePolicy
{
public bool WsusConfigured { get; init; }
public string? WsusServer { get; init; }
public string? WsusStatusServer { get; init; }
public bool WufbConfigured { get; init; }
public int? DeferFeatureUpdatesDays { get; init; }
public int? DeferQualityUpdatesDays { get; init; }
public bool AutoUpdateEnabled { get; init; }
public int? AuOptions { get; init; }
public bool TargetGroupEnabled { get; init; }
public string? TargetGroup { get; init; }
public string? BranchReadinessLevel { get; init; }
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,25 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using PatchProbe.Shared.Models;
namespace PatchProbe.Shared.Serialization;
public static class PayloadSerializer
{
public static readonly JsonSerializerOptions Options = new()
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }
};
public static string Serialize(PatchProbePayload payload) =>
JsonSerializer.Serialize(payload, Options);
public static async Task SerializeToFileAsync(PatchProbePayload payload, string path, CancellationToken cancellationToken = default)
{
await using var stream = File.Create(path);
await JsonSerializer.SerializeAsync(stream, payload, Options, cancellationToken);
}
}