diff --git a/Deploy/build-release.ps1 b/Deploy/binary_zip.ps1 similarity index 82% rename from Deploy/build-release.ps1 rename to Deploy/binary_zip.ps1 index ec0dca4089..712eebb3eb 100644 --- a/Deploy/build-release.ps1 +++ b/Deploy/binary_zip.ps1 @@ -1,8 +1,8 @@ $sourceDirectoryName = $env:APPVEYOR_BUILD_FOLDER + "\Output\Release" $fileName = $env:APPVEYOR_BUILD_FOLDER + "\Wox-$env:APPVEYOR_BUILD_VERSION.zip" -$current_path = Convert-Path . -Write-Host "Current path: " + $current_path +$currentPath = Convert-Path . +Write-Host "Current path: " + $currentPath Write-Host "Target path: " + $sourceDirectoryName [Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") diff --git a/Deploy/nuget.ps1 b/Deploy/nuget.ps1 index 63418d798a..363566475b 100644 --- a/Deploy/nuget.ps1 +++ b/Deploy/nuget.ps1 @@ -1,7 +1,7 @@ $path = $env:APPVEYOR_BUILD_FOLDER + "\Deploy\wox.plugin.nuspec" -$current_path = Convert-Path . -Write-Host "Current path: " + $current_path -Write-Host "Target path: " + $path +$currentPath = Convert-Path . +Write-Host "Current path:" + $currentPath +Write-Host "nuspec path:" + $path & nuget pack $path -Version $env:APPVEYOR_BUILD_VERSION diff --git a/Deploy/squirrel_installer.ps1 b/Deploy/squirrel_installer.ps1 new file mode 100644 index 0000000000..9c1d010d1f --- /dev/null +++ b/Deploy/squirrel_installer.ps1 @@ -0,0 +1,15 @@ +$currentPath = Convert-Path . +Write-Host "Current path: " + $currentPath + +$path = $env:APPVEYOR_BUILD_FOLDER + "\Deploy\wox.nuspec" +Write-Host "nuspec path: " + $path +& nuget.exe pack $path -Version $env:APPVEYOR_BUILD_VERSION -Properties Configuration=Release + +$nupkgPath = $env:APPVEYOR_BUILD_FOLDER + "\Wox." + $env:APPVEYOR_BUILD_VERSION + ".nupkg" +Write-Host "nupkg path: " + $nupkgPath + +# must use Squirrel.com, Squirrel.exe will produce nothing +$squirrelPath = $env:APPVEYOR_BUILD_FOLDER + "\packages\squirrel*\tools\Squirrel.com" +Write-Host "squirrel path: " + $squirrelPath +$iconPath = $env:APPVEYOR_BUILD_FOLDER + "\Wox\Resources\app.ico" +& $squirrelPath --releasify $nupkgPath --setupIcon $iconPath --no-msi diff --git a/Deploy/wox.nuspec b/Deploy/wox.nuspec new file mode 100644 index 0000000000..448cc8ea35 --- /dev/null +++ b/Deploy/wox.nuspec @@ -0,0 +1,16 @@ + + + + Wox + Wox + $version$ + happlebao + https://github.com/Wox-launcher/Wox + https://raw.githubusercontent.com/Wox-launcher/Wox/master/Wox/Images/app.png + false + Wox - a launcher for windows + + + + + diff --git a/Deploy/wox.plugin.nuspec b/Deploy/wox.plugin.nuspec index d090bc9c5c..d88c91af8c 100644 --- a/Deploy/wox.plugin.nuspec +++ b/Deploy/wox.plugin.nuspec @@ -11,6 +11,6 @@ wox - + diff --git a/SolutionAssemblyInfo.cs b/SolutionAssemblyInfo.cs index e900203594..980e82176d 100644 --- a/SolutionAssemblyInfo.cs +++ b/SolutionAssemblyInfo.cs @@ -9,12 +9,12 @@ using System.Runtime.InteropServices; [assembly: AssemblyDescription("Release build, https://github.com/Wox-launcher/Wox")] #endif -[assembly: AssemblyCompany("Wox-launcher")] +[assembly: AssemblyCompany("Wox")] [assembly: AssemblyProduct("Wox")] [assembly: AssemblyCopyright("The MIT License (MIT)")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: AssemblyVersion("1.2.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] -[assembly: AssemblyInformationalVersion("1.2-beta.2")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.2.0")] +[assembly: AssemblyInformationalVersion("1.2.0")] \ No newline at end of file diff --git a/Wox.Infrastructure/Wox.cs b/Wox.Infrastructure/Wox.cs index 94a5c45db5..3e04189dac 100644 --- a/Wox.Infrastructure/Wox.cs +++ b/Wox.Infrastructure/Wox.cs @@ -15,5 +15,6 @@ namespace Wox.Infrastructure public static readonly string UserDirectory = Path.Combine(DataPath, Plugins); public static readonly string PreinstalledDirectory = Path.Combine(ProgramPath, Plugins); public static readonly string SettingsPath = Path.Combine(DataPath, Settings); + public const string Github = "https://github.com/Wox-launcher/Wox"; } } diff --git a/Wox/App.xaml b/Wox/App.xaml index d7c5a879e3..1d7493d271 100644 --- a/Wox/App.xaml +++ b/Wox/App.xaml @@ -1,8 +1,8 @@  + Startup="OnStartup" + Activated="OnActivated"> diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs index 0855fd8117..842bd91a40 100644 --- a/Wox/App.xaml.cs +++ b/Wox/App.xaml.cs @@ -1,43 +1,43 @@ using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using System.Windows; -using Wox.CommandArgs; +using Squirrel; using Wox.Core.Plugin; using Wox.Helper; using Wox.Infrastructure.Image; using Wox.ViewModel; using Stopwatch = Wox.Infrastructure.Stopwatch; +using Wox.Infrastructure.Logger; namespace Wox { - public partial class App : ISingleInstanceApp + public partial class App : ISingleInstanceApp, IDisposable { private const string Unique = "Wox_Unique_Application_Mutex"; public static MainWindow Window { get; private set; } public static PublicAPIInstance API { get; private set; } - private bool _saved; + private static bool _disposed; + public static UpdateManager Updater; [STAThread] public static void Main() { + RegisterAppDomainUnhandledException(); if (SingleInstance.InitializeAsFirstInstance(Unique)) { - var application = new App(); - application.InitializeComponent(); - application.Run(); - SingleInstance.Cleanup(); + using (var application = new App()) + { + application.InitializeComponent(); + application.Run(); + } } } - protected override void OnStartup(StartupEventArgs e) + private void OnStartup(object sender, StartupEventArgs e) { Stopwatch.Debug("Startup Time", () => { - base.OnStartup(e); - RegisterUnhandledException(); + RegisterDispatcherUnhandledException(); ImageLoader.PreloadImages(); @@ -47,53 +47,72 @@ namespace Wox PluginManager.InitializePlugins(API, pluginsSettings); Window = new MainWindow(mainVM._settings, mainVM); - NotifyIconManager notifyIconManager = new NotifyIconManager(API); - CommandArgsFactory.Execute(e.Args.ToList()); + var _notifyIconManager = new NotifyIconManager(API); + + RegisterExitEvents(); }); } - [Conditional("RELEASE")] - private void RegisterUnhandledException() + private async void OnActivated(object sender, EventArgs e) { - // let exception throw as normal is better for Debug + try + { + using (Updater = await UpdateManager.GitHubUpdateManager(Infrastructure.Wox.Github, prerelease: true)) + { + await Updater.UpdateApp(); + } + } + catch (Exception exception) + { + Log.Error(exception); + } + } + + private void RegisterExitEvents() + { + AppDomain.CurrentDomain.ProcessExit += (s, e) => Dispose(); + Current.Exit += (s, e) => Dispose(); + Current.SessionEnding += (s, e) => Dispose(); + } + [Conditional("RELEASE")] + private void RegisterDispatcherUnhandledException() + { + // let exception throw as normal is better for Debug DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException; + } + + [Conditional("RELEASE")] + private static void RegisterAppDomainUnhandledException() + { + // let exception throw as normal is better for Debug AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle; } - public void OnActivate(IList args) + public void OnActivate() { - if (args.Count > 0 && args[0] == SingleInstance.Restart) - { - API.CloseApp(); - } - else - { - CommandArgsFactory.Execute(args); - } + API.ShowApp(); } - private void OnExit(object sender, ExitEventArgs e) + private static void Save() { - Save(); + var vm = (MainViewModel)Window.DataContext; + vm.Save(); + PluginManager.Save(); + ImageLoader.Save(); + _disposed = true; } - private void OnSessionEnding(object sender, SessionEndingCancelEventArgs e) - { - Save(); - } - private void Save() + public void Dispose() { // if sessionending is called, exit proverbially be called when log off / shutdown // but if sessionending is not called, exit won't be called when log off / shutdown - if (!_saved) + if (!_disposed) { - var vm = (MainViewModel) Window.DataContext; - vm.Save(); - PluginManager.Save(); - ImageLoader.Save(); - _saved = true; + Save(); + Updater?.Dispose(); + SingleInstance.Cleanup(); } } } -} +} \ No newline at end of file diff --git a/Wox/CommandArgs/CommandArgsFactory.cs b/Wox/CommandArgs/CommandArgsFactory.cs index 14a3f99a72..2b7a7b8b5b 100644 --- a/Wox/CommandArgs/CommandArgsFactory.cs +++ b/Wox/CommandArgs/CommandArgsFactory.cs @@ -22,7 +22,8 @@ namespace Wox.CommandArgs public static void Execute(IList args) { // todo restart command line args? - if (args.Count > 0 && args[0] != SingleInstance.Restart) + //if (args.Count > 0 && args[0] != SingleInstance.Restart) + if (args.Count > 0) { string command = args[0]; ICommandArg cmd = commandArgs.FirstOrDefault(o => o.Command.ToLower() == command); diff --git a/Wox/Helper/SingleInstance.cs b/Wox/Helper/SingleInstance.cs index 58fe0adef4..b26f59d7dd 100644 --- a/Wox/Helper/SingleInstance.cs +++ b/Wox/Helper/SingleInstance.cs @@ -186,7 +186,7 @@ namespace Wox.Helper public interface ISingleInstanceApp { - void OnActivate(IList args); + void OnActivate(); } /// @@ -238,23 +238,10 @@ namespace Wox.Helper /// private static IpcServerChannel channel; - /// - /// List of command line arguments for the application. - /// - private static IList commandLineArgs; - #endregion #region Public Properties - /// - /// Gets list of command line arguments for the application. - /// - public static IList CommandLineArgs - { - get { return commandLineArgs; } - } - #endregion #region Public Methods @@ -266,10 +253,6 @@ namespace Wox.Helper /// True if this is the first instance of the application. public static bool InitializeAsFirstInstance( string uniqueName ) { - commandLineArgs = GetCommandLineArgs(uniqueName); - //remove execute path itself - commandLineArgs.RemoveAt(0); - // Build unique application Id and the IPC channel name. string applicationIdentifier = uniqueName + Environment.UserName; @@ -283,17 +266,9 @@ namespace Wox.Helper CreateRemoteService(channelName); return true; } - // Restart - else if (commandLineArgs.Count > 0 && commandLineArgs[0] == Restart) - { - SignalFirstInstance(channelName, commandLineArgs); - singleInstanceMutex.WaitOne(TimeSpan.FromSeconds(10)); - CreateRemoteService(channelName); - return true; - } else { - SignalFirstInstance(channelName, commandLineArgs); + SignalFirstInstance(channelName); return false; } } @@ -398,7 +373,7 @@ namespace Wox.Helper /// /// Command line arguments for the second instance, passed to the first instance to take appropriate action. /// - private static void SignalFirstInstance(string channelName, IList args) + private static void SignalFirstInstance(string channelName) { IpcClientChannel secondInstanceChannel = new IpcClientChannel(); ChannelServices.RegisterChannel(secondInstanceChannel, true); @@ -414,7 +389,7 @@ namespace Wox.Helper { // Invoke a method of the remote service exposed by the first instance passing on the command line // arguments and causing the first instance to activate itself - firstInstanceRemoteServiceReference.InvokeFirstInstance(args); + firstInstanceRemoteServiceReference.InvokeFirstInstance(); } } @@ -423,11 +398,9 @@ namespace Wox.Helper /// /// Callback argument. /// Always null. - private static object ActivateFirstInstanceCallback(object arg) + private static object ActivateFirstInstanceCallback(object o) { - // Get command line args to be passed to first instance - IList args = arg as IList; - ActivateFirstInstance(args); + ActivateFirstInstance(); return null; } @@ -435,7 +408,7 @@ namespace Wox.Helper /// Activates the first instance of the application with arguments from a second instance. /// /// List of arguments to supply the first instance of the application. - private static void ActivateFirstInstance(IList args) + private static void ActivateFirstInstance() { // Set main window state and process command line args if (Application.Current == null) @@ -443,7 +416,7 @@ namespace Wox.Helper return; } - ((TApplication)Application.Current).OnActivate(args); + ((TApplication)Application.Current).OnActivate(); } #endregion @@ -459,14 +432,13 @@ namespace Wox.Helper /// /// Activates the first instance of the application. /// - /// List of arguments to pass to the first instance. - public void InvokeFirstInstance(IList args) + public void InvokeFirstInstance() { if (Application.Current != null) { // Do an asynchronous call to ActivateFirstInstance function Application.Current.Dispatcher.BeginInvoke( - DispatcherPriority.Normal, new DispatcherOperationCallback(ActivateFirstInstanceCallback), args); + DispatcherPriority.Normal, new DispatcherOperationCallback(ActivateFirstInstanceCallback)); } } diff --git a/Wox/PublicAPIInstance.cs b/Wox/PublicAPIInstance.cs index 4bfbc41a38..500df1217d 100644 --- a/Wox/PublicAPIInstance.cs +++ b/Wox/PublicAPIInstance.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using System.Windows; using NHotkey; using NHotkey.Wpf; +using Squirrel; using Wox.Core.Plugin; using Wox.Core.Resource; using Wox.Core.UserSettings; @@ -67,12 +68,7 @@ namespace Wox public void RestarApp() { - ProcessStartInfo info = new ProcessStartInfo - { - FileName = Application.ResourceAssembly.Location, - Arguments = SingleInstance.Restart - }; - Process.Start(info); + UpdateManager.RestartApp(); } public void HideApp() diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 9fb8646837..857b5d521c 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -60,6 +60,18 @@ Wox.App + + ..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.dll + True + + + ..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.MsDelta.dll + True + + + ..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.PatchApi.dll + True + ..\packages\Exceptionless.1.5.2121\lib\net45\Exceptionless.dll True @@ -68,16 +80,28 @@ ..\packages\Exceptionless.1.5.2121\lib\net45\Exceptionless.Models.dll True - - ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll + + ..\packages\squirrel.windows.1.4.0\lib\Net45\ICSharpCode.SharpZipLib.dll True ..\packages\JetBrains.Annotations.10.1.4\lib\net20\JetBrains.Annotations.dll True - - ..\packages\MarkdownSharp.1.13.0.0\lib\35\MarkdownSharp.dll + + ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.dll + True + + + ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Mdb.dll + True + + + ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Pdb.dll + True + + + ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Rocks.dll True @@ -92,8 +116,20 @@ ..\packages\NHotkey.Wpf.1.2.1\lib\net35\NHotkey.Wpf.dll True + + ..\packages\squirrel.windows.1.4.0\lib\Net45\NuGet.Squirrel.dll + True + + + ..\packages\Splat.1.6.2\lib\Net45\Splat.dll + True + + + ..\packages\squirrel.windows.1.4.0\lib\Net45\Squirrel.dll + True + diff --git a/Wox/packages.config b/Wox/packages.config index d6785a0d70..e822764989 100644 --- a/Wox/packages.config +++ b/Wox/packages.config @@ -1,12 +1,15 @@  + - + + + \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index f51c57f9b9..437f7f60ef 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,16 +16,17 @@ after_test: - ps: >- .\Deploy\nuget.ps1 - .\Deploy\build-release.ps1 + .\Deploy\binary_zip.ps1 + + .\Deploy\squirrel_installer.ps1 artifacts: - path: 'Wox-*.zip' - name: release_binary + name: zipped_binary - path: '*.nupkg' name: nuget_package -deploy: -- provider: NuGet - api_key: - secure: yybUOFgBuGVpbmOVZxsurC8OpkClzt9dR+/54WpMWcq6b6oyMatciaelRPnXsjRn - artifact: nuget_package - on: - branch: api +- path: '\Releases\*.exe' + name: installer +- path: '\Releases\*.nupkg' + name: installer +- path: 'Releases\RELEASES' + name: installer \ No newline at end of file