@@ -31,6 +31,8 @@ use crate::{
31
31
Config ,
32
32
} ;
33
33
34
+ const UPDATER_USER_AGENT : & str = concat ! ( env!( "CARGO_PKG_NAME" ) , "/" , env!( "CARGO_PKG_VERSION" ) , ) ;
35
+
34
36
#[ derive( Debug , Deserialize , Serialize , Clone ) ]
35
37
pub struct ReleaseManifestPlatform {
36
38
/// Download URL for the platform
@@ -102,6 +104,7 @@ pub struct UpdaterBuilder {
102
104
timeout : Option < Duration > ,
103
105
proxy : Option < Url > ,
104
106
installer_args : Vec < OsString > ,
107
+ nsis_installer_args : Vec < OsString > ,
105
108
on_before_exit : Option < OnBeforeExit > ,
106
109
}
107
110
@@ -113,6 +116,7 @@ impl UpdaterBuilder {
113
116
. as_ref ( )
114
117
. map ( |w| w. installer_args . clone ( ) )
115
118
. unwrap_or_default ( ) ,
119
+ nsis_installer_args : Vec :: new ( ) ,
116
120
current_version,
117
121
config,
118
122
version_comparator : None ,
@@ -241,6 +245,7 @@ impl UpdaterBuilder {
241
245
proxy : self . proxy ,
242
246
endpoints,
243
247
installer_args : self . installer_args ,
248
+ nsis_installer_args : self . nsis_installer_args ,
244
249
arch,
245
250
target,
246
251
json_target,
@@ -251,15 +256,33 @@ impl UpdaterBuilder {
251
256
}
252
257
}
253
258
259
+ impl UpdaterBuilder {
260
+ pub ( crate ) fn nsis_installer_arg < S > ( mut self , arg : S ) -> Self
261
+ where
262
+ S : Into < OsString > ,
263
+ {
264
+ self . nsis_installer_args . push ( arg. into ( ) ) ;
265
+ self
266
+ }
267
+
268
+ pub ( crate ) fn nsis_installer_args < I , S > ( mut self , args : I ) -> Self
269
+ where
270
+ I : IntoIterator < Item = S > ,
271
+ S : Into < OsString > ,
272
+ {
273
+ let args = args. into_iter ( ) . map ( |a| a. into ( ) ) . collect :: < Vec < _ > > ( ) ;
274
+ self . nsis_installer_args . extend_from_slice ( & args) ;
275
+ self
276
+ }
277
+ }
278
+
254
279
pub struct Updater {
255
280
config : Config ,
256
281
current_version : Version ,
257
282
version_comparator : Option < Box < dyn Fn ( Version , RemoteRelease ) -> bool + Send + Sync > > ,
258
283
timeout : Option < Duration > ,
259
284
proxy : Option < Url > ,
260
285
endpoints : Vec < Url > ,
261
- #[ allow( dead_code) ]
262
- installer_args : Vec < OsString > ,
263
286
arch : & ' static str ,
264
287
// The `{{target}}` variable we replace in the endpoint
265
288
target : String ,
@@ -268,6 +291,10 @@ pub struct Updater {
268
291
headers : HeaderMap ,
269
292
extract_path : PathBuf ,
270
293
on_before_exit : Option < OnBeforeExit > ,
294
+ #[ allow( unused) ]
295
+ installer_args : Vec < OsString > ,
296
+ #[ allow( unused) ]
297
+ nsis_installer_args : Vec < OsString > ,
271
298
}
272
299
273
300
impl Updater {
@@ -312,7 +339,7 @@ impl Updater {
312
339
. replace ( "{{arch}}" , self . arch )
313
340
. parse ( ) ?;
314
341
315
- let mut request = ClientBuilder :: new ( ) ;
342
+ let mut request = ClientBuilder :: new ( ) . user_agent ( UPDATER_USER_AGENT ) ;
316
343
if let Some ( timeout) = self . timeout {
317
344
request = request. timeout ( timeout) ;
318
345
}
@@ -370,7 +397,6 @@ impl Updater {
370
397
current_version : self . current_version . to_string ( ) ,
371
398
target : self . target . clone ( ) ,
372
399
extract_path : self . extract_path . clone ( ) ,
373
- installer_args : self . installer_args . clone ( ) ,
374
400
version : release. version . to_string ( ) ,
375
401
date : release. pub_date ,
376
402
download_url : release. download_url ( & self . json_target ) ?. to_owned ( ) ,
@@ -379,6 +405,8 @@ impl Updater {
379
405
timeout : self . timeout ,
380
406
proxy : self . proxy . clone ( ) ,
381
407
headers : self . headers . clone ( ) ,
408
+ installer_args : self . installer_args . clone ( ) ,
409
+ nsis_installer_args : self . nsis_installer_args . clone ( ) ,
382
410
} )
383
411
} else {
384
412
None
@@ -403,11 +431,6 @@ pub struct Update {
403
431
pub date : Option < OffsetDateTime > ,
404
432
/// Target
405
433
pub target : String ,
406
- /// Extract path
407
- #[ allow( unused) ]
408
- extract_path : PathBuf ,
409
- #[ allow( unused) ]
410
- installer_args : Vec < OsString > ,
411
434
/// Download URL announced
412
435
pub download_url : Url ,
413
436
/// Signature announced
@@ -418,6 +441,13 @@ pub struct Update {
418
441
pub proxy : Option < Url > ,
419
442
/// Request headers
420
443
pub headers : HeaderMap ,
444
+ /// Extract path
445
+ #[ allow( unused) ]
446
+ extract_path : PathBuf ,
447
+ #[ allow( unused) ]
448
+ installer_args : Vec < OsString > ,
449
+ #[ allow( unused) ]
450
+ nsis_installer_args : Vec < OsString > ,
421
451
}
422
452
423
453
impl Resource for Update { }
@@ -442,7 +472,7 @@ impl Update {
442
472
HeaderValue :: from_str ( "tauri-updater" ) . unwrap ( ) ,
443
473
) ;
444
474
445
- let mut request = ClientBuilder :: new ( ) ;
475
+ let mut request = ClientBuilder :: new ( ) . user_agent ( UPDATER_USER_AGENT ) ;
446
476
if let Some ( timeout) = self . timeout {
447
477
request = request. timeout ( timeout) ;
448
478
}
@@ -544,6 +574,7 @@ impl Update {
544
574
/// │ └──[AppName]_[version]_x64-setup.exe # NSIS installer
545
575
/// └── ...
546
576
fn install_inner ( & self , bytes : & [ u8 ] ) -> Result < ( ) > {
577
+ use std:: iter:: once;
547
578
use windows_sys:: {
548
579
w,
549
580
Win32 :: UI :: { Shell :: ShellExecuteW , WindowsAndMessaging :: SW_SHOW } ,
@@ -552,24 +583,39 @@ impl Update {
552
583
let ( updater_type, path, _temp) = Self :: extract ( bytes) ?;
553
584
554
585
let install_mode = self . config . install_mode ( ) ;
555
- let mut installer_args = self . installer_args ( ) ;
556
- match updater_type {
557
- WindowsUpdaterType :: Nsis => {
558
- installer_args. extend ( install_mode. nsis_args ( ) . iter ( ) . map ( OsStr :: new) ) ;
559
- installer_args. push ( OsStr :: new ( "/UPDATE" ) ) ;
560
- }
561
- WindowsUpdaterType :: Msi => {
562
- installer_args. extend ( install_mode. msiexec_args ( ) . iter ( ) . map ( OsStr :: new) ) ;
563
- installer_args. push ( OsStr :: new ( "/promptrestart" ) ) ;
564
- }
586
+ let installer_args: Vec < & OsStr > = match updater_type {
587
+ WindowsUpdaterType :: Nsis => install_mode
588
+ . nsis_args ( )
589
+ . iter ( )
590
+ . map ( OsStr :: new)
591
+ . chain ( once ( OsStr :: new ( "/UPDATE" ) ) )
592
+ . chain ( self . nsis_installer_args ( ) )
593
+ . chain ( self . installer_args ( ) )
594
+ . collect ( ) ,
595
+ WindowsUpdaterType :: Msi => [ OsStr :: new ( "/i" ) , path. as_os_str ( ) ]
596
+ . into_iter ( )
597
+ . chain ( install_mode. msiexec_args ( ) . iter ( ) . map ( OsStr :: new) )
598
+ . chain ( once ( OsStr :: new ( "/promptrestart" ) ) )
599
+ . chain ( self . installer_args ( ) )
600
+ . collect ( ) ,
565
601
} ;
566
602
567
603
if let Some ( on_before_exit) = self . on_before_exit . as_ref ( ) {
568
604
on_before_exit ( ) ;
569
605
}
570
606
607
+ let parameters = installer_args. join ( OsStr :: new ( " " ) ) ;
608
+ let parameters = encode_wide ( parameters) ;
609
+
610
+ let path = match updater_type {
611
+ WindowsUpdaterType :: Msi => std:: env:: var ( "SYSTEMROOT" ) . as_ref ( ) . map_or_else (
612
+ |_| OsString :: from ( "msiexec.exe" ) ,
613
+ |p| OsString :: from ( format ! ( "{p}\\ System32\\ msiexec.exe" ) ) ,
614
+ ) ,
615
+ WindowsUpdaterType :: Nsis => path. as_os_str ( ) . to_os_string ( ) ,
616
+ } ;
571
617
let file = encode_wide ( path) ;
572
- let parameters = encode_wide ( installer_args . join ( OsStr :: new ( " " ) ) ) ;
618
+
573
619
unsafe {
574
620
ShellExecuteW (
575
621
0 ,
@@ -591,6 +637,13 @@ impl Update {
591
637
. collect :: < Vec < _ > > ( )
592
638
}
593
639
640
+ fn nsis_installer_args ( & self ) -> Vec < & OsStr > {
641
+ self . nsis_installer_args
642
+ . iter ( )
643
+ . map ( OsStr :: new)
644
+ . collect :: < Vec < _ > > ( )
645
+ }
646
+
594
647
fn extract ( bytes : & [ u8 ] ) -> Result < ( WindowsUpdaterType , PathBuf , Option < tempfile:: TempPath > ) > {
595
648
#[ cfg( feature = "zip" ) ]
596
649
if infer:: archive:: is_zip ( bytes) {
0 commit comments