Skip to main content

πŸ”§ GeneralUpdate Advanced Customization Reference

Covers extension point architecture, Pipeline, differential engine, Bowl crash daemon, event system, and filesystem tools.

⚠️ API Version Note: This guide is based on NuGet v10.5.0-beta.7. All the following features are available in v10.5.0-beta.7:

  • βœ… IUpdateHooks lifecycle hooks (Hooks<T>())
  • βœ… IStrategy custom strategy injection (Strategy<T>())
  • βœ… SilentPollOrchestrator silent poller (Option.Silent)
  • βœ… Option programmable config system
  • βœ… ISslValidationPolicy SSL policy interface
  • βœ… IHttpAuthProvider HTTP auth provider
  • βœ… DiffPipelineBuilder differential pipeline config

Namespace and usage for each feature is noted in each section.


πŸ“‹ User Requirements Gathering​

### Customization Target (Required)
- What customization is needed: ______ (Bowl crash daemon / IPC replacement / Pipeline customization / Custom strategy / AOT / Drivelution / Blacklist / Auth provider / Differential engine)
- GeneralUpdate version used: ______ (v10.4.6 stable / v10.5.0+ dev)
- .NET version: ______ (.NET 6/8/9/10)

### Bowl (if selected)
- Monitored process name: ______
- Work mode: ______ (Normal / Upgrade)
- Need crash Dump: ______ (Yes/No)
- Backup directory path: ______

### IPC Replacement (if selected)
- Replacement method: ______ (NamedPipe / SharedMemory / Custom)
- Target platform: ______ (Windows / Linux / macOS / Cross-platform)
- Security requirements: ______ (Encryption / Signing / None)

### AOT (if selected)
- Current trim warnings: ______ (Yes/No)
- Using reflection: ______ (Yes/No)
- JSON serialization needs: ______ (Yes/No)

1. Pipeline System (v10.5.0-beta.7 available)​

GeneralUpdate uses the Pipeline pattern for update package verification, extraction, and patch application.

PipelineBuilder API​

using GeneralUpdate.Core.Pipeline;

var context = new PipelineContext();
context.Add("ZipFilePath", @"C:\temp\update.zip");
context.Add("Hash", "sha256-hex-value");
context.Add("Format", 0); // 0=Zip
context.Add("Encoding", System.Text.Encoding.UTF8);
context.Add("SourcePath", @"C:\Program Files\MyApp");
context.Add("PatchEnabled", true);

await new PipelineBuilder(context)
.UseMiddleware<HashMiddleware>() // Hash verification
.UseMiddleware<CompressMiddleware>() // Extraction
.UseMiddleware<PatchMiddleware>() // Differential patch
.Build();
MiddlewareClassNamespaceFunction
Hash verificationHashMiddlewareGeneralUpdate.Core.PipelineSHA256 integrity check
ExtractionCompressMiddlewareGeneralUpdate.Core.PipelineZIP extraction
Differential patchPatchMiddlewareGeneralUpdate.Core.PipelineApply BSDIFF/HDiffPatch patches
Driver updateDrivelutionMiddlewareGeneralUpdate.Core.PipelineWindows driver installation

2. Strategy System (v10.5.0-beta.7 available)​

GeneralUpdate has three built-in platform strategies via the IStrategy interface:

StrategyClassPlatform
WindowsWindowsStrategyWindows
LinuxLinuxStrategyLinux
OSSOSSStrategyCross-platform (object storage)

βœ… Supports custom strategy injection via bootstrap.Strategy<T>(). Custom strategies need to implement the IStrategy interface.


3. Bowl Crash Daemon (v10.5.0-beta.7)​

Bowl is a crash monitoring component configured via BowlContext.

using GeneralUpdate.Bowl;

var context = new BowlContext
{
ProcessNameOrId = "MyApp.exe",
DumpFileName = "v1.0.0.0_fail.dmp",
FailFileName = "v1.0.0.0_fail.json",
TargetPath = @"C:\Program Files\MyApp",
FailDirectory = @"C:\Program Files\MyApp\fail",
BackupDirectory = @"C:\Program Files\MyApp\backup",
WorkModel = "Upgrade",
TimeoutMs = 30_000,
AutoRestore = true,
OnCrash = async (info, ct) => Console.WriteLine($"Crash: {info.DumpFilePath}"),
};

var bowl = new Bowl();
var result = await bowl.LaunchAsync(context);
Console.WriteLine($"Result: Success={result.Success}, Restored={result.Restored}");
PropertyTypeDescription
ProcessNameOrIdstringMonitored process name or PID (required)
TargetPathstringApp install root directory (required)
DumpFileNamestringDump file name (required)
FailFileNamestringFailure report file name (required)
FailDirectorystringCrash report output directory (required)
BackupDirectorystringBackup directory (required)
WorkModelstring"Upgrade" or "Normal"
TimeoutMsintMonitor timeout(ms), default 30000
AutoRestoreboolAuto-rollback on crash
DumpTypeDumpTypeMini / Full
OnCrashdelegateCrash callback

⚠️ In NuGet v10.5.0-beta.7, Bowl and Core have no type conflicts and can be referenced together.


4. EventManager (v10.5.0-beta.7 available)​

EventManager is a global singleton providing event publish/subscribe:

using GeneralUpdate.Core.Event;

// Add listener
EventManager.Instance.AddListener((object? sender, UpdateInfoEventArgs e) => { });

// Dispatch event manually
EventManager.Instance.Dispatch(this, new ExceptionEventArgs(ex, "Custom error"));

// Clear all listeners
EventManager.Instance.Clear();

// Dispose
EventManager.Instance.Dispose();

⚠️ EventManager is a global singleton. After Dispose(), Instance is still accessible (found by code audit).


5. Filesystem Tools (v10.5.0-beta.7 available)​

BlackList​

UpdateRequest supports file exclusion through these properties:

var config = new UpdateRequest
{
// ...
Files = new List<string> { "*.log", "*.tmp" },
Formats = new List<string> { ".pdb", ".vshost.exe" },
Directories = new List<string> { "logs", "cache", "temp" },
};

The blacklist is internally converted to BlackPolicy records via ToBlackPolicy().

FileTree (File Tree Diff)​

using GeneralUpdate.Core.FileSystem;

var tree = new FileTree();
var snapshot = tree.CreateSnapshot(@"C:\Program Files\MyApp");

6. Differential Engine (v10.5.0-beta.7 available, no extra package needed)​

Differential types are embedded in GeneralUpdate.Core, no need for a separate GeneralUpdate.Differential package.

using GeneralUpdate.Core.Pipeline;

var pipeline = new DiffPipelineBuilder()
.UseDiffer(new StreamingHdiffDiffer()) // Diff algorithm
.UseCleanMatcher(new DefaultCleanMatcher()) // File matcher (server side)
.UseDirtyMatcher(new DefaultDirtyMatcher()) // File matcher (client side)
.WithParallelism(4)
.WithStopOnFirstError(true)
.WithProgress(new Progress<DiffProgress>(p =>
Console.WriteLine($"[{p.Completed}/{p.Total}] {p.FileName}")))
.Build();

// Server side: generate patches
await pipeline.CleanAsync(oldDir, newDir, patchDir);

// Client side: apply patches
await pipeline.DirtyAsync(appDir, patchDir);

Bootstrap Integration​

new GeneralUpdateBootstrap()
.SetConfig(config)
.UseDiffPipeline(pipeline =>
{
pipeline.WithParallelism(2)
.WithStopOnFirstError(true);
})
.LaunchAsync();

Custom Matchers​

using GeneralUpdate.Core.Differential;

var cleanMatcher = new DefaultCleanMatcher(); // or implement ICleanMatcher
var dirtyMatcher = new DefaultDirtyMatcher(); // or implement IDirtyMatcher

7. AOT / NativeAOT Compatibility​

GeneralUpdate.Core v10.5.0-beta.7 supports .NET Native AOT (net8.0 and net10.0):

<PropertyGroup>
<IsAotCompatible>true</IsAotCompatible>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>

JSON serialization contexts (reduce AOT size):

using GeneralUpdate.Core.JsonContext;

// Use built-in JsonSerializerContext
// VersionRespJsonContext, ProcessContractJsonContext, HttpParameterJsonContext etc.

8. Drivelution (Windows Driver Updates)​

The GeneralUpdate.Drivelution package provides Windows driver management:

using GeneralUpdate.Drivelution;

// Scan driver directory
var allDrivers = GeneralDrivelution.ScanDirectory(driverDir);

// Validate driver
var isValid = GeneralDrivelution.ValidateDriver(driverPath);

// Install driver (DIFx β†’ SetupAPI β†’ PnPUtil cascade)
var result = GeneralDrivelution.InstallDriver(driverPath);

Feature Availability Index​

FeatureAvailabilityReference
Pipelineβœ… v10.5.0-beta.7GeneralUpdate.Core.Pipeline
Strategy Systemβœ… v10.5.0-beta.7GeneralUpdate.Core.Strategy
FileTreeβœ… v10.5.0-beta.7GeneralUpdate.Core.FileSystem
BlackListβœ… v10.5.0-beta.7UpdateRequest.Files/Formats/Directories β†’ ToBlackPolicy()
Differential Engineβœ… Embedded in CoreDiffPipelineBuilder / DiffPipeline
AOTβœ… v10.5.0-beta.7JsonSerializerContext subclasses
EventManagerβœ… v10.5.0-beta.7GeneralUpdate.Core.Event
Bowl Crash Daemonβœ… v10.5.0-beta.7GeneralUpdate.Bowl.Bowl
IUpdateHooksβœ… v10.5.0-beta.7GeneralUpdate.Core.Hooks β€” Hooks<T>()
Custom Strategy Injectionβœ… v10.5.0-beta.7Strategy<T>()
IPC Replacement Interface❌ Not yet supportedUse NamedPipe alternative
SilentPollOrchestratorβœ… v10.5.0-beta.7Option.Silent + SetOption()
Option Systemβœ… v10.5.0-beta.7SetOption<T>(Option<T>, T)

βœ… Advanced Customization Verification Checklist​

Bowl Crash Daemon​

  • With Bowl: reference both GeneralUpdate.Core and GeneralUpdate.Bowl (no conflict in v10.5.0-beta.7)
  • BowlContext.ProcessNameOrId matches the actual process name
  • TargetPath set to app install root directory, not a subdirectory
  • WorkModel correct for the scenario (Normal/Upgrade)
  • FailDirectory has write permissions
  • Linux/macOS: Bowl is Windows-only

Pipeline Customization​

  • PipelineContext key names spelled correctly
  • Middleware order correct: Hash β†’ Compress β†’ Patch β†’ Drivelution
  • Encoding set to Encoding.UTF8

AOT/NativeAOT​

  • Enabled <IsAotCompatible>true</IsAotCompatible>
  • Added [DynamicDependency] or [RequiresUnreferencedCode] for reflection paths
  • Used built-in JsonSerializerContext subclasses (reduce trimming)

⚠️ Anti-Pattern Checklist​

#Anti-PatternConsequenceCorrect Approach
1Using dev-branch APIs (IUpdateHooks etc.) on v10.4.6 stableBuild failure / MissingMethodExceptionCheck API availability table
2PipelineContext key spelling errorsPipeline runs abnormally, values not passedUse library constants or documented key names
3Bowl WorkModel set to Upgrade but process is main appMonitoring logic errorNormal=main process, Upgrade=upgrade process
4Using default encryption key for IPC on WindowsEncryption can be crackedUse strong key (β‰₯ 32 chars)
5Different source file structure when generating patchesPatch application failsSource and target file structure must be consistent
6Heavy reflection in AOT without DynamicDependencyTypeLoadException at runtimeUse source generators or explicit preserve markers
7PatchMiddleware before CompressMiddleware in PipelineTrying to patch without extractionOrder must be Compress→Patch

  • /generalupdate-init β€” Bootstrap configuration
  • /generalupdate-strategy β€” Strategy selection
  • /generalupdate-troubleshoot β€” Issue diagnosis