2
2
using System . IO . Compression ;
3
3
using System . Net ;
4
4
5
+ using log4net ;
6
+
5
7
using Microsoft . VisualBasic . FileIO ;
6
8
7
9
using Newtonsoft . Json ;
@@ -12,6 +14,11 @@ namespace Nullinside.Api.Common.Desktop;
12
14
/// Handles checking for updates to the application via GitHub releases.
13
15
/// </summary>
14
16
public static class GitHubUpdateManager {
17
+ /// <summary>
18
+ /// The logger.
19
+ /// </summary>
20
+ private static readonly ILog Log = LogManager . GetLogger ( typeof ( GitHubUpdateManager ) ) ;
21
+
15
22
/// <summary>
16
23
/// Gets the latest version number of the release.
17
24
/// </summary>
@@ -45,60 +52,75 @@ public static class GitHubUpdateManager {
45
52
/// Prepares to update this application before this application is closed.
46
53
/// </summary>
47
54
public static async Task PrepareUpdate ( ) {
48
- // To prepare the update, we just need to back up our files
49
- string ourFolder = Path . GetDirectoryName ( typeof ( GitHubUpdateManager ) . Assembly . Location ) ?? "" ;
50
- string backupFolder = Path . Combine ( ourFolder , ".." , "backup" ) ;
51
- await DeleteFolderRetry ( backupFolder ) ;
52
-
53
- Directory . CreateDirectory ( backupFolder ) ;
54
- FileSystem . CopyDirectory ( ourFolder , backupFolder ) ;
55
+ try {
56
+ // To prepare the update, we just need to back up our files
57
+ string ourFolder = Path . GetDirectoryName ( typeof ( GitHubUpdateManager ) . Assembly . Location ) ?? "" ;
58
+ string backupFolder = Path . Combine ( ourFolder , ".." , "backup" ) ;
59
+ await DeleteFolderRetry ( backupFolder ) ;
60
+
61
+ Directory . CreateDirectory ( backupFolder ) ;
62
+ FileSystem . CopyDirectory ( ourFolder , backupFolder ) ;
63
+ }
64
+ catch ( Exception ex ) {
65
+ Log . Error ( ex ) ;
66
+ }
55
67
}
56
68
57
69
/// <summary>
58
70
/// Runs this application from the backup folder to initiate the update on the installed folder.
59
71
/// </summary>
60
72
public static void ExitApplicationToUpdate ( ) {
61
- // Since we have a backup folder from PrepareUpdate() we can just run the backup executable
62
- string ourFolder = Path . GetDirectoryName ( typeof ( GitHubUpdateManager ) . Assembly . Location ) ?? "" ;
63
- string backupFolder = Path . Combine ( ourFolder , ".." , "backup" ) ;
64
- if ( ! Directory . Exists ( backupFolder ) ) {
65
- return ;
66
- }
73
+ try {
74
+ // Since we have a backup folder from PrepareUpdate() we can just run the backup executable
75
+ string ourFolder = Path . GetDirectoryName ( typeof ( GitHubUpdateManager ) . Assembly . Location ) ?? "" ;
76
+ string backupFolder = Path . Combine ( ourFolder , ".." , "backup" ) ;
77
+ if ( ! Directory . Exists ( backupFolder ) ) {
78
+ return ;
79
+ }
67
80
68
- string ourExecutable = $ "{ AppDomain . CurrentDomain . FriendlyName } .exe";
81
+ string ourExecutable = $ "{ AppDomain . CurrentDomain . FriendlyName } .exe";
69
82
70
- // we must pass the installation folder to the executable so it knows where to install
71
- Process . Start ( Path . Combine ( backupFolder , ourExecutable ) , $ "--update \" { ourFolder } \" ") ;
72
- Environment . Exit ( 0 ) ;
83
+ // we must pass the installation folder to the executable so it knows where to install
84
+ Process . Start ( Path . Combine ( backupFolder , ourExecutable ) , $ "--update \" { ourFolder } \" ") ;
85
+ Environment . Exit ( 0 ) ;
86
+ }
87
+ catch ( Exception ex ) {
88
+ Log . Error ( ex ) ;
89
+ }
73
90
}
74
91
75
92
/// <summary>
76
93
/// Performs the application update. This involves downloading the latest release from GitHub, extracting its contents
77
94
/// to the installation folder, and closing the currently running application while running the new one.
78
95
/// </summary>
79
96
public static async Task PerformUpdateAndRestart ( string owner , string repo , string installFolder , string assetName ) {
80
- // Delete the old install folder.
81
- await DeleteFolderContentsRetry ( installFolder ) ;
82
-
83
- // Get the latest version of the application from GitHub.
84
- string ourFolder = Path . GetDirectoryName ( typeof ( GitHubUpdateManager ) . Assembly . Location ) ?? "" ;
85
- string zipLocation = Path . Combine ( ourFolder , assetName ) ;
86
- GithubLatestReleaseJson ? latestVersion = await GetLatestVersion ( owner , repo ) ;
87
- using ( var client = new HttpClient ( ) ) {
88
- using HttpResponseMessage response = await client . GetAsync ( $ "https://github.com/{ owner } /{ repo } /releases/download/{ latestVersion ? . name } /{ assetName } ") ;
89
- await using Stream streamToReadFrom = await response . Content . ReadAsStreamAsync ( ) ;
90
- await using var fileStream = new FileStream ( zipLocation , FileMode . Create ) ;
91
- await streamToReadFrom . CopyToAsync ( fileStream ) ;
92
- }
97
+ try {
98
+ // Delete the old install folder.
99
+ await DeleteFolderContentsRetry ( installFolder ) ;
100
+
101
+ // Get the latest version of the application from GitHub.
102
+ string ourFolder = Path . GetDirectoryName ( typeof ( GitHubUpdateManager ) . Assembly . Location ) ?? "" ;
103
+ string zipLocation = Path . Combine ( ourFolder , assetName ) ;
104
+ GithubLatestReleaseJson ? latestVersion = await GetLatestVersion ( owner , repo ) ;
105
+ using ( var client = new HttpClient ( ) ) {
106
+ using HttpResponseMessage response = await client . GetAsync ( $ "https://github.com/{ owner } /{ repo } /releases/download/{ latestVersion ? . name } /{ assetName } ") ;
107
+ await using Stream streamToReadFrom = await response . Content . ReadAsStreamAsync ( ) ;
108
+ await using var fileStream = new FileStream ( zipLocation , FileMode . Create ) ;
109
+ await streamToReadFrom . CopyToAsync ( fileStream ) ;
110
+ }
93
111
94
- // Extract the zip file to the installation folder.
95
- ZipFile . ExtractToDirectory ( zipLocation , installFolder ) ;
112
+ // Extract the zip file to the installation folder.
113
+ ZipFile . ExtractToDirectory ( zipLocation , installFolder ) ;
96
114
97
- // Run the new version of the application.
98
- Process . Start ( Path . Combine ( installFolder , $ "{ AppDomain . CurrentDomain . FriendlyName } .exe") , "--justUpdated" ) ;
115
+ // Run the new version of the application.
116
+ Process . Start ( Path . Combine ( installFolder , $ "{ AppDomain . CurrentDomain . FriendlyName } .exe") , "--justUpdated" ) ;
99
117
100
- // Close this version of the application.
101
- Environment . Exit ( 0 ) ;
118
+ // Close this version of the application.
119
+ Environment . Exit ( 0 ) ;
120
+ }
121
+ catch ( Exception ex ) {
122
+ Log . Error ( ex ) ;
123
+ }
102
124
}
103
125
104
126
/// <summary>
@@ -116,30 +138,40 @@ public static async Task CleanupUpdate() {
116
138
/// </summary>
117
139
/// <param name="folder">The folder to delete.</param>
118
140
private static async Task DeleteFolderRetry ( string folder ) {
119
- await Retry . Execute ( ( ) => {
120
- if ( Directory . Exists ( folder ) ) {
121
- Directory . Delete ( folder , true ) ;
122
- }
141
+ try {
142
+ await Retry . Execute ( ( ) => {
143
+ if ( Directory . Exists ( folder ) ) {
144
+ Directory . Delete ( folder , true ) ;
145
+ }
123
146
124
- return Task . FromResult ( true ) ;
125
- } , 30 , waitTime : TimeSpan . FromSeconds ( 1 ) ) ;
147
+ return Task . FromResult ( true ) ;
148
+ } , 30 , waitTime : TimeSpan . FromSeconds ( 1 ) ) ;
149
+ }
150
+ catch ( Exception ex ) {
151
+ Log . Error ( ex ) ;
152
+ }
126
153
}
127
154
128
155
/// <summary>
129
156
/// Retries deleting the contents of a folder multiple times.
130
157
/// </summary>
131
158
/// <param name="folder">The folder to delete the contents of.</param>
132
159
private static async Task DeleteFolderContentsRetry ( string folder ) {
133
- await Retry . Execute ( ( ) => {
134
- if ( ! Directory . Exists ( folder ) ) {
135
- return Task . FromResult ( true ) ;
136
- }
160
+ try {
161
+ await Retry . Execute ( ( ) => {
162
+ if ( ! Directory . Exists ( folder ) ) {
163
+ return Task . FromResult ( true ) ;
164
+ }
137
165
138
- foreach ( string file in Directory . GetFiles ( folder ) ) {
139
- File . Delete ( file ) ;
140
- }
166
+ foreach ( string file in Directory . GetFiles ( folder ) ) {
167
+ File . Delete ( file ) ;
168
+ }
141
169
142
- return Task . FromResult ( true ) ;
143
- } , 30 , waitTime : TimeSpan . FromSeconds ( 1 ) ) ;
170
+ return Task . FromResult ( true ) ;
171
+ } , 30 , waitTime : TimeSpan . FromSeconds ( 1 ) ) ;
172
+ }
173
+ catch ( Exception ex ) {
174
+ Log . Error ( ex ) ;
175
+ }
144
176
}
145
177
}
0 commit comments