@@ -65,6 +65,7 @@ public void Cancel()
6565 public override async Task < GeneralUpdateBootstrap > LaunchAsync ( )
6666 {
6767 var appType = GetOption ( UpdateOptions . AppType ) ;
68+ _configInfo . AppType = appType ;
6869
6970 // Silent mode: start background poll and return immediately
7071 if ( appType == AppType . Client && GetOption ( UpdateOptions . Silent ) )
@@ -75,9 +76,9 @@ public override async Task<GeneralUpdateBootstrap> LaunchAsync()
7576
7677 return appType switch
7778 {
78- AppType . Client => await LaunchWithStrategy ( new ClientUpdateStrategy ( ) ) ,
79+ AppType . Client => await LaunchWithStrategy ( new ClientUpdateStrategy ( ) ) ,
7980 AppType . Upgrade => await LaunchWithStrategy ( new UpgradeUpdateStrategy ( ) ) ,
80- AppType . OSSClient => await LaunchWithStrategy ( new OSSUpdateStrategy ( AppType . OSSClient ) ) ,
81+ AppType . OSSClient => await LaunchWithStrategy ( new OSSUpdateStrategy ( AppType . OSSClient ) ) ,
8182 AppType . OSSUpgrade => await LaunchWithStrategy ( new OSSUpdateStrategy ( AppType . OSSUpgrade ) ) ,
8283 _ => await LaunchWithStrategy ( new ClientUpdateStrategy ( ) )
8384 } ;
@@ -94,68 +95,40 @@ private async Task<GeneralUpdateBootstrap> LaunchWithStrategy(IStrategy roleStra
9495
9596 // Resolve hooks and reporter from extensions
9697 var hooks = ResolveExtension < Hooks . IUpdateHooks > ( ) ?? new Hooks . NoOpUpdateHooks ( ) ;
97- var reporter = ResolveExtension < Download . Reporting . IUpdateReporter > ( ) ?? new Download . Reporting . NoOpUpdateReporter ( ) ;
98+ var reporter = ResolveExtension < Download . Reporting . IUpdateReporter > ( ) ??
99+ new Download . Reporting . NoOpUpdateReporter ( ) ;
98100
99- // Configure client-specific callbacks
100- if ( roleStrategy is ClientUpdateStrategy clientStrat )
101- {
102- clientStrat . Hooks = hooks ;
103- clientStrat . Reporter = reporter ;
104- // Resolve DownloadSource from extension registry (Hub, custom, etc.)
105- var resolvedSource = ResolveExtension < Download . Abstractions . IDownloadSource > ( ) ;
106-
107- // Inject SignalR Hub download source if configured
108- if ( resolvedSource == null )
109- {
110- var hubConfig = GetOption ( UpdateOptions . Hub ) ;
111- if ( hubConfig != null && ! string . IsNullOrEmpty ( hubConfig . Url ) )
112- {
113- var hubSource = new Download . Sources . HubDownloadSource (
114- hubConfig . Url , _configInfo . Token , _configInfo . AppSecretKey ) ;
115- await hubSource . StartAsync ( ) . ConfigureAwait ( false ) ;
116- resolvedSource = hubSource ;
117- GeneralTracer . Info ( "GeneralUpdateBootstrap: HubDownloadSource started from HubConfig." ) ;
118- }
119- }
120- clientStrat . DownloadSource = resolvedSource ;
121- if ( _updatePrecheck != null )
122- clientStrat . UseUpdatePrecheck ( _updatePrecheck ) ;
123- await CallSmallBowlHomeAsync ( _configInfo . Bowl ) . ConfigureAwait ( false ) ;
124- }
125- else if ( roleStrategy is UpgradeUpdateStrategy upgradeStrat )
126- {
127- upgradeStrat . Hooks = hooks ;
128- upgradeStrat . Reporter = reporter ;
129- }
130- else if ( roleStrategy is OSSUpdateStrategy ossStrat )
131- {
132- ossStrat . Hooks = hooks ;
133- ossStrat . Reporter = reporter ;
134- }
101+ // ── Phase 1: inject all dependencies before Create ──
102+ roleStrategy . Hooks = hooks ;
103+ roleStrategy . Reporter = reporter ;
135104
136- roleStrategy . Create ( _configInfo ) ;
137-
138105 var binaryDiffer = ResolveExtension < IBinaryDiffer > ( ) ;
139106 var dirtyStrategy = ResolveExtension < IDirtyStrategy > ( ) ;
107+ var diffPipeline = BuildDiffPipeline ( ) ;
140108
141- if ( roleStrategy is ClientUpdateStrategy cs2 )
142- {
143- if ( binaryDiffer != null ) cs2 . SetBinaryDiffer ( binaryDiffer ) ;
144- if ( dirtyStrategy != null ) cs2 . SetDirtyStrategy ( dirtyStrategy ) ;
145- }
146- else if ( roleStrategy is UpgradeUpdateStrategy us2 )
109+ switch ( roleStrategy )
147110 {
148- if ( binaryDiffer != null ) us2 . SetBinaryDiffer ( binaryDiffer ) ;
149- if ( dirtyStrategy != null ) us2 . SetDirtyStrategy ( dirtyStrategy ) ;
111+ case ClientUpdateStrategy cs :
112+ cs . DownloadSource = ResolveExtension < Download . Abstractions . IDownloadSource > ( ) ;
113+
114+ if ( _updatePrecheck != null )
115+ cs . UseUpdatePrecheck ( _updatePrecheck ) ;
116+
117+ await CallSmallBowlHomeAsync ( _configInfo . Bowl ) . ConfigureAwait ( false ) ;
118+
119+ if ( binaryDiffer != null ) cs . SetBinaryDiffer ( binaryDiffer ) ;
120+ if ( dirtyStrategy != null ) cs . SetDirtyStrategy ( dirtyStrategy ) ;
121+ cs . SetDiffPipeline ( diffPipeline ) ;
122+ break ;
123+
124+ case UpgradeUpdateStrategy us :
125+ if ( binaryDiffer != null ) us . SetBinaryDiffer ( binaryDiffer ) ;
126+ if ( dirtyStrategy != null ) us . SetDirtyStrategy ( dirtyStrategy ) ;
127+ us . SetDiffPipeline ( diffPipeline ) ;
128+ break ;
150129 }
151130
152- // Build DiffPipeline — user‑configured or default with BsdiffDiffer,
153- // parallelism=2, and progress reporter wired to AddListenerProgress.
154- var diffPipeline = BuildDiffPipeline ( ) ;
155- if ( roleStrategy is ClientUpdateStrategy cs3 )
156- cs3 . SetDiffPipeline ( diffPipeline ) ;
157- else if ( roleStrategy is UpgradeUpdateStrategy us3 )
158- us3 . SetDiffPipeline ( diffPipeline ) ;
131+ roleStrategy . Create ( _configInfo ) ;
159132
160133 // Check custom skip condition before executing update
161134 if ( _customSkipOption ? . Invoke ( ) == true )
@@ -173,24 +146,21 @@ private async Task<GeneralUpdateBootstrap> LaunchWithStrategy(IStrategy roleStra
173146 }
174147 finally
175148 {
176- // Dispose HubDownloadSource if it was started
177- if ( roleStrategy is ClientUpdateStrategy cs && cs . DownloadSource is IAsyncDisposable ad )
178- await ad . DisposeAsync ( ) ;
179149 _cts ? . Dispose ( ) ;
180150 _cts = null ;
181151 }
152+
182153 return this ;
183154 }
184-
185-
155+
186156 // ════════════════════════════════════════════════════════════════
187157 // Configuration
188158 // ════════════════════════════════════════════════════════════════
189159
190160 public GeneralUpdateBootstrap SetConfig ( Configinfo configInfo )
191- {
192- configInfo . Validate ( ) ;
193- _configInfo = ConfigurationMapper . MapToGlobalConfigInfo ( configInfo ) ;
161+ {
162+ configInfo . Validate ( ) ;
163+ _configInfo = ConfigurationMapper . MapToGlobalConfigInfo ( configInfo ) ;
194164
195165 var appType = GetOption ( UpdateOptions . AppType ) ;
196166 if ( appType != AppType . Upgrade )
@@ -223,7 +193,7 @@ public GeneralUpdateBootstrap SetConfig(string filePath)
223193
224194 // Resolve filename-only paths to current directory
225195 var hasPathChar = filePath . Contains ( Path . DirectorySeparatorChar )
226- || filePath . Contains ( Path . AltDirectorySeparatorChar ) ;
196+ || filePath . Contains ( Path . AltDirectorySeparatorChar ) ;
227197 var fullPath = hasPathChar
228198 ? Path . GetFullPath ( filePath )
229199 : Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , filePath ) ;
@@ -277,16 +247,18 @@ private void InitializeFromEnvironment()
277247 LastVersion = processInfo . LastVersion ,
278248 UpdateLogUrl = processInfo . UpdateLogUrl ,
279249 Encoding = Encoding . GetEncoding ( processInfo . CompressEncoding ) ,
280- Format = processInfo . CompressFormat ,
250+ Format = ParseFormat ( processInfo . CompressFormat ) ,
281251 DownloadTimeOut = processInfo . DownloadTimeOut ,
282252 AppSecretKey = processInfo . AppSecretKey ,
283253 UpdateVersions = processInfo . UpdateVersions ,
284- TempPath = StorageManager . GetTempDirectory ( "upgrade_temp" ) ,
254+ TempPath = processInfo . TempPath ,
285255 ReportUrl = processInfo . ReportUrl ,
286256 BackupDirectory = processInfo . BackupDirectory ,
287257 Scheme = processInfo . Scheme ,
288258 Token = processInfo . Token ,
289259 DriverDirectory = processInfo . DriverDirectory ,
260+ UpdatePath = processInfo . UpdatePath ,
261+ LaunchClientAfterUpdate = processInfo . LaunchClientAfterUpdate ,
290262 BlackFiles = processInfo . BlackFiles ?? BlackListDefaults . DefaultBlackFiles ,
291263 BlackFormats = processInfo . BlackFileFormats ?? BlackListDefaults . DefaultBlackFormats ,
292264 SkipDirectorys = processInfo . SkipDirectorys ?? BlackListDefaults . DefaultSkipDirectories
@@ -306,11 +278,7 @@ private void ApplyRuntimeOptions()
306278 {
307279 // Preserve Upgrade path values set by InitializeFromEnvironment()
308280 _configInfo . Encoding ??= GetOption ( UpdateOptions . Encoding ) ;
309- _configInfo . Format ??= GetOption ( UpdateOptions . Format ) ;
310- // Normalize legacy "ZIP" default (UpdateOptions) to Format.ZIP (".zip")
311- // so the pipeline constructs correct paths and CompressProvider matches its switch.
312- if ( _configInfo . Format == "ZIP" )
313- _configInfo . Format = Format . ZIP ;
281+ _configInfo . Format = GetOption ( UpdateOptions . Format ) ;
314282 if ( _configInfo . DownloadTimeOut <= 0 )
315283 _configInfo . DownloadTimeOut = GetOption ( UpdateOptions . DownloadTimeout ) ?? 60 ;
316284
@@ -338,16 +306,15 @@ private async Task LaunchSilentAsync()
338306 GeneralTracer . Info ( "GeneralUpdateBootstrap: starting silent update mode." ) ;
339307
340308 var pollMinutes = GetOption ( UpdateOptions . SilentPollIntervalMinutes ) ;
341- var autoInstall = GetOption ( UpdateOptions . SilentAutoInstall ) ;
342309
343310 var silentOptions = new Silent . SilentOptions
344311 {
345- PollInterval = TimeSpan . FromMinutes ( pollMinutes ) ,
346- AutoInstall = autoInstall
312+ PollInterval = TimeSpan . FromMinutes ( pollMinutes )
347313 } ;
348314
349315 var hooks = ResolveExtension < Hooks . IUpdateHooks > ( ) ?? new Hooks . NoOpUpdateHooks ( ) ;
350- var reporter = ResolveExtension < Download . Reporting . IUpdateReporter > ( ) ?? new Download . Reporting . NoOpUpdateReporter ( ) ;
316+ var reporter = ResolveExtension < Download . Reporting . IUpdateReporter > ( ) ??
317+ new Download . Reporting . NoOpUpdateReporter ( ) ;
351318
352319 var orchestrator = new Silent . SilentPollOrchestrator ( _configInfo , silentOptions )
353320 . WithHooks ( hooks )
@@ -371,14 +338,26 @@ private DiffPipeline BuildDiffPipeline()
371338 . Build ( ) ;
372339 }
373340
341+ private static Format ParseFormat ( string ? compressFormat )
342+ {
343+ if ( string . IsNullOrWhiteSpace ( compressFormat ) ) return Format . Zip ;
344+ return compressFormat switch
345+ {
346+ ".zip" => Format . Zip ,
347+ _ => Format . Zip
348+ } ;
349+ }
350+
374351 private void InitBlackList ( )
375352 {
376353 // Build blacklist matcher from GlobalConfigInfo and set on StorageManager.
377354 // The matcher combines user config with system defaults.
378355 var effectiveConfig = new BlackListConfig (
379356 _configInfo . BlackFiles ? . Count > 0 ? _configInfo . BlackFiles : BlackListDefaults . DefaultBlackFiles ,
380357 _configInfo . BlackFormats ? . Count > 0 ? _configInfo . BlackFormats : BlackListDefaults . DefaultBlackFormats ,
381- _configInfo . SkipDirectorys ? . Count > 0 ? _configInfo . SkipDirectorys : BlackListDefaults . DefaultSkipDirectories
358+ _configInfo . SkipDirectorys ? . Count > 0
359+ ? _configInfo . SkipDirectorys
360+ : BlackListDefaults . DefaultSkipDirectories
382361 ) ;
383362 StorageManager . BlackListMatcher = new DefaultBlackListMatcher ( effectiveConfig ) ;
384363 }
@@ -449,4 +428,4 @@ public GeneralUpdateBootstrap AddListenerProgress(
449428 AddListener < ProgressEventArgs > ( ( s , e ) => listener . OnProgress ( e ) ) ;
450429 return this ;
451430 }
452- }
431+ }
0 commit comments