forked from V-Modder/SharpUpdate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSharpUpdater.cs
194 lines (171 loc) · 7.85 KB
/
SharpUpdater.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Globalization;
using System.Resources;
namespace SharpUpdate
{
/// <summary>
/// Provides application update support in C#
/// </summary>
public class SharpUpdater : IDisposable
{
/// <summary>
/// Holds the program-to-update's info
/// </summary>
private ISharpUpdatable applicationInfo;
/// <summary>
/// Thread to find update
/// </summary>
private BackgroundWorker bgWorker;
private bool doUpdate;
/// Creates a new SharpUpdater object
/// </summary>
/// <param name="applicationInfo">The info about the application so it can be displayed on dialog boxes to user</param>
/// <param name="doUpdate">Set weather the update should be applied or show ony</param>
public SharpUpdater(ISharpUpdatable applicationInfo, bool doUpdate=true)
{
this.applicationInfo = applicationInfo;
this.doUpdate = doUpdate;
// Set up backgroundworker
this.bgWorker = new BackgroundWorker();
this.bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
this.bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
}
/// <summary>
/// Checks for an update for the program passed.
/// If there is an update, a dialog asking to download will appear
/// </summary>
public void DoUpdate()
{
if (!this.bgWorker.IsBusy)
this.bgWorker.RunWorkerAsync(this.applicationInfo);
}
/// <summary>
/// Checks for/parses update.xml on server
/// </summary>
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
ISharpUpdatable application = (ISharpUpdatable)e.Argument;
// Check for update on server
if (!SharpUpdateXml.ExistsOnServer(application.UpdateXmlLocation))
e.Cancel = true;
else // Parse update xml
e.Result = SharpUpdateXml.Parse(application.UpdateXmlLocation, application.ApplicationID);
}
/// <summary>
/// Get the drirectory of the application
/// </summary>
/// <returns>Full path to the application to update</returns>
private string AssemblyDirectory()
{
//get the full location of the assembly with DaoTests in it
string fullPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
//get the folder that's in
return Path.GetDirectoryName(fullPath);
}
/// <summary>
/// After the background worker is done, prompt to update if there is one
/// </summary>
private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// If there is a file on the server
if (!e.Cancelled)
{
SharpUpdateXml update = (SharpUpdateXml)e.Result;
// Check if the update is not null and is a newer version than the current application
if (update != null)
{
//Check for missing files
if(!update.HasAllFiles(AssemblyDirectory()))
this.DownloadUpdate(update);
else if (update.IsNewerThan(this.applicationInfo.ApplicationAssembly.GetName().Version))
{
// Ask to accept the update
if (new SharpUpdateAcceptForm(this.applicationInfo, update).ShowDialog(this.applicationInfo.Context) == DialogResult.Yes)
{
if (doUpdate)
this.DownloadUpdate(update); // Do the update
else
{//This is not the only instance
MessageBox.Show(SharpUpdate.LanguageFile._default.SharpUpdater_DoubleInstanceWarning,
SharpUpdate.LanguageFile._default.SharpUpdater_DoubleInstanceWarningTitle,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
}
}
/// <summary>
/// Downloads update and installs the update
/// </summary>
/// <param name="update">The update xml info</param>
private void DownloadUpdate(SharpUpdateXml update)
{
SharpUpdateDownloadForm form = new SharpUpdateDownloadForm(update.UpdateFiles, this.applicationInfo.ApplicationIcon);
DialogResult result = form.ShowDialog(this.applicationInfo.Context);
// Download update
if (result == DialogResult.OK)
{
string currentPath = this.applicationInfo.ApplicationAssembly.Location;
// "Install" it
UpdateApplication(form.TempFilesPath, currentPath, update.LaunchArgs);
Application.Exit();
}
else if (result == DialogResult.Abort)
{
MessageBox.Show(SharpUpdate.LanguageFile._default.SharpUpdater_DownloadCancelled, SharpUpdate.LanguageFile._default.SharpUpdater_DownloadCancelledTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show(SharpUpdate.LanguageFile._default.SharpUpdater_DownloadProblem, SharpUpdate.LanguageFile._default.SharpUpdater_DownloadProblemTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// Hack to close program, delete original, move the new one to that location
/// </summary>
/// <param name="tempFilePath">The temporary file's path</param>
/// <param name="currentPath">The path of the current application</param>
/// <param name="launchArgs">The launch arguments</param>
private void UpdateApplication(List<SharpUpdateFileInfo> tempFilePath, string currentPath, string launchArgs)
{
//Wait 4 seceonds to close the application
string argument = "/C choice /C Y /N /D Y /T 4 & ";
//Delete all file that will be updated
foreach (SharpUpdateFileInfo fi in tempFilePath)
{
argument += string.Format("Del /F /Q \"{0}\" & ", Path.GetDirectoryName(currentPath) + "\\" + fi.FileName);
}
//Wait 2 seconds
argument += "choice /C Y /N /D Y /T 2 & ";
//Move all downloaded files from temporarily path to installed path
foreach (SharpUpdateFileInfo fi in tempFilePath)
{
argument += string.Format("Move /Y \"{0}\" \"{1}\" & ", fi.TempFile, Path.GetDirectoryName(currentPath) + "\\" + fi.FileName);
}
//Start the application after updateing all files
argument += "Start \"\" /D \"{0}\" \"{1}\" {2}";
//Start the process to do above tasks
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = String.Format(argument, Path.GetDirectoryName(currentPath), Path.GetFileName(tempFilePath[0].FileName), launchArgs);
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (bgWorker.IsBusy)
bgWorker.CancelAsync();
}
}
}