Skip to content

Commit 960c9a2

Browse files
committed
- Added: Only one instance of SMA can be run #156
- Added: Rescue tool ("SMA Updater") which can install or update to any SMA version #152 - Added: Installer ability to rollback to a previous version #151 - Added: Distribution channels for SMA updates (stable, beta, nightly) #86 - Added: Update settings accessible from Collection Window - Added: Shortcut for "SMA Updater" on install - Added: Debug symbols (pdb) to Services nuspec - Fixed: SMA interrupts update mid-way when exiting #88 #161 #151 - Updated: Stub executable now selects the version based on the local RELEASES file first #161 #151 - Updated: Improved Installer ability to optimize the download size by choosing delta updates - Updated: All windows' default size are less or equal to 800x600 #160 - Updated: Tool tips (wip) #166 - Updated: All projects to PackageReference - Updated: Change log is now generated before build to include the include the latest commit messages in the package - Updated: Packages
1 parent e142def commit 960c9a2

File tree

71 files changed

+892
-1900
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+892
-1900
lines changed

ChangeLogs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT UNLESS YOU KNOW WHAT YOU ARE DOING.
22
# CHANGE LOG
33

4-
[Next version (3d4d54688e1b3390524525d1f443b88d6e470ea4)]
4+
[2.0.3.451]
5+
- Fixed: Updated plugin does not refresh in the UI (still happens in the Browse tab)
6+
- Fixed: Occasional error when updating a Plugin
7+
- Misc: Reorganized Template plugin
8+
9+
10+
[2.0.3.435]
511
- Added: SuperMemo 18.04 compatibility #138
612
- Added: automated ChangeLog and NuPkg Release notes #52
713
- Added: Splash screen (also overrides SuperMemo's) #100

SuperMemoAssistant.sln

+48-48
Large diffs are not rendered by default.

libs/Squirrel.Windows

Submodule Squirrel.Windows updated 73 files

src/AppHosts/SuperMemoAssistant/App.Configs.cs

+10-13
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
// DEALINGS IN THE SOFTWARE.
2222
//
2323
//
24-
// Created On: 2020/02/12 22:20
25-
// Modified On: 2020/02/12 22:20
24+
// Modified On: 2020/03/23 04:02
2625
// Modified By: Alexis
2726

2827
#endregion
@@ -42,28 +41,27 @@ public partial class App
4241
{
4342
#region Methods
4443

45-
private Task<bool> LoadConfigs(out NativeDataCfg nativeDataCfg, out CoreCfg coreCfg)
44+
private async Task<(bool success, NativeDataCfg nativeDataCfg, CoreCfg coreCfg)> LoadConfigs()
4645
{
47-
nativeDataCfg = LoadNativeDataConfig().Result;
48-
coreCfg = LoadCoreConfig().Result;
46+
var nativeDataCfg = await LoadNativeDataConfig().ConfigureAwait(false);
47+
var coreCfg = await LoadCoreConfig().ConfigureAwait(false);
4948

5049
if (nativeDataCfg == null || coreCfg == null)
51-
return Task.FromResult(false);
50+
return (false, null, null);
5251

53-
return Task.FromResult(true);
52+
return (true, nativeDataCfg, coreCfg);
5453
}
5554

5655
private async Task<CoreCfg> LoadCoreConfig()
5756
{
5857
try
5958
{
60-
return await SMA.Core.Configuration.Load<CoreCfg>()
59+
return await SMA.Core.Configuration
60+
.Load<CoreCfg>()
6161
.ConfigureAwait(false) ?? new CoreCfg();
6262
}
6363
catch (SMAException)
6464
{
65-
await "Failed to open CoreCfg.json. Make sure file is unlocked and try again.".ErrorMsgBox();
66-
6765
return null;
6866
}
6967
}
@@ -72,13 +70,12 @@ private async Task<NativeDataCfg> LoadNativeDataConfig()
7270
{
7371
try
7472
{
75-
return await SMA.Core.Configuration.Load<NativeDataCfg>(SMAExecutableInfo.Instance.DirectoryPath)
73+
return await SMA.Core.Configuration
74+
.Load<NativeDataCfg>(SMAExecutableInfo.Instance.DirectoryPath)
7675
.ConfigureAwait(false);
7776
}
7877
catch (SMAException)
7978
{
80-
await "Failed to load native data config file.".ErrorMsgBox();
81-
8279
return null;
8380
}
8481
}

src/AppHosts/SuperMemoAssistant/App.config

-12
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,10 @@
3838
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
3939
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
4040
</dependentAssembly>
41-
<dependentAssembly>
42-
<assemblyIdentity name="Sentry" publicKeyToken="fba2ec45388e2af0" culture="neutral" />
43-
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
44-
</dependentAssembly>
4541
<dependentAssembly>
4642
<assemblyIdentity name="FontAwesome5" publicKeyToken="9cfaf01297a008f8" culture="neutral" />
4743
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
4844
</dependentAssembly>
49-
<dependentAssembly>
50-
<assemblyIdentity name="Sentry.Protocol" publicKeyToken="fba2ec45388e2af0" culture="neutral" />
51-
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
52-
</dependentAssembly>
53-
<dependentAssembly>
54-
<assemblyIdentity name="Sentry.Serilog" publicKeyToken="fba2ec45388e2af0" culture="neutral" />
55-
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
56-
</dependentAssembly>
5745
</assemblyBinding>
5846
</runtime>
5947
</configuration>

src/AppHosts/SuperMemoAssistant/App.xaml.cs

+22-13
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
using SuperMemoAssistant.SMA.Utils;
4545
using SuperMemoAssistant.Sys.Windows;
4646
using SuperMemoAssistant.UI;
47+
using SuperMemoAssistant.Utils;
4748

4849
namespace SuperMemoAssistant
4950
{
@@ -66,6 +67,8 @@ public partial class App : Application
6667
/// <param name="e"></param>
6768
protected override void OnExit(ExitEventArgs e)
6869
{
70+
SMAInstaller.Instance.Semaphore.Wait();
71+
6972
_taskbarIcon?.Dispose();
7073
_splashScreen?.Close();
7174
_splashScreen = null;
@@ -93,8 +96,14 @@ private async void Application_Startup(object o,
9396
{
9497
_taskbarIcon = (TaskbarIcon)FindResource("TbIcon");
9598

99+
if (ApplicationSingleton.IsOnlyInstance(_ => LogTo.Warning("SuperMemoAssistant is already running. Exiting."), e.Args) == false)
100+
{
101+
Shutdown(SMAExitCodes.ExitCodeSMAAlreadyRunning);
102+
return;
103+
}
104+
96105
if (Parser.Default.ParseArguments<SMAParameters>(e.Args) is Parsed<SMAParameters> parsed)
97-
await LoadApp(parsed.Value);
106+
await LoadApp(parsed.Value).ConfigureAwait(false);
98107

99108
else
100109
Shutdown(SMAExitCodes.ExitCodeParametersError);
@@ -118,20 +127,22 @@ private async Task LoadApp(SMAParameters args)
118127
if (AssemblyCheck.CheckRequired(out var errMsg) == false || CheckSMALocation(out errMsg) == false)
119128
{
120129
LogTo.Warning(errMsg);
121-
await errMsg.ErrorMsgBox();
130+
await errMsg.ErrorMsgBox().ConfigureAwait(false);
122131

123132
Shutdown(SMAExitCodes.ExitCodeDependencyError);
124133
return;
125134
}
126135

127136
//
128137
// Load main configuration files
129-
if (await LoadConfigs(out var nativeDataCfg, out var coreCfg) == false)
138+
var (success, nativeDataCfg, coreCfg) = await LoadConfigs().ConfigureAwait(true);
139+
140+
if (success == false)
130141
{
131142
errMsg =
132143
$"At least one essential config file could not be loaded: nativeDataCfg ? {nativeDataCfg == null} ; startupCfg ? {coreCfg == null}";
133144
LogTo.Warning(errMsg);
134-
await errMsg.ErrorMsgBox();
145+
await errMsg.ErrorMsgBox().ConfigureAwait(false);
135146

136147
Shutdown(SMAExitCodes.ExitCodeConfigError);
137148
return;
@@ -197,23 +208,21 @@ private async Task LoadApp(SMAParameters args)
197208

198209
Exception ex;
199210

200-
if ((ex = await SMA.Core.SMA.Start(nativeDataCfg, smCollection).ConfigureAwait(true)) != null)
211+
if (true && (ex = await SMA.Core.SMA.Start(nativeDataCfg, smCollection).ConfigureAwait(true)) != null)
201212
{
202-
await Dispatcher.InvokeAsync(async () =>
203-
{
204-
_splashScreen?.Close();
205-
_splashScreen = null;
213+
214+
_splashScreen?.Close();
215+
_splashScreen = null;
206216

207-
await $"SMA failed to start: {ex.Message}".ErrorMsgBox();
217+
await $"SMA failed to start: {ex.Message}".ErrorMsgBox().ConfigureAwait(false);
208218

209-
Shutdown(SMAExitCodes.ExitCodeSMAStartupError);
210-
});
219+
Shutdown(SMAExitCodes.ExitCodeSMAStartupError);
211220

212221
return;
213222
}
214223

215224
if (SMAExecutableInfo.Instance.IsDev == false)
216-
await SMAInstaller.Instance.Update();
225+
await SMAInstaller.Instance.Update().ConfigureAwait(false);
217226
}
218227
else
219228
{

src/AppHosts/SuperMemoAssistant/Installer/SMAInstaller.cs

+15-6
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public sealed class SMAInstaller
6868

6969
#region Properties & Fields - Non-Public
7070

71-
private readonly AsyncSemaphore _semaphore = new AsyncSemaphore(1);
71+
public AsyncSemaphore Semaphore { get; } = new AsyncSemaphore(1);
7272

7373
#endregion
7474

@@ -110,17 +110,28 @@ public static bool HandleEvent(SMAParameters parameters, out bool firstRun)
110110
using (var mgr = CreateUpdateMgr())
111111
{
112112
Logger.Information($"SuperMemo Assistant version {parameters.SquirrelInstalled} installed. Creating shortcuts.");
113+
113114
mgr.CreateShortcutForThisExe();
114115

116+
mgr.CreateShortcutsForExecutable(
117+
SMAFileSystem.UpdaterExeFile.FullPathWin,
118+
ShortcutLocation.StartMenu,
119+
false, null, null);
120+
115121
return true;
116122
}
117123

118124
if (parameters.SquirrelUninstalled != null)
119125
using (var mgr = CreateUpdateMgr())
120126
{
121127
Logger.Information($"SuperMemo Assistant version {parameters.SquirrelUninstalled} uninstalled. Removing shortcuts.");
128+
122129
mgr.RemoveShortcutForThisExe();
123130

131+
mgr.RemoveShortcutsForExecutable(
132+
SMAFileSystem.UpdaterExeFile.FullPathWin,
133+
ShortcutLocation.StartMenu);
134+
124135
return true;
125136
}
126137

@@ -141,8 +152,6 @@ public static bool HandleEvent(SMAParameters parameters, out bool firstRun)
141152
/// <returns></returns>
142153
public async Task Update()
143154
{
144-
// TODO: Ensure only one Update is running across all instances of SMA (in case SMA is closed during the update process)
145-
// TODO: Offer manual updates
146155
// TODO: Add option to wait for user confirmation to update
147156

148157
if (UpdateEnabled == false)
@@ -158,12 +167,12 @@ public async Task Update()
158167
CancellationTokenSource cts = new CancellationTokenSource(0);
159168
cts.Cancel();
160169

161-
using (await _semaphore.LockAsync(cts.Token))
170+
using (await Semaphore.LockAsync(cts.Token))
162171
using (var updateMgr = CreateUpdateMgr())
163172
{
164173
State = SMAUpdateState.Fetching;
165174

166-
var updateInfo = await updateMgr.CheckForUpdate(false, progress => ProgressPct = progress);
175+
var updateInfo = await updateMgr.CheckForUpdate(true, false, progress => ProgressPct = progress);
167176

168177
if (updateInfo?.ReleasesToApply == null)
169178
{
@@ -202,7 +211,7 @@ public async Task Update()
202211
}
203212
finally
204213
{
205-
_semaphore.Release();
214+
Semaphore.Release();
206215

207216
if (updateVersion != null)
208217
NotifyUpdateResult(updateVersion);

src/AppHosts/SuperMemoAssistant/Installer/SuperMemoAssistant.nuspec

+5-29
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
33
<metadata>
44
<id>SuperMemoAssistant</id>
5-
<!-- version will be replaced by MSBuild -->
5+
<!-- version will be replaced by MSBuild (see SuperMemoAssistant.csproj) -->
66
<version>0.0.0.0</version>
77
<title>SuperMemo Assistant</title>
88
<authors>SuperMemo.wiki</authors>
@@ -12,34 +12,10 @@
1212
<requireLicenseAcceptance>false</requireLicenseAcceptance>
1313
<copyright></copyright>
1414
<dependencies />
15-
<releaseNotes>- Added: SuperMemo 18.04 compatibility #138
16-
- Added: automated ChangeLog and NuPkg Release notes #52
17-
- Added: Splash screen (also overrides SuperMemo's) #100
18-
- Added: Plugin labels (e.g. Official, Verified)
19-
- Added: A ChangeLog Popup after update, and a Change Logs Tab in the Settings #134
20-
- Added: Limited settings window to one instance displayed at a time #113
21-
- Added: Tool tips (hints) to UI icons that do not have a label #130
22-
- Added: During installation, the confirmation popup displays the install folder destination #129
23-
- Added: Import collection from SuperMemo (supermemo.ini) setup step #73
24-
- Added Notifications #53
25-
- Added Notification + Option to restart on plugin crash
26-
- Added plugin labels #133
27-
- Added ToolTips to UI icons #130
28-
- Added install destination folder in confirmation popup message #129 (Squirrel.Windows)
29-
- Added cancel button + reset in Collection Selection #117
30-
- Added a setup step to import collections from supermemo.ini #73
31-
- Added CfgBase with reset on cancel
32-
- Added automatic version configuration
33-
- Added more documentation
34-
- Updated: ChangeLogs is now an embedded resource
35-
- Updated: NuSpec dependencies version
36-
- Updated: Packages
37-
- Updated: ChangeLogs
38-
- Fixed: Change Log window now displays correctly
39-
- Fixed: Wrong offsets for Hook and Concept in NativeDataCfg.json
40-
- Fixed: Collection Selection &gt; Options, and other option windows can now be canceled and revert changes #117
41-
- Misc: Cleaned up SMAInstaller from legacy Change Log code
42-
- Several other minor updates
15+
<!-- releaseNotes will be replaced by MSBuild.Tools (see SuperMemoAssistant.csproj and https://github.com/alexis-/MSBuild.Tools) -->
16+
<releaseNotes>- Fixed: Updated plugin does not refresh in the UI (still happens in the Browse tab)
17+
- Fixed: Occasional error when updating a Plugin
18+
- Misc: Reorganized Template plugin
4319
</releaseNotes>
4420
</metadata>
4521
<files>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#region License & Metadata
2+
3+
// The MIT License (MIT)
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a
6+
// copy of this software and associated documentation files (the "Software"),
7+
// to deal in the Software without restriction, including without limitation
8+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+
// and/or sell copies of the Software, and to permit persons to whom the
10+
// Software is furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in
13+
// all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
// DEALINGS IN THE SOFTWARE.
22+
//
23+
//
24+
// Modified On: 2020/03/19 01:50
25+
// Modified By: Alexis
26+
27+
#endregion
28+
29+
30+
31+
32+
using System.Collections.Generic;
33+
using System.Runtime.Serialization;
34+
35+
namespace SuperMemoAssistant.Models
36+
{
37+
[DataContract]
38+
internal class AppPayload
39+
40+
{
41+
#region Properties & Fields - Public
42+
43+
/// <summary>A list of command line arguments.</summary>
44+
[DataMember]
45+
public List<string> CommandLineArguments { get; set; } = new List<string>();
46+
47+
#endregion
48+
}
49+
}

src/AppHosts/SuperMemoAssistant/Models/SMAExitCodes.cs

+6-5
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ public static class SMAExitCodes
3535
{
3636
#region Constants & Statics
3737

38-
public const int ExitCodeParametersError = 1;
39-
public const int ExitCodeDependencyError = 2;
40-
public const int ExitCodeConfigError = 3;
41-
public const int ExitCodeSMASetupError = 4;
42-
public const int ExitCodeSMAStartupError = 5;
38+
public const int ExitCodeParametersError = 1;
39+
public const int ExitCodeDependencyError = 2;
40+
public const int ExitCodeConfigError = 3;
41+
public const int ExitCodeSMASetupError = 4;
42+
public const int ExitCodeSMAStartupError = 5;
43+
public const int ExitCodeSMAAlreadyRunning = 6;
4344

4445
#endregion
4546
}

src/AppHosts/SuperMemoAssistant/Properties/AssemblyInfo.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@
8484
//
8585
// You can specify all the values or you can default the Build and Revision Numbers
8686
// by using the '*' as shown below:
87-
// [assembly: AssemblyVersion("1.0.*")]
88-
[assembly: AssemblyVersion("2.0.3.450")]
89-
[assembly: AssemblyFileVersion("2.0.3.450")]
87+
[assembly: AssemblyVersion("2.0.4.82")]
88+
[assembly: AssemblyFileVersion("2.0.4.82")]
9089

91-
[assembly: AssemblyInformationalVersion("2.0.3")]
90+
[assembly: AssemblyInformationalVersion("2.0.4")]

0 commit comments

Comments
 (0)