@@ -30,13 +30,16 @@ public partial class Operate : Form
3030 long byteProgress = 0 ;
3131 long byteTotal = 0 ;
3232
33+ int cancelStatus = 0 ;
34+
3335 public Operate ( ) => InitializeComponent ( ) ;
3436
3537 private async void Operation_Load ( object sender , EventArgs e )
3638 {
3739 TaskbarManager . Instance . SetProgressState ( TaskbarProgressBarState . Normal , FPM . Main . Handle ) ;
3840
3941 downloader . DownloadProgressChanged += OnDownloadProgressChanged ;
42+ downloader . DownloadFileCompleted += OnDownloadFileCompleted ;
4043
4144 if ( ! FPM . UpdateMode )
4245 {
@@ -72,6 +75,21 @@ private async void Operation_Load(object sender, EventArgs e)
7275
7376 byteTotal = removedComponents . Concat ( addedComponents ) . Sum ( item => item . Size ) ;
7477
78+ foreach ( var component in addedComponents )
79+ {
80+ workingComponent = component ;
81+ stream = await downloader . DownloadFileTaskAsync ( component . URL ) ;
82+
83+ if ( cancelStatus != 0 ) return ;
84+
85+ await Task . Run ( ExtractComponents ) ;
86+
87+ byteProgress += component . Size ;
88+ }
89+
90+ if ( cancelStatus != 0 ) return ;
91+ CancelButton . Enabled = false ;
92+
7593 foreach ( var component in removedComponents )
7694 {
7795 workingComponent = component ;
@@ -81,23 +99,33 @@ private async void Operation_Load(object sender, EventArgs e)
8199 byteProgress += component . Size ;
82100 }
83101
102+ ProgressLabel . Text = "[100%] Finishing up..." ;
103+
84104 foreach ( var component in addedComponents )
85105 {
86106 workingComponent = component ;
87- stream = await downloader . DownloadFileTaskAsync ( component . URL ) ;
88-
89- await Task . Run ( ExtractComponents ) ;
90107
91- byteProgress += component . Size ;
108+ await Task . Run ( ApplyComponents ) ;
92109 }
93110
111+ await Task . Run ( DeleteTempDirectory ) ;
112+
94113 TaskbarManager . Instance . SetProgressState ( TaskbarProgressBarState . NoProgress , FPM . Main . Handle ) ;
95114
115+ if ( FPM . AutoDownload == "" ) FPM . SyncManager ( ) ;
116+
117+ cancelStatus = 2 ;
96118 Close ( ) ;
97119 }
98120
99121 private void OnDownloadProgressChanged ( object sender , DownloadProgressChangedEventArgs e )
100122 {
123+ if ( cancelStatus != 0 )
124+ {
125+ downloader . CancelAsync ( ) ;
126+ return ;
127+ }
128+
101129 double currentProgress = ( double ) e . ReceivedBytesSize / e . TotalBytesToReceive ;
102130 long currentSize = workingComponent . Size ;
103131 double totalProgress = ( byteProgress + ( currentProgress / 2 * currentSize ) ) / byteTotal ;
@@ -122,6 +150,11 @@ private void OnDownloadProgressChanged(object sender, DownloadProgressChangedEve
122150 } ) ;
123151 }
124152
153+ private void OnDownloadFileCompleted ( object sender , System . ComponentModel . AsyncCompletedEventArgs e )
154+ {
155+ if ( e . Cancelled ) cancelStatus = 2 ;
156+ }
157+
125158 private void ExtractComponents ( )
126159 {
127160 using ( archive = ZipArchive . Open ( stream ) )
@@ -131,8 +164,8 @@ private void ExtractComponents()
131164 long extractedSize = 0 ;
132165 long totalSize = archive . TotalUncompressSize ;
133166
134- string destPath = Path . Combine ( FPM . SourcePath , workingComponent . Path . Replace ( '/' , '\\ ' ) ) ;
135- string infoPath = Path . Combine ( FPM . SourcePath , "Components" ) ;
167+ string destPath = Path . Combine ( FPM . SourcePath , "Temp" , workingComponent . Path . Replace ( '/' , '\\ ' ) ) ;
168+ string infoPath = Path . Combine ( FPM . SourcePath , "Temp" , " Components") ;
136169 string infoFile = Path . Combine ( infoPath , $ "{ workingComponent . ID } .txt") ;
137170
138171 Directory . CreateDirectory ( infoPath ) ;
@@ -144,7 +177,7 @@ private void ExtractComponents()
144177 writer . WriteLine ( string . Join ( " " , header ) ) ;
145178 }
146179
147- while ( reader . MoveToNextEntry ( ) )
180+ while ( cancelStatus == 0 && reader . MoveToNextEntry ( ) )
148181 {
149182 if ( reader . Entry . IsDirectory ) continue ;
150183
@@ -184,22 +217,28 @@ private void ExtractComponents()
184217 ) ;
185218 } ) ;
186219 }
220+
221+ if ( cancelStatus != 0 )
222+ {
223+ reader . Cancel ( ) ;
224+ cancelStatus = 2 ;
225+ }
187226 }
188227 }
189228 }
190229
191230 private void RemoveComponents ( )
192231 {
193232 string infoFile = Path . Combine ( FPM . SourcePath , "Components" , $ "{ workingComponent . ID } .txt") ;
194- string [ ] infoText = File . ReadAllLines ( infoFile ) ;
233+ string [ ] infoText = File . ReadLines ( infoFile ) . Skip ( 1 ) . ToArray ( ) ;
195234
196235 long removedFiles = 0 ;
197236 long totalFiles = infoText . Length - 1 ;
198237 long totalSize = workingComponent . Size ;
199238
200- for ( int i = 1 ; i < infoText . Length ; i ++ )
239+ foreach ( string file in infoText )
201240 {
202- string filePath = Path . Combine ( FPM . SourcePath , infoText [ i ] ) ;
241+ string filePath = Path . Combine ( FPM . SourcePath , file ) ;
203242 double removeProgress = ( double ) removedFiles / totalFiles ;
204243 double totalProgress = ( byteProgress + ( removeProgress * totalSize ) ) / byteTotal ;
205244
@@ -213,9 +252,11 @@ private void RemoveComponents()
213252
214253 ProgressLabel . Invoke ( ( MethodInvoker ) delegate
215254 {
216- ProgressLabel . Text =
217- $ "[{ ( int ) ( ( double ) totalProgress * 100 ) } %] Removing component \" { workingComponent . Title } \" ... " +
218- $ "{ removedFiles } of { totalFiles } files";
255+ string text = FPM . ComponentTracker . ToUpdate . Exists ( c => c . ID == workingComponent . ID )
256+ ? $ "Removing old version of component \" { workingComponent . Title } \" ..."
257+ : $ "Removing component \" { workingComponent . Title } \" ...";
258+
259+ ProgressLabel . Text = $ "[{ ( int ) ( ( double ) totalProgress * 100 ) } %] { text } { removedFiles } of { totalFiles } files";
219260 } ) ;
220261
221262 FPM . Main . Invoke ( ( MethodInvoker ) delegate
@@ -228,5 +269,66 @@ private void RemoveComponents()
228269
229270 FPM . DeleteFileAndDirectories ( infoFile ) ;
230271 }
272+
273+ private void ApplyComponents ( )
274+ {
275+ string tempPath = Path . Combine ( FPM . SourcePath , "Temp" ) ;
276+ string tempInfoFile = Path . Combine ( tempPath , "Components" , $ "{ workingComponent . ID } .txt") ;
277+ string [ ] infoText = File . ReadLines ( tempInfoFile ) . Skip ( 1 ) . ToArray ( ) ;
278+
279+ foreach ( string file in infoText )
280+ {
281+ string tempFile = Path . Combine ( FPM . SourcePath , "Temp" , file ) ;
282+ string destFile = Path . Combine ( FPM . SourcePath , file ) ;
283+
284+ Directory . CreateDirectory ( Path . GetDirectoryName ( destFile ) ) ;
285+ try { File . Move ( tempFile , destFile ) ; } catch { }
286+ }
287+
288+ string destInfoFile = Path . Combine ( FPM . SourcePath , "Components" , $ "{ workingComponent . ID } .txt") ;
289+ try { File . Move ( tempInfoFile , destInfoFile ) ; } catch { }
290+ }
291+
292+ public static void DeleteTempDirectory ( )
293+ {
294+ string tempPath = Path . Combine ( FPM . SourcePath , "Temp" ) ;
295+
296+ if ( Directory . Exists ( tempPath ) )
297+ {
298+ foreach ( string tempFile in Directory . EnumerateFiles ( tempPath ) )
299+ {
300+ try { File . Delete ( tempFile ) ; } catch { }
301+ }
302+
303+ try { Directory . Delete ( tempPath , true ) ; } catch { }
304+ }
305+ }
306+
307+ private async void CancelButton_Click ( object sender , EventArgs e )
308+ {
309+ cancelStatus = 1 ;
310+
311+ CancelButton . Enabled = false ;
312+ ProgressLabel . Invoke ( ( MethodInvoker ) delegate
313+ {
314+ ProgressLabel . Text = "Cancelling..." ;
315+ } ) ;
316+
317+ await Task . Run ( ( ) =>
318+ {
319+ while ( cancelStatus != 2 ) { }
320+
321+ DeleteTempDirectory ( ) ;
322+ } ) ;
323+
324+ TaskbarManager . Instance . SetProgressState ( TaskbarProgressBarState . NoProgress , FPM . Main . Handle ) ;
325+
326+ Close ( ) ;
327+ }
328+
329+ private void Operation_FormClosing ( object sender , FormClosingEventArgs e )
330+ {
331+ if ( cancelStatus != 2 ) e . Cancel = true ;
332+ }
231333 }
232334}
0 commit comments