From 9acbbde0230bd0084a1199a2eece1df650d3c71e Mon Sep 17 00:00:00 2001 From: JusterZhu Date: Mon, 25 May 2026 21:41:38 +0800 Subject: [PATCH] fix: repair encoding corruption from #420 and fix cross-project BlackListManager references - Restore all files from before #420 merge and re-apply changes with proper encoding - Replace BlackListManager.Instance references in Differential project and tests - Fix ParameterMatrixAndEventTests to work with DefaultBlackListMatcher API - Use BlackListDefaults instead of removed BlackListManager singleton All changes from #419 + CI build fixes. Build and tests pass. --- .../Configuration/Environments.cs | 3 ++- .../GeneralUpdate.Core.csproj | 3 +-- .../Ipc/IProcessInfoProvider.cs | 1 - .../Silent/SilentPollOrchestrator.cs | 12 ++++++------ .../Strategy/ClientUpdateStrategy.cs | 6 +++--- .../Strategy/OSSUpdateStrategy.cs | 18 +++++++++--------- .../Matchers/DefaultDirtyStrategy.cs | 4 ++-- .../Pipeline/DiffPipeline.cs | 4 ++-- .../Bootstrap/ParameterMatrixAndEventTests.cs | 13 +++++++------ 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/c#/GeneralUpdate.Core/Configuration/Environments.cs b/src/c#/GeneralUpdate.Core/Configuration/Environments.cs index bd32d404..0f19beb7 100644 --- a/src/c#/GeneralUpdate.Core/Configuration/Environments.cs +++ b/src/c#/GeneralUpdate.Core/Configuration/Environments.cs @@ -9,10 +9,11 @@ namespace GeneralUpdate.Core.Configuration; /// /// Secure IPC environment variable provider. /// AES-encrypted temp files in a dedicated subdirectory, auto-deleted after read. -/// Encryption is delegated to . /// public static class Environments { + // Fixed key/IV derived from a constant — not crypto-grade, but sufficient for + // ephemeral IPC where the file lives < 1 second and is in a per-user directory. private static readonly byte[] _aesKey = SHA256.Create() .ComputeHash(Encoding.UTF8.GetBytes("GeneralUpdate.IPC.EnvironmentProvider.v1")); private static readonly byte[] _aesIV = new byte[16] { 0x47, 0x55, 0x50, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/src/c#/GeneralUpdate.Core/GeneralUpdate.Core.csproj b/src/c#/GeneralUpdate.Core/GeneralUpdate.Core.csproj index 1c1424af..cf93fe4e 100644 --- a/src/c#/GeneralUpdate.Core/GeneralUpdate.Core.csproj +++ b/src/c#/GeneralUpdate.Core/GeneralUpdate.Core.csproj @@ -4,7 +4,7 @@ enable GeneralUpdate.Core JusterZhu - GeneralUpdate unified core �?client and upgrade bootstrap, download, pipeline, strategies, utilities. + GeneralUpdate unified core — client and upgrade bootstrap, download, pipeline, strategies, utilities. Copyright 2020-2026 JusterZhu https://github.com/GeneralLibrary/GeneralUpdate https://github.com/GeneralLibrary/GeneralUpdate @@ -30,7 +30,6 @@ - diff --git a/src/c#/GeneralUpdate.Core/Ipc/IProcessInfoProvider.cs b/src/c#/GeneralUpdate.Core/Ipc/IProcessInfoProvider.cs index 26ddfd62..994b6c52 100644 --- a/src/c#/GeneralUpdate.Core/Ipc/IProcessInfoProvider.cs +++ b/src/c#/GeneralUpdate.Core/Ipc/IProcessInfoProvider.cs @@ -20,7 +20,6 @@ public interface IProcessInfoProvider /// /// AES-encrypted temporary file IPC — simplest, most reliable cross-platform approach. /// File lives in %TEMP%/GeneralUpdate/ipc/ with a random name, auto-deleted after read. -/// Encryption is delegated to . /// public class EncryptedFileProcessInfoProvider : IProcessInfoProvider { diff --git a/src/c#/GeneralUpdate.Core/Silent/SilentPollOrchestrator.cs b/src/c#/GeneralUpdate.Core/Silent/SilentPollOrchestrator.cs index 3ec758bd..527df4ac 100644 --- a/src/c#/GeneralUpdate.Core/Silent/SilentPollOrchestrator.cs +++ b/src/c#/GeneralUpdate.Core/Silent/SilentPollOrchestrator.cs @@ -23,7 +23,7 @@ namespace GeneralUpdate.Core.Silent; /// -/// Silent update poll orchestrator �?periodically checks for updates, +/// Silent update poll orchestrator — periodically checks for updates, /// downloads them in the background, and optionally auto-installs. /// Replaces the legacy SilentUpdateMode class. /// @@ -126,7 +126,7 @@ private async Task PrepareUpdateIfNeededAsync(CancellationToken token) return; } - // ══�?Hooks: allow cancellation before starting update ══�? + // ══— Hooks: allow cancellation before starting update ══— var updateCtx = new UpdateContext( _configInfo.MainAppName ?? _configInfo.AppName, _configInfo.InstallPath, @@ -173,7 +173,7 @@ private async Task PrepareUpdateIfNeededAsync(CancellationToken token) _configInfo.SkipDirectorys ?? BlackListDefaults.DefaultSkipDirectories); _configInfo.ProcessInfo = JsonSerializer.Serialize(_preparedProcessInfo, ProcessInfoJsonContext.Default.ProcessInfo); - // ══�?Reporter: update started ══�? + // ══— Reporter: update started ══— var startTime = DateTimeOffset.UtcNow; if (_reporter != null) { @@ -203,7 +203,7 @@ await _reporter.ReportAsync(new UpdateReport( downloadElapsed = report.TotalDuration; GeneralTracer.Info($"SilentPollOrchestrator: download complete. Success={downloadSuccessCount}, Failed={downloadFailedCount}"); - // ══�?Hooks + Reporter: download completed ══�? + // ══— Hooks + Reporter: download completed ══— if (_hooks != null) { try @@ -268,7 +268,7 @@ await _reporter.ReportAsync(new UpdateReport( GeneralTracer.Info("SilentPollOrchestrator: update prepared."); Interlocked.Exchange(ref _prepared, 1); - // ══�?Hooks + Reporter: update applied ══�? + // ══— Hooks + Reporter: update applied ══— if (_hooks != null) { try { await _hooks.OnAfterUpdateAsync(updateCtx).ConfigureAwait(false); } @@ -318,7 +318,7 @@ private void OnProcessExit(object? sender, EventArgs e) { var updaterPath = Path.Combine(_configInfo.InstallPath, _configInfo.AppName); - // Start the upgrade process first �?it will call ReceiveAsync in its constructor. + // Start the upgrade process first — it will call ReceiveAsync in its constructor. // We then call SendAsync which creates the NamedPipe server; the upgrade's // client connects to it. Auto-fallback (SharedMemory > EncryptedFile) handles // timing gaps where the named pipe handshake doesn't complete in time. diff --git a/src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs b/src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs index 31ec965b..ff9f0023 100644 --- a/src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs +++ b/src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs @@ -89,7 +89,7 @@ public ClientUpdateStrategy UseUpdatePrecheck(Func fu private async Task ExecuteWorkflowAsync() { - // Standard mode �?silent mode is handled by GeneralUpdateBootstrap.LaunchSilentAsync(). + // Standard mode — silent mode is handled by GeneralUpdateBootstrap.LaunchSilentAsync(). // Runtime options (Encoding, Format, DownloadTimeOut, etc.) are already // populated on _configInfo by Bootstrap.ApplyRuntimeOptions(). await ExecuteStandardWorkflowAsync(); @@ -185,7 +185,7 @@ private async Task ExecuteStandardWorkflowAsync() new EncryptedFileProcessInfoProvider().Send(processInfo); GeneralTracer.Info("ClientUpdateStrategy: ProcessInfo sent via encrypted file IPC."); - // Backup �?conditionally skipped when BackupEnabled is false + // Backup — conditionally skipped when BackupEnabled is false if (_configInfo.BackupEnabled != false) { Backup(); @@ -197,7 +197,7 @@ private async Task ExecuteStandardWorkflowAsync() _osStrategy!.Create(_configInfo); - // Download via orchestrator �?wired with options from GlobalConfigInfo + // Download via orchestrator — wired with options from GlobalConfigInfo var orchOptions = Download.Models.DownloadOrchestratorOptions.From(_configInfo); GeneralTracer.Info($"ClientUpdateStrategy: downloading {downloadPlan.Assets.Count} asset(s)."); if (_orchestrator != null) diff --git a/src/c#/GeneralUpdate.Core/Strategy/OSSUpdateStrategy.cs b/src/c#/GeneralUpdate.Core/Strategy/OSSUpdateStrategy.cs index 89496404..eb393935 100644 --- a/src/c#/GeneralUpdate.Core/Strategy/OSSUpdateStrategy.cs +++ b/src/c#/GeneralUpdate.Core/Strategy/OSSUpdateStrategy.cs @@ -6,7 +6,6 @@ using System.Net.Http; using System.Text; using System.Text.Json; -using System.Threading; using System.Threading.Tasks; using GeneralUpdate.Core.Compress; using GeneralUpdate.Core.Configuration; @@ -17,11 +16,11 @@ namespace GeneralUpdate.Core.Strategy; /// -/// OSS (Object Storage Service) update strategy �?client/upgrade split via AppType. +/// OSS (Object Storage Service) update strategy — client/upgrade split via AppType. /// -/// �?downloads version config, checks for updates, +/// — downloads version config, checks for updates, /// starts the upgrade process, and exits. -/// �?reads version config, downloads packages from OSS, +/// — reads version config, downloads packages from OSS, /// decompresses them, starts the main app, and exits. /// /// @@ -52,7 +51,7 @@ public async Task ExecuteAsync() if (_configInfo == null) throw new InvalidOperationException("OSSUpdateStrategy not configured. Call Create() first."); - // Dispatch by role �?no env-var detection needed. + // Dispatch by role — no env-var detection needed. if (_role == AppType.OSSUpgrade) { await ExecuteUpgradeAsync(); @@ -241,11 +240,12 @@ private async Task DownloadAssetsAsync(List assets) } else { - using var httpClient = GeneralUpdate.Core.Network.HttpClientProvider.Shared; - using var cts = new CancellationTokenSource( - TimeSpan.FromSeconds(_configInfo?.DownloadTimeOut > 0 ? _configInfo!.DownloadTimeOut : DefaultTimeOut)); + using var httpClient = new HttpClient + { + Timeout = TimeSpan.FromSeconds(_configInfo?.DownloadTimeOut > 0 ? _configInfo!.DownloadTimeOut : DefaultTimeOut) + }; var orchestrator = new DefaultDownloadOrchestrator(httpClient); - await orchestrator.ExecuteAsync(plan, _appPath, token: cts.Token).ConfigureAwait(false); + await orchestrator.ExecuteAsync(plan, _appPath).ConfigureAwait(false); } } diff --git a/src/c#/GeneralUpdate.Differential/Matchers/DefaultDirtyStrategy.cs b/src/c#/GeneralUpdate.Differential/Matchers/DefaultDirtyStrategy.cs index 787e51fc..7bb6b755 100644 --- a/src/c#/GeneralUpdate.Differential/Matchers/DefaultDirtyStrategy.cs +++ b/src/c#/GeneralUpdate.Differential/Matchers/DefaultDirtyStrategy.cs @@ -52,7 +52,7 @@ public async Task ExecuteAsync(string appPath, string patchPath) { if (!Directory.Exists(appPath) || !Directory.Exists(patchPath)) return; - var skipDirectory = BlackListManager.Instance.SkipDirectorys.ToList(); + var skipDirectory = BlackListDefaults.DefaultSkipDirectories; var patchFiles = StorageManager.GetAllFiles(patchPath, skipDirectory); var oldFiles = StorageManager.GetAllFiles(appPath, skipDirectory); HandleDeleteList(patchFiles, oldFiles); @@ -128,7 +128,7 @@ await Task.Run(() => foreach (var file in comparisonResult.DifferentNodes) { var extensionName = Path.GetExtension(file.FullName); - if (BlackListManager.Instance.IsBlacklisted(extensionName)) continue; + if (BlackListDefaults.DefaultBlackFormats.Contains(extensionName)) continue; var targetFileName = file.FullName.Replace(patchPath, "").TrimStart(Path.DirectorySeparatorChar); var targetPath = Path.Combine(appPath, targetFileName); diff --git a/src/c#/GeneralUpdate.Differential/Pipeline/DiffPipeline.cs b/src/c#/GeneralUpdate.Differential/Pipeline/DiffPipeline.cs index bc853898..539c411b 100644 --- a/src/c#/GeneralUpdate.Differential/Pipeline/DiffPipeline.cs +++ b/src/c#/GeneralUpdate.Differential/Pipeline/DiffPipeline.cs @@ -172,7 +172,7 @@ public async Task DirtyAsync( var reporter = progress ?? _progress; if (!Directory.Exists(appPath) || !Directory.Exists(patchPath)) return; - var skipDirectory = BlackListManager.Instance.SkipDirectorys.ToList(); + var skipDirectory = BlackListDefaults.DefaultSkipDirectories; var patchFiles = StorageManager.GetAllFiles(patchPath, skipDirectory).ToList(); var oldFiles = StorageManager.GetAllFiles(appPath, skipDirectory).ToList(); @@ -284,7 +284,7 @@ private static Task CopyUnknownFiles(string appPath, string patchPath) foreach (var file in comparisonResult.DifferentNodes) { var extensionName = Path.GetExtension(file.FullName); - if (BlackListManager.Instance.IsBlacklisted(extensionName)) continue; + if (BlackListDefaults.DefaultBlackFormats.Contains(extensionName)) continue; var targetFileName = file.FullName.Replace(patchPath, "").TrimStart(Path.DirectorySeparatorChar); var targetPath = Path.Combine(appPath, targetFileName); diff --git a/tests/CoreTest/Bootstrap/ParameterMatrixAndEventTests.cs b/tests/CoreTest/Bootstrap/ParameterMatrixAndEventTests.cs index f712bbd4..0c15789d 100644 --- a/tests/CoreTest/Bootstrap/ParameterMatrixAndEventTests.cs +++ b/tests/CoreTest/Bootstrap/ParameterMatrixAndEventTests.cs @@ -264,25 +264,26 @@ public void Configinfo_WithBlackLists_ValidatesSuccessfully() [Fact] public void BlackListManager_VariousConfigurations_AcceptsAllRules() { - var manager = BlackListManager.Instance; + var manager = new DefaultBlackListMatcher(BlackListConfig.Empty); Assert.NotNull(manager); - Assert.NotNull(manager.BlackFiles); - Assert.NotNull(manager.BlackFormats); - Assert.NotNull(manager.SkipDirectorys); + Assert.NotNull(BlackListDefaults.DefaultBlackFiles); + Assert.NotNull(BlackListDefaults.DefaultBlackFormats); + Assert.NotNull(BlackListDefaults.DefaultSkipDirectories); + Assert.False(manager.IsBlacklisted("test.dll")); } [Fact] public void BlackListManager_EmptyLists_DoesNotThrow() { - var manager = BlackListManager.Instance; + var manager = new DefaultBlackListMatcher(BlackListConfig.Empty); Assert.NotNull(manager); } [Fact] public void BlackListManager_NullList_DoesNotThrow() { - var manager = BlackListManager.Instance; + var manager = new DefaultBlackListMatcher(BlackListConfig.Empty); Assert.NotNull(manager); }