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);
}