mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Added the progress handling;
Now API (AppUpdater) is async. Cancellation token hasn't been tested yet, because UI doesn't allow to cancel the update. Signed-off-by: Vest <Vest@users.noreply.github.com>
This commit is contained in:
@@ -148,10 +148,14 @@ namespace mRemoteNG.App.Update
|
||||
}
|
||||
*/
|
||||
|
||||
public async Task DownloadUpdateAsync()
|
||||
public async Task DownloadUpdateAsync(IProgress<int> progress)
|
||||
{
|
||||
if (IsGetUpdateInfoRunning)
|
||||
{
|
||||
getUpdateInfoCancelToken.Cancel();
|
||||
getUpdateInfoCancelToken.Dispose();
|
||||
getUpdateInfoCancelToken = null;
|
||||
|
||||
throw new InvalidOperationException("A previous call to DownloadUpdateAsync() is still in progress.");
|
||||
}
|
||||
|
||||
@@ -161,8 +165,7 @@ namespace mRemoteNG.App.Update
|
||||
"CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync().");
|
||||
}
|
||||
#if !PORTABLE
|
||||
CurrentUpdateInfo.UpdateFilePath =
|
||||
Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi"));
|
||||
CurrentUpdateInfo.UpdateFilePath = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi"));
|
||||
#else
|
||||
var sfd = new SaveFileDialog
|
||||
{
|
||||
@@ -179,7 +182,42 @@ namespace mRemoteNG.App.Update
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// TODO: DownloadUpdateWebClient.DownloadFileAsync(CurrentUpdateInfo.DownloadAddress, CurrentUpdateInfo.UpdateFilePath);
|
||||
try
|
||||
{
|
||||
getUpdateInfoCancelToken = new CancellationTokenSource();
|
||||
using (var response = await _httpClient.GetAsync(CurrentUpdateInfo.DownloadAddress,
|
||||
HttpCompletionOption.ResponseHeadersRead, getUpdateInfoCancelToken.Token))
|
||||
{
|
||||
var buffer = new byte[8192];
|
||||
var totalBytes = response.Content.Headers.ContentLength ?? 0;
|
||||
var readBytes = 0L;
|
||||
|
||||
await using var httpStream =
|
||||
await response.Content.ReadAsStreamAsync(getUpdateInfoCancelToken.Token);
|
||||
await using var fileStream = new FileStream(CurrentUpdateInfo.UpdateFilePath, FileMode.Create,
|
||||
FileAccess.Write, FileShare.None, buffer.Length, true);
|
||||
|
||||
while (readBytes <= totalBytes || !getUpdateInfoCancelToken.IsCancellationRequested)
|
||||
{
|
||||
var bytesRead = await httpStream.ReadAsync(buffer, 0, buffer.Length, getUpdateInfoCancelToken.Token);
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
progress.Report(100);
|
||||
break;
|
||||
}
|
||||
|
||||
await fileStream.WriteAsync(buffer, 0, bytesRead, getUpdateInfoCancelToken.Token);
|
||||
|
||||
readBytes += bytesRead;
|
||||
|
||||
var percentComplete = (int)(readBytes * 100 / totalBytes);
|
||||
progress.Report(percentComplete);
|
||||
}
|
||||
}
|
||||
} finally{
|
||||
getUpdateInfoCancelToken.Dispose();
|
||||
getUpdateInfoCancelToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -11,13 +11,14 @@ using mRemoteNG.Messages;
|
||||
using mRemoteNG.Themes;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace mRemoteNG.UI.Window
|
||||
{
|
||||
public partial class UpdateWindow : BaseWindow
|
||||
{
|
||||
private AppUpdater _appUpdate;
|
||||
private bool _isUpdateDownloadHandlerDeclared;
|
||||
//private bool _isUpdateDownloadHandlerDeclared;
|
||||
|
||||
#region Public Methods
|
||||
|
||||
@@ -43,7 +44,7 @@ namespace mRemoteNG.UI.Window
|
||||
ApplyTheme();
|
||||
ThemeManager.getInstance().ThemeChanged += ApplyTheme;
|
||||
ApplyLanguage();
|
||||
CheckForUpdate();
|
||||
CheckForUpdateAsync();
|
||||
}
|
||||
|
||||
private new void ApplyTheme()
|
||||
@@ -74,12 +75,12 @@ namespace mRemoteNG.UI.Window
|
||||
|
||||
private void btnCheckForUpdate_Click(object sender, EventArgs e)
|
||||
{
|
||||
CheckForUpdate();
|
||||
CheckForUpdateAsync();
|
||||
}
|
||||
|
||||
private void btnDownload_Click(object sender, EventArgs e)
|
||||
private async void btnDownload_Click(object sender, EventArgs e)
|
||||
{
|
||||
DownloadUpdate();
|
||||
await DownloadUpdateAsync();
|
||||
}
|
||||
|
||||
private void pbUpdateImage_Click(object sender, EventArgs e)
|
||||
@@ -97,7 +98,7 @@ namespace mRemoteNG.UI.Window
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async void CheckForUpdate()
|
||||
private async void CheckForUpdateAsync()
|
||||
{
|
||||
if (_appUpdate == null)
|
||||
{
|
||||
@@ -192,7 +193,7 @@ namespace mRemoteNG.UI.Window
|
||||
prgbDownload.Visible = visible;
|
||||
}
|
||||
|
||||
private void DownloadUpdate()
|
||||
private async Task DownloadUpdateAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -200,50 +201,18 @@ namespace mRemoteNG.UI.Window
|
||||
prgbDownload.Visible = true;
|
||||
prgbDownload.Value = 0;
|
||||
|
||||
if (_isUpdateDownloadHandlerDeclared == false)
|
||||
{
|
||||
// _appUpdate.DownloadUpdateProgressChangedEvent += DownloadUpdateProgressChanged;
|
||||
// _appUpdate.DownloadUpdateCompletedEvent += DownloadUpdateCompleted;
|
||||
_isUpdateDownloadHandlerDeclared = true;
|
||||
}
|
||||
await _appUpdate.DownloadUpdateAsync(new Progress<int>(progress => prgbDownload.Value = progress));
|
||||
|
||||
_appUpdate.DownloadUpdateAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector?.AddExceptionStackTrace(Language.UpdateDownloadFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
|
||||
private void DownloadUpdateProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||
{
|
||||
prgbDownload.Value = e.ProgressPercentage;
|
||||
}
|
||||
|
||||
private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
btnDownload.Enabled = true;
|
||||
prgbDownload.Visible = false;
|
||||
|
||||
if (e.Cancelled)
|
||||
return;
|
||||
if (e.Error != null)
|
||||
throw e.Error;
|
||||
|
||||
if (Runtime.IsPortableEdition)
|
||||
MessageBox.Show(Language.UpdatePortableDownloadComplete, Language.CheckForUpdates,
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
{
|
||||
if (MessageBox.Show(Language.UpdateDownloadComplete, Language.CheckForUpdates,
|
||||
MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
|
||||
MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
|
||||
{
|
||||
Shutdown.Quit(_appUpdate.CurrentUpdateInfo.UpdateFilePath);
|
||||
}
|
||||
@@ -255,8 +224,11 @@ namespace mRemoteNG.UI.Window
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector?.AddExceptionStackTrace(Language.UpdateDownloadFailed, ex);
|
||||
|
||||
Runtime.MessageCollector?.AddExceptionStackTrace(Language.UpdateDownloadCompleteFailed, ex);
|
||||
Runtime.MessageCollector?.AddMessage(MessageClass.ErrorMsg, ex.Message);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user