Skip to content

Commit cecb65c

Browse files
authored
Installed & portable mode: Enhance auto updates (#142)
* Add handling of portable mode when updating Additionally: 1. Changed getting version from internally rather than from RELEASES file 2. Added PortableDataPath as a constant so can be used to determine if portable mode is used * Fix incorrectly wired auto update event handler * Fix Sys plugin missing Shutdown command icon * Add check update command to Sys plugin * Add message if current Wox version is latest * Add default silent when auto checking updates in background Silent when current is still the latest version * Move UserData folder to new version location * Changes per review 1. Move IsPortableMode to Constant 2. Merge if statement * Per comment- change variables to be more descriptive UpdateInfo and UpdateManager renamed * Per comment- Add exception handling and message if failed.
1 parent 73705be commit cecb65c

File tree

11 files changed

+201
-43
lines changed

11 files changed

+201
-43
lines changed
22.7 KB
Loading

Plugins/Wox.Plugin.Sys/Main.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,20 @@ private List<Result> Commands()
234234
context.API.GetTranslation("wox_plugin_sys_dlgtext_all_applicableplugins_reloaded"));
235235
return true;
236236
}
237+
},
238+
new Result
239+
{
240+
Title = "Check For Update",
241+
SubTitle = "Check for new Wox update",
242+
IcoPath = "Images\\checkupdate.png",
243+
Action = c =>
244+
{
245+
Application.Current.MainWindow.Hide();
246+
context.API.CheckForNewUpdate();
247+
context.API.ShowMsg("Please wait...",
248+
"Checking for new update");
249+
return true;
250+
}
237251
}
238252
});
239253
return results;

Plugins/Wox.Plugin.Sys/Wox.Plugin.Sys.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,15 @@
7171
</ProjectReference>
7272
</ItemGroup>
7373
<ItemGroup>
74+
<None Include="Images\checkupdate.png">
75+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
76+
</None>
7477
<Content Include="Images\recyclebin.png">
7578
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
7679
</Content>
80+
<None Include="Images\shutdown.png">
81+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
82+
</None>
7783
<Content Include="Images\sleep.png">
7884
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
7985
</Content>

Wox.Core/Updater.cs

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Net;
44
using System.Net.Http;
@@ -10,9 +10,11 @@
1010
using Squirrel;
1111
using Newtonsoft.Json;
1212
using Wox.Core.Resource;
13+
using Wox.Plugin.SharedCommands;
1314
using Wox.Infrastructure;
1415
using Wox.Infrastructure.Http;
1516
using Wox.Infrastructure.Logger;
17+
using System.IO;
1618

1719
namespace Wox.Core
1820
{
@@ -25,14 +27,14 @@ public Updater(string gitHubRepository)
2527
GitHubRepository = gitHubRepository;
2628
}
2729

28-
public async Task UpdateApp()
30+
public async Task UpdateApp(bool silentIfLatestVersion = true)
2931
{
30-
UpdateManager m;
31-
UpdateInfo u;
32+
UpdateManager updateManager;
33+
UpdateInfo newUpdateInfo;
3234

3335
try
3436
{
35-
m = await GitHubUpdateManager(GitHubRepository);
37+
updateManager = await GitHubUpdateManager(GitHubRepository);
3638
}
3739
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException)
3840
{
@@ -43,42 +45,61 @@ public async Task UpdateApp()
4345
try
4446
{
4547
// UpdateApp CheckForUpdate will return value only if the app is squirrel installed
46-
u = await m.CheckForUpdate().NonNull();
48+
newUpdateInfo = await updateManager.CheckForUpdate().NonNull();
4749
}
4850
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException)
4951
{
5052
Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to api.github.com.", e);
51-
m.Dispose();
53+
updateManager.Dispose();
5254
return;
5355
}
5456

55-
var fr = u.FutureReleaseEntry;
56-
var cr = u.CurrentlyInstalledVersion;
57-
Log.Info($"|Updater.UpdateApp|Future Release <{fr.Formatted()}>");
58-
if (fr.Version > cr.Version)
57+
var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString());
58+
var currentVersion = Version.Parse(Constant.Version);
59+
60+
Log.Info($"|Updater.UpdateApp|Future Release <{newUpdateInfo.FutureReleaseEntry.Formatted()}>");
61+
62+
if (newReleaseVersion <= currentVersion)
5963
{
60-
try
61-
{
62-
await m.DownloadReleases(u.ReleasesToApply);
63-
}
64-
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException)
65-
{
66-
Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
67-
m.Dispose();
68-
return;
69-
}
70-
71-
await m.ApplyReleases(u);
72-
await m.CreateUninstallerRegistryEntry();
73-
74-
var newVersionTips = this.NewVersinoTips(fr.Version.ToString());
75-
76-
MessageBox.Show(newVersionTips);
77-
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
64+
if (!silentIfLatestVersion)
65+
MessageBox.Show("You already have the latest Wox version");
66+
updateManager.Dispose();
67+
return;
7868
}
7969

70+
try
71+
{
72+
await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply);
73+
}
74+
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException)
75+
{
76+
Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
77+
updateManager.Dispose();
78+
return;
79+
}
80+
81+
await updateManager.ApplyReleases(newUpdateInfo);
82+
83+
if (Constant.IsPortableMode)
84+
{
85+
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{Constant.PortableFolderName}";
86+
FilesFolders.Copy(Constant.PortableDataPath, targetDestination);
87+
if (!FilesFolders.VerifyBothFolderFilesEqual(Constant.PortableDataPath, targetDestination))
88+
MessageBox.Show(string.Format("Wox was not able to move your user profile data to the new update version. Please manually" +
89+
"move your profile data folder from {0} to {1}", Constant.PortableDataPath, targetDestination));
90+
}
91+
else
92+
{
93+
await updateManager.CreateUninstallerRegistryEntry();
94+
}
95+
96+
var newVersionTips = NewVersinoTips(newReleaseVersion.ToString());
97+
98+
MessageBox.Show(newVersionTips);
99+
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
100+
80101
// always dispose UpdateManager
81-
m.Dispose();
102+
updateManager.Dispose();
82103
}
83104

84105
[UsedImplicitly]

Wox.Infrastructure/Wox.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,29 @@ namespace Wox.Infrastructure
77
{
88
public static class Constant
99
{
10+
public const string Wox = "Wox";
11+
public const string Plugins = "Plugins";
12+
13+
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
14+
public static readonly string ProgramDirectory = Directory.GetParent(Assembly.Location.NonNull()).ToString();
15+
public static readonly string ExecutablePath = Path.Combine(ProgramDirectory, Wox + ".exe");
16+
17+
public static bool IsPortableMode;
18+
public const string PortableFolderName = "UserData";
19+
public static string PortableDataPath = Path.Combine(ProgramDirectory, PortableFolderName);
1020
public static string DetermineDataDirectory()
1121
{
12-
string portableDataPath = Path.Combine(ProgramDirectory, "UserData");
13-
if (Directory.Exists(portableDataPath))
22+
if (Directory.Exists(PortableDataPath))
1423
{
15-
return portableDataPath;
24+
IsPortableMode = true;
25+
return PortableDataPath;
1626
}
1727
else
1828
{
1929
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Wox);
2030
}
2131
}
2232

23-
public const string Wox = "Wox";
24-
public const string Plugins = "Plugins";
25-
26-
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
27-
public static readonly string ProgramDirectory = Directory.GetParent(Assembly.Location.NonNull()).ToString();
28-
public static readonly string ExecutablePath = Path.Combine(ProgramDirectory, Wox + ".exe");
2933
public static readonly string DataDirectory = DetermineDataDirectory();
3034
public static readonly string PluginsDirectory = Path.Combine(DataDirectory, Plugins);
3135
public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins);

Wox.Plugin/IPublicAPI.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ public interface IPublicAPI
7070
/// </summary>
7171
void ReloadAllPluginData();
7272

73+
/// <summary>
74+
/// Check for new Wox update
75+
/// </summary>
76+
void CheckForNewUpdate();
77+
7378
/// <summary>
7479
/// Show message box
7580
/// </summary>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using System.IO;
3+
using System.Windows;
4+
5+
namespace Wox.Plugin.SharedCommands
6+
{
7+
public static class FilesFolders
8+
{
9+
public static void Copy(this string sourcePath, string targetPath)
10+
{
11+
// Get the subdirectories for the specified directory.
12+
DirectoryInfo dir = new DirectoryInfo(sourcePath);
13+
14+
if (!dir.Exists)
15+
{
16+
throw new DirectoryNotFoundException(
17+
"Source directory does not exist or could not be found: "
18+
+ sourcePath);
19+
}
20+
21+
try
22+
{
23+
DirectoryInfo[] dirs = dir.GetDirectories();
24+
// If the destination directory doesn't exist, create it.
25+
if (!Directory.Exists(targetPath))
26+
{
27+
Directory.CreateDirectory(targetPath);
28+
}
29+
30+
// Get the files in the directory and copy them to the new location.
31+
FileInfo[] files = dir.GetFiles();
32+
foreach (FileInfo file in files)
33+
{
34+
string temppath = Path.Combine(targetPath, file.Name);
35+
file.CopyTo(temppath, false);
36+
}
37+
38+
// Recursively copy subdirectories by calling itself on each subdirectory until there are no more to copy
39+
foreach (DirectoryInfo subdir in dirs)
40+
{
41+
string temppath = Path.Combine(targetPath, subdir.Name);
42+
Copy(subdir.FullName, temppath);
43+
}
44+
}
45+
catch (Exception e)
46+
{
47+
#if DEBUG
48+
throw e;
49+
#else
50+
MessageBox.Show(string.Format("Copying path {0} has failed, it will now be deleted for consistency", targetPath));
51+
RemoveFolder(targetPath);
52+
#endif
53+
}
54+
55+
}
56+
57+
public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath)
58+
{
59+
try
60+
{
61+
var fromDir = new DirectoryInfo(fromPath);
62+
var toDir = new DirectoryInfo(toPath);
63+
64+
if (fromDir.GetFiles("*", SearchOption.AllDirectories).Length != toDir.GetFiles("*", SearchOption.AllDirectories).Length)
65+
return false;
66+
67+
if (fromDir.GetDirectories("*", SearchOption.AllDirectories).Length != toDir.GetDirectories("*", SearchOption.AllDirectories).Length)
68+
return false;
69+
70+
return true;
71+
}
72+
catch (Exception e)
73+
{
74+
#if DEBUG
75+
throw e;
76+
#else
77+
MessageBox.Show(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath));
78+
return false;
79+
#endif
80+
}
81+
82+
}
83+
84+
public static void RemoveFolder(this string path)
85+
{
86+
try
87+
{
88+
if (Directory.Exists(path))
89+
Directory.Delete(path, true);
90+
}
91+
catch (Exception e)
92+
{
93+
#if DEBUG
94+
throw e;
95+
#else
96+
MessageBox.Show(string.Format("Not able to delete folder {0}, please go to the location and manually delete it", path));
97+
#endif
98+
}
99+
}
100+
}
101+
}

Wox.Plugin/Wox.Plugin.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
<Compile Include="Query.cs" />
6666
<Compile Include="Result.cs" />
6767
<Compile Include="ActionContext.cs" />
68+
<Compile Include="SharedCommands\FilesFolders.cs" />
6869
<Compile Include="SharedCommands\SearchWeb.cs" />
6970
<Compile Include="SharedCommands\ShellCommand.cs" />
7071
</ItemGroup>

Wox/PublicAPIInstance.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using System.Windows;
77
using Squirrel;
8+
using Wox.Core;
89
using Wox.Core.Plugin;
910
using Wox.Core.Resource;
1011
using Wox.Helper;
@@ -65,6 +66,11 @@ public void RestarApp()
6566
UpdateManager.RestartApp();
6667
}
6768

69+
public void CheckForNewUpdate()
70+
{
71+
_settingsVM.UpdateApp();
72+
}
73+
6874
public void SaveAppAllSettings()
6975
{
7076
_mainVM.Save();

Wox/SettingWindow.xaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
<TabControl Height="auto" SelectedIndex="0">
3434
<TabItem Header="{DynamicResource general}">
3535
<StackPanel Orientation="Vertical">
36-
<CheckBox IsChecked="{Binding Settings.StartWoxOnSystemStartup}" Margin="10">
36+
<CheckBox Margin="10" IsChecked="{Binding Settings.StartWoxOnSystemStartup}"
37+
Checked="OnAutoStartupChecked" Unchecked="OnAutoStartupUncheck">
3738
<TextBlock Text="{DynamicResource startWoxOnSystemStartup}" />
3839
</CheckBox>
3940
<CheckBox Margin="10" IsChecked="{Binding Settings.HideOnStartup}">
@@ -51,8 +52,7 @@
5152
<CheckBox Margin="10" IsChecked="{Binding Settings.IgnoreHotkeysOnFullscreen}">
5253
<TextBlock Text="{DynamicResource ignoreHotkeysOnFullscreen}" />
5354
</CheckBox>
54-
<CheckBox Margin="10" IsChecked="{Binding Settings.AutoUpdates}"
55-
Checked="OnAutoStartupChecked" Unchecked="OnAutoStartupUncheck">
55+
<CheckBox Margin="10" IsChecked="{Binding Settings.AutoUpdates}">
5656
<TextBlock Text="{DynamicResource autoUpdates}" />
5757
</CheckBox>
5858
<CheckBox Margin="10" IsChecked="{Binding Settings.ShouldUsePinyin}">

0 commit comments

Comments
 (0)