1+ using System ;
2+ using System . Diagnostics . CodeAnalysis ;
3+ using System . IO ;
4+ using System . Net ;
5+ using Novus . Win32 ;
6+ using SimpleCore . Cli ;
7+ using SmartImage . Core ;
8+
9+ namespace SmartImage . Utilities
10+ {
11+ public enum VersionStatus
12+ {
13+ UpToDate ,
14+ Available ,
15+ Preview ,
16+ }
17+
18+ public readonly struct UpdateInfo
19+ {
20+ public Version Current { get ; }
21+
22+ public ReleaseInfo Latest { get ; }
23+
24+ public VersionStatus Status { get ; }
25+
26+ private UpdateInfo ( Version current , ReleaseInfo info , VersionStatus status )
27+ {
28+ Current = current ;
29+ Latest = info ;
30+ Status = status ;
31+ }
32+
33+ [ DoesNotReturn ]
34+ public static void Update ( UpdateInfo ui )
35+ {
36+ const string NEW_EXE = "SmartImage-new.exe" ;
37+ const string UPDATE_BAT = "SmartImage_Updater.bat" ;
38+
39+
40+ var destNew = Path . Combine ( Info . AppFolder , NEW_EXE ) ;
41+ var wc = new WebClient ( ) ;
42+
43+ Console . WriteLine ( "Downloading..." ) ;
44+
45+ wc . DownloadFile ( ui . Latest . AssetUrl , destNew ) ;
46+
47+
48+ string exeFileName = Info . ExeLocation ;
49+
50+ //const string WAIT_4_SEC = "ping 127.0.0.1 > nul";
51+
52+ const string WAIT_4_SEC = "timeout /t 4 /nobreak >nul" ;
53+
54+ string [ ] commands =
55+ {
56+ "@echo off" ,
57+
58+ /* Wait approximately 4 seconds (so that the process is already terminated) */
59+ WAIT_4_SEC ,
60+
61+ /* Delete executable */
62+ "echo y | del /F " + exeFileName ,
63+
64+ /* Rename */
65+ $ "move /Y \" { destNew } \" \" { exeFileName } \" > NUL",
66+
67+ /* Wait */
68+ WAIT_4_SEC ,
69+ WAIT_4_SEC ,
70+
71+ /* Open the new SmartImage version */
72+ $ "start /d \" { Info . AppFolder } \" { Info . NAME_EXE } ",
73+
74+ /* Delete this batch file */
75+ "echo y | del " + UPDATE_BAT ,
76+ } ;
77+
78+
79+ // Runs in background
80+ Command . RunBatch ( commands , false , UPDATE_BAT ) ;
81+ }
82+
83+
84+ // NOTE: Does not return if a new update is found and the user updates
85+ public static void AutoUpdate ( )
86+ {
87+ var ui = GetUpdateInfo ( ) ;
88+
89+ if ( ui . Status == VersionStatus . Available ) {
90+ Console . WriteLine ( $ "Update found: { ui . Latest } ") ;
91+
92+ if ( NConsole . ReadConfirmation ( "Update?" ) ) {
93+ try {
94+ Update ( ui ) ;
95+ }
96+ catch ( Exception e ) {
97+ Console . WriteLine ( e ) ;
98+ return ;
99+ }
100+ }
101+ }
102+
103+ Console . WriteLine ( $ "Up to date: { ui . Current } [{ ui . Latest } ]") ;
104+ NConsole . WaitForSecond ( ) ;
105+ }
106+
107+ public static UpdateInfo GetUpdateInfo ( )
108+ {
109+ var currentVersion = Info . Version ;
110+
111+ var release = ReleaseInfo . GetLatestRelease ( ) ;
112+
113+ int cmp = currentVersion . CompareTo ( release . Version ) ;
114+
115+ var status = cmp switch
116+ {
117+ < 0 => VersionStatus . Available ,
118+ 0 => VersionStatus . UpToDate ,
119+ _ => VersionStatus . Preview
120+ } ;
121+
122+ return new UpdateInfo ( currentVersion , release , status ) ;
123+ }
124+ }
125+ }
0 commit comments