Skip to content

Commit e5132e8

Browse files
implement AutoUpdater
1 parent 8605fab commit e5132e8

File tree

16 files changed

+332
-5
lines changed

16 files changed

+332
-5
lines changed

ElectronNET.API/AutoUpdater.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using ElectronNET.API.Entities;
2+
using Newtonsoft.Json.Linq;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Text;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace ElectronNET.API
10+
{
11+
/// <summary>
12+
/// Enable apps to automatically update themselves. Based on electron-updater.
13+
/// </summary>
14+
public sealed class AutoUpdater
15+
{
16+
private static AutoUpdater _autoUpdater;
17+
private static object _syncRoot = new object();
18+
19+
internal AutoUpdater() { }
20+
21+
internal static AutoUpdater Instance
22+
{
23+
get
24+
{
25+
if (_autoUpdater == null)
26+
{
27+
lock (_syncRoot)
28+
{
29+
if (_autoUpdater == null)
30+
{
31+
_autoUpdater = new AutoUpdater();
32+
}
33+
}
34+
}
35+
36+
return _autoUpdater;
37+
}
38+
}
39+
40+
/// <summary>
41+
/// Asks the server whether there is an update.
42+
/// </summary>
43+
/// <returns></returns>
44+
public Task<UpdateCheckResult> CheckForUpdatesAsync()
45+
{
46+
var taskCompletionSource = new TaskCompletionSource<UpdateCheckResult>();
47+
string guid = Guid.NewGuid().ToString();
48+
49+
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesComplete" + guid, (updateCheckResult) =>
50+
{
51+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
52+
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
53+
});
54+
55+
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdates", guid);
56+
57+
return taskCompletionSource.Task;
58+
}
59+
60+
/// <summary>
61+
/// Asks the server whether there is an update.
62+
///
63+
/// This will immediately download an update, then install when the app quits.
64+
/// </summary>
65+
/// <returns></returns>
66+
public Task<UpdateCheckResult> CheckForUpdatesAndNotifyAsync()
67+
{
68+
var taskCompletionSource = new TaskCompletionSource<UpdateCheckResult>();
69+
string guid = Guid.NewGuid().ToString();
70+
71+
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid, (updateCheckResult) =>
72+
{
73+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
74+
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
75+
});
76+
77+
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdatesAndNotify", guid);
78+
79+
return taskCompletionSource.Task;
80+
}
81+
82+
/// <summary>
83+
/// Restarts the app and installs the update after it has been downloaded.
84+
/// It should only be called after `update-downloaded` has been emitted.
85+
///
86+
/// Note: QuitAndInstall() will close all application windows first and only emit `before-quit` event on `app` after that.
87+
/// This is different from the normal quit event sequence.
88+
/// </summary>
89+
/// <param name="isSilent">*windows-only* Runs the installer in silent mode. Defaults to `false`.</param>
90+
/// <param name="isForceRunAfter">Run the app after finish even on silent install. Not applicable for macOS. Ignored if `isSilent` is set to `false`.</param>
91+
public void QuitAndInstall(bool isSilent = false, bool isForceRunAfter = false)
92+
{
93+
BridgeConnector.Socket.Emit("autoUpdaterQuitAndInstall", isSilent, isForceRunAfter);
94+
}
95+
}
96+
}

ElectronNET.API/Electron.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ public static class Electron
1515
/// </summary>
1616
public static App App { get { return App.Instance; } }
1717

18+
/// <summary>
19+
/// Enable apps to automatically update themselves. Based on electron-updater.
20+
/// </summary>
21+
public static AutoUpdater AutoUpdater { get { return AutoUpdater.Instance; } }
22+
1823
/// <summary>
1924
/// Control your windows.
2025
/// </summary>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace ElectronNET.API.Entities
6+
{
7+
/// <summary>
8+
///
9+
/// </summary>
10+
public class BlockMapDataHolder
11+
{
12+
/// <summary>
13+
/// The file size. Used to verify downloaded size (save one HTTP request to get length).
14+
/// Also used when block map data is embedded into the file(appimage, windows web installer package).
15+
/// </summary>
16+
public double Size { get; set; }
17+
18+
/// <summary>
19+
/// The block map file size. Used when block map data is embedded into the file (appimage, windows web installer package).
20+
/// This information can be obtained from the file itself, but it requires additional HTTP request,
21+
/// so, to reduce request count, block map size is specified in the update metadata too.
22+
/// </summary>
23+
public double BlockMapSize { get; set; }
24+
25+
/// <summary>
26+
/// The file checksum.
27+
/// </summary>
28+
public string Sha512 { get; set; }
29+
30+
/// <summary>
31+
///
32+
/// </summary>
33+
public bool IsAdminRightsRequired { get; set; }
34+
}
35+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace ElectronNET.API.Entities
2+
{
3+
/// <summary>
4+
///
5+
/// </summary>
6+
public class ReleaseNoteInfo
7+
{
8+
/// <summary>
9+
/// The version.
10+
/// </summary>
11+
public string Version { get; set; }
12+
13+
/// <summary>
14+
/// The note.
15+
/// </summary>
16+
public string Note { get; set; }
17+
}
18+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace ElectronNET.API.Entities
2+
{
3+
/// <summary>
4+
///
5+
/// </summary>
6+
public class UpdateCancellationToken
7+
{
8+
/// <summary>
9+
///
10+
/// </summary>
11+
public bool Cancelled { get; set; }
12+
13+
/// <summary>
14+
///
15+
/// </summary>
16+
public void Cancel()
17+
{
18+
19+
}
20+
21+
/// <summary>
22+
///
23+
/// </summary>
24+
public void Dispose()
25+
{
26+
27+
}
28+
}
29+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace ElectronNET.API.Entities
2+
{
3+
/// <summary>
4+
///
5+
/// </summary>
6+
public class UpdateCheckResult
7+
{
8+
/// <summary>
9+
///
10+
/// </summary>
11+
public UpdateInfo UpdateInfo { get; set; } = new UpdateInfo();
12+
13+
/// <summary>
14+
///
15+
/// </summary>
16+
public string[] Download { get; set; }
17+
18+
/// <summary>
19+
///
20+
/// </summary>
21+
public UpdateCancellationToken CancellationToken { get; set; }
22+
}
23+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace ElectronNET.API.Entities
2+
{
3+
/// <summary>
4+
///
5+
/// </summary>
6+
public class UpdateFileInfo : BlockMapDataHolder
7+
{
8+
/// <summary>
9+
///
10+
/// </summary>
11+
public string Url { get; set; }
12+
}
13+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
namespace ElectronNET.API.Entities
2+
{
3+
/// <summary>
4+
///
5+
/// </summary>
6+
public class UpdateInfo
7+
{
8+
/// <summary>
9+
/// The version.
10+
/// </summary>
11+
public string Version { get; set; }
12+
13+
/// <summary>
14+
///
15+
/// </summary>
16+
public UpdateFileInfo[] Files { get; set; } = new UpdateFileInfo[0];
17+
18+
/// <summary>
19+
/// The release name.
20+
/// </summary>
21+
public string ReleaseName { get; set; }
22+
23+
/// <summary>
24+
/// The release notes.
25+
/// </summary>
26+
public ReleaseNoteInfo[] ReleaseNotes { get; set; } = new ReleaseNoteInfo[0];
27+
28+
/// <summary>
29+
///
30+
/// </summary>
31+
public string ReleaseDate { get; set; }
32+
33+
/// <summary>
34+
/// The staged rollout percentage, 0-100.
35+
/// </summary>
36+
public int StagingPercentage { get; set; }
37+
}
38+
}

ElectronNET.CLI/Commands/Actions/DeployEmbeddedElectronFiles.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public static void Do(string tempPath)
2727
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "shell.js", "api.");
2828
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "screen.js", "api.");
2929
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "clipboard.js", "api.");
30+
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "autoUpdater.js", "api.");
3031

3132
string splashscreenFolder = Path.Combine(tempPath, "splashscreen");
3233
if (Directory.Exists(splashscreenFolder) == false)

ElectronNET.CLI/ElectronNET.CLI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ This package contains the dotnet tooling to electronize your application.</Descr
9292

9393
<ItemGroup>
9494
<EmbeddedResource Include="..\ElectronNET.Host\api\clipboard.js" Link="ElectronHost\api\clipboard.js" />
95+
<EmbeddedResource Include="..\ElectronNET.Host\api\autoUpdater.js" Link="ElectronHost\api\autoUpdater.js" />
9596
</ItemGroup>
9697

9798
<ItemGroup>

0 commit comments

Comments
 (0)