diff --git a/Installer/Package.appxmanifest b/Installer/Package.appxmanifest index 33ee2f66..3864dbaa 100644 --- a/Installer/Package.appxmanifest +++ b/Installer/Package.appxmanifest @@ -11,7 +11,7 @@ + Version="1.0.69.0" /> PRemoteM diff --git a/Shawn.Utils b/Shawn.Utils index 09f13fd2..dba2e631 160000 --- a/Shawn.Utils +++ b/Shawn.Utils @@ -1 +1 @@ -Subproject commit 09f13fd2151d4cf55792132e92cc6900509473e9 +Subproject commit dba2e63185d6a2f3f4a53ff1a40d0ab165ebd5ef diff --git a/Ui/AppVersion.cs b/Ui/AppVersion.cs index 95810dba..c28cb33e 100644 --- a/Ui/AppVersion.cs +++ b/Ui/AppVersion.cs @@ -7,7 +7,7 @@ public static class AppVersion public const uint Major = 0; public const uint Minor = 7; public const uint Patch = 2; - public const uint Build = 7; + public const uint Build = 8; public const string PreRelease = ""; // e.g. "alpha" "beta.2" public static readonly VersionHelper.Version VersionData = new VersionHelper.Version(Major, Minor, Patch, Build, PreRelease); @@ -17,7 +17,6 @@ public static class AppVersion public static readonly string[] UpdateUrls = { "https://github.com/1Remote/1Remote", - "https://github.com/1Remote/PRemoteM", }; } } \ No newline at end of file diff --git a/Ui/Service/ConfigurationService.cs b/Ui/Service/ConfigurationService.cs index c0ceb9f0..265e85c2 100644 --- a/Ui/Service/ConfigurationService.cs +++ b/Ui/Service/ConfigurationService.cs @@ -6,10 +6,12 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows.Input; using Newtonsoft.Json; using PRM.Model.DAO; +using PRM.Utils; using Shawn.Utils; using Shawn.Utils.Wpf; using VariableKeywordMatcher.Provider.DirectMatch; @@ -22,9 +24,14 @@ public class EngagementSettings public DateTime InstallTime = DateTime.Today; public bool DoNotShowAgain = false; public string DoNotShowAgainVersionString = ""; + public DateTime LastRequestRatingsTime = DateTime.MinValue; [Newtonsoft.Json.JsonIgnore] public VersionHelper.Version DoNotShowAgainVersion => VersionHelper.Version.FromString(DoNotShowAgainVersionString); - public DateTime LastRequestRatingsTime = DateTime.MinValue; + + + public string BreakingChangeAlertVersionString = ""; + [Newtonsoft.Json.JsonIgnore] + public VersionHelper.Version BreakingChangeAlertVersion => VersionHelper.Version.FromString(BreakingChangeAlertVersionString); public int ConnectCount = 0; } public class GeneralConfig @@ -210,10 +217,23 @@ public void Save() { if (!CanSave) return; CanSave = false; - var fi = new FileInfo(AppPathHelper.Instance.ProfileJsonPath); - if (fi?.Directory?.Exists == false) - fi.Directory.Create(); - File.WriteAllText(AppPathHelper.Instance.ProfileJsonPath, JsonConvert.SerializeObject(this._cfg, Formatting.Indented), Encoding.UTF8); + for (int i = 0; i < 3; i++) + { + if(i > 0) + Thread.Sleep(100); + try + { + var fi = new FileInfo(AppPathHelper.Instance.ProfileJsonPath); + if (fi?.Directory?.Exists == false) + fi.Directory.Create(); + File.WriteAllText(AppPathHelper.Instance.ProfileJsonPath, JsonConvert.SerializeObject(this._cfg, Formatting.Indented), Encoding.UTF8); + break; + } + catch (Exception e) + { + MsAppCenterHelper.Error(e); + } + } CanSave = true; } diff --git a/Ui/Service/LocalityService.cs b/Ui/Service/LocalityService.cs index 373a59f7..a8a61246 100644 --- a/Ui/Service/LocalityService.cs +++ b/Ui/Service/LocalityService.cs @@ -7,6 +7,7 @@ using System.Windows; using Newtonsoft.Json; using PRM.Model.Protocol; +using PRM.Utils; using Shawn.Utils; namespace PRM.Service @@ -199,7 +200,14 @@ private void Save() var fi = new FileInfo(AppPathHelper.Instance.LocalityJsonPath); if (fi?.Directory?.Exists == false) fi.Directory.Create(); - File.WriteAllText(AppPathHelper.Instance.LocalityJsonPath, JsonConvert.SerializeObject(this._localitySettings, Formatting.Indented), Encoding.UTF8); + try + { + File.WriteAllText(AppPathHelper.Instance.LocalityJsonPath, JsonConvert.SerializeObject(this._localitySettings, Formatting.Indented), Encoding.UTF8); + } + catch (Exception e) + { + MsAppCenterHelper.Error(e); + } CanSave = true; } } diff --git a/Ui/Service/ProtocolConfigurationService.cs b/Ui/Service/ProtocolConfigurationService.cs index 7504fab2..af75259d 100644 --- a/Ui/Service/ProtocolConfigurationService.cs +++ b/Ui/Service/ProtocolConfigurationService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Net.Sockets; using System.Text; +using System.Threading; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PRM.Model; @@ -12,6 +13,7 @@ using PRM.Model.Protocol.Base; using PRM.Model.ProtocolRunner; using PRM.Model.ProtocolRunner.Default; +using PRM.Utils; using Shawn.Utils; namespace PRM.Service @@ -190,7 +192,20 @@ public void Save() } } var file = Path.Combine(AppPathHelper.Instance.ProtocolRunnerDirPath, $"{protocolName}.json"); - File.WriteAllText(file, JsonConvert.SerializeObject(config, Formatting.Indented), Encoding.UTF8); + for (int i = 0; i < 3; i++) + { + if (i > 0) + Thread.Sleep(100); + try + { + File.WriteAllText(file, JsonConvert.SerializeObject(config, Formatting.Indented), Encoding.UTF8); + break; + } + catch (Exception e) + { + MsAppCenterHelper.Error(e); + } + } } } } diff --git a/Ui/Service/SessionControlService.cs b/Ui/Service/SessionControlService.cs index b5b81094..f6c18282 100644 --- a/Ui/Service/SessionControlService.cs +++ b/Ui/Service/SessionControlService.cs @@ -5,11 +5,14 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using MSTSCLib; +using Newtonsoft.Json; using PRM.Model; +using PRM.Model.DAO.Dapper; using PRM.Model.Protocol; using PRM.Model.Protocol.Base; using PRM.Model.ProtocolRunner; @@ -20,6 +23,7 @@ using PRM.View.Host.ProtocolHosts; using Shawn.Utils; using Shawn.Utils.Wpf; +using Shawn.Utils.WpfResources.Theme.Styles; using Stylet; using ProtocolHostStatus = PRM.View.Host.ProtocolHosts.ProtocolHostStatus; using Screen = System.Windows.Forms.Screen; @@ -73,13 +77,16 @@ private bool ActivateOrReConnIfServerSessionIsOpened(ProtocolBase server) if (server.IsOnlyOneInstance() && _connectionId2Hosts.ContainsKey(serverId.ToString())) { SimpleLogHelper.Debug($"_connectionId2Hosts ContainsKey {serverId.ToString()}"); - if (_connectionId2Hosts[serverId.ToString()].ParentWindow is TabWindowBase t) + if (_connectionId2Hosts[serverId.ToString()].ParentWindow is { } win) { - var s = t.GetViewModel().Items.FirstOrDefault(x => x.Content?.ProtocolServer?.Id == serverId); - if (s != null) - t.GetViewModel().SelectedItem = s; + if (win is TabWindowBase tab) + { + var s = tab.GetViewModel().Items.FirstOrDefault(x => x.Content?.ProtocolServer?.Id == serverId); + if (s != null) + tab.GetViewModel().SelectedItem = s; + } - if (t.IsClosed) + if (win.IsClosed) { MarkProtocolHostToClose(new string[] { serverId.ToString() }); CleanupProtocolsAndWindows(); @@ -88,8 +95,15 @@ private bool ActivateOrReConnIfServerSessionIsOpened(ProtocolBase server) try { - if (t.IsClosing == false) t.Show(); - if (t.IsClosing == false) t.Activate(); + Execute.OnUIThreadSync(() => + { + if (win.IsClosing == false) + { + win.WindowState = win.WindowState == WindowState.Minimized ? WindowState.Normal : win.WindowState; + win.Show(); + win.Activate(); + } + }); } catch (Exception e) { @@ -120,7 +134,20 @@ private void ConnectRdpByMstsc(RDP rdp) // write a .rdp file for mstsc.exe if (_context.DataService != null) { - File.WriteAllText(rdpFile, rdp.ToRdpConfig(_context.DataService).ToString()); + for (int i = 0; i < 3; i++) + { + if (i > 0) + Thread.Sleep(100); + try + { + File.WriteAllText(rdpFile, rdp.ToRdpConfig(_context.DataService).ToString()); + break; + } + catch (Exception e) + { + MsAppCenterHelper.Error(e); + } + } var p = new Process { StartInfo = @@ -167,7 +194,20 @@ private void ConnectRemoteApp(RdpApp remoteApp) // write a .rdp file for mstsc.exe if (_context.DataService != null) { - File.WriteAllText(rdpFile, remoteApp.ToRdpConfig(_context.DataService).ToString()); + for (int i = 0; i < 3; i++) + { + if (i > 0) + Thread.Sleep(100); + try + { + File.WriteAllText(rdpFile, remoteApp.ToRdpConfig(_context.DataService).ToString()); + break; + } + catch (Exception e) + { + MsAppCenterHelper.Error(e); + } + } var p = new Process { StartInfo = @@ -290,10 +330,7 @@ private void ConnectWithTab(ProtocolBase server, Runner runner, string assignTab tab.AddItem(new TabItemViewModel(host, server.DisplayName)); _connectionId2Hosts.TryAdd(host.ConnectionId, host); host.Conn(); - if (tab.WindowState == WindowState.Minimized) - { - tab.WindowState = WindowState.Normal; - } + tab.WindowState = tab.WindowState == WindowState.Minimized ? WindowState.Normal : tab.WindowState; tab.Activate(); }); } diff --git a/Ui/Service/TaskTrayService.cs b/Ui/Service/TaskTrayService.cs index 903a4987..2dde29f9 100644 --- a/Ui/Service/TaskTrayService.cs +++ b/Ui/Service/TaskTrayService.cs @@ -103,19 +103,19 @@ private void ReloadTaskTrayContextMenu() var about = new System.Windows.Forms.ToolStripMenuItem(IoC.Get().Translate("About") + $" {Assert.APP_DISPLAY_NAME}"); about.Click += (sender, args) => { - //HyperlinkHelper.OpenUriBySystem("https://github.com/1Remote/PRemoteM"); + //HyperlinkHelper.OpenUriBySystem("https://github.com/1Remote/1Remote"); IoC.Get().ShowMe(true); IoC.Get().CmdGoAboutPage.Execute(); }; var linkHowToUse = new System.Windows.Forms.ToolStripMenuItem(IoC.Get().Translate("about_page_how_to_use")); linkHowToUse.Click += (sender, args) => { - HyperlinkHelper.OpenUriBySystem("https://github.com/1Remote/PRemoteM/wiki"); + HyperlinkHelper.OpenUriBySystem("https://1remote.github.io/usage/quick-start/"); }; var linkFeedback = new System.Windows.Forms.ToolStripMenuItem(IoC.Get().Translate("about_page_feedback")); linkFeedback.Click += (sender, args) => { - HyperlinkHelper.OpenUriBySystem("https://github.com/1Remote/PRemoteM/issues"); + HyperlinkHelper.OpenUriBySystem("https://github.com/1Remote/1Remote/issues"); }; var exit = new System.Windows.Forms.ToolStripMenuItem(IoC.Get().Translate("Exit")); exit.Click += (sender, args) => diff --git a/Ui/Utils/KiTTY/IKittyConnectable.cs b/Ui/Utils/KiTTY/IKittyConnectable.cs index e2b52c38..10fcaf90 100644 --- a/Ui/Utils/KiTTY/IKittyConnectable.cs +++ b/Ui/Utils/KiTTY/IKittyConnectable.cs @@ -1,7 +1,9 @@ using System; using System.Diagnostics; using System.IO; +using System.IO.Compression; using System.Linq; +using System.Threading; using Microsoft.Win32; using Newtonsoft.Json; using PRM.Model; @@ -223,8 +225,15 @@ public static void InstallKitty(this IKittyConnectable iKittyConnectable) kitty.Close(); } - File.WriteAllText(Path.Combine(fi!.Directory!.FullName, "kitty.ini"), - @" + for (int i = 0; i < 3; i++) + { + if (i > 0) + Thread.Sleep(100); + try + { + + File.WriteAllText(Path.Combine(fi!.Directory!.FullName, "kitty.ini"), + @" [Agent] [ConfigBox] dblclick=open @@ -266,6 +275,13 @@ public static void InstallKitty(this IKittyConnectable iKittyConnectable) [Launcher] reload=yes "); + break; + } + catch (Exception e) + { + MsAppCenterHelper.Error(e); + } + } } public static string GetKittyExeFullName() diff --git a/Ui/Utils/KiTTY/KittyConfig.cs b/Ui/Utils/KiTTY/KittyConfig.cs index d4642462..2dce3da0 100644 --- a/Ui/Utils/KiTTY/KittyConfig.cs +++ b/Ui/Utils/KiTTY/KittyConfig.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.IO; +using System.IO.Compression; using System.Linq; using System.Text; +using System.Threading; using Microsoft.Win32; using Shawn.Utils; @@ -391,10 +393,23 @@ private void SaveToKittyPortableConfig(string kittyPath) sb.AppendLine($@"{item.Key}\{item.Value}\"); } - var fi = new FileInfo(configPath); - if (fi?.Directory?.Exists == false) - fi.Directory.Create(); - File.WriteAllText(configPath, sb.ToString(), Encoding.UTF8); + for (int i = 0; i < 3; i++) + { + if (i > 0) + Thread.Sleep(100); + try + { + var fi = new FileInfo(configPath); + if (fi?.Directory?.Exists == false) + fi.Directory.Create(); + File.WriteAllText(configPath, sb.ToString(), Encoding.UTF8); + break; + } + catch (Exception e) + { + MsAppCenterHelper.Error(e); + } + } } catch (Exception e) { diff --git a/Ui/View/AboutPageView.xaml b/Ui/View/AboutPageView.xaml index 92e52029..4927a0d1 100644 --- a/Ui/View/AboutPageView.xaml +++ b/Ui/View/AboutPageView.xaml @@ -105,7 +105,7 @@ - + - + How to use @@ -191,7 +191,7 @@ - + @@ -217,22 +217,6 @@ - diff --git a/Ui/View/AboutPageViewModel.cs b/Ui/View/AboutPageViewModel.cs index 74d77d41..fcc867d0 100644 --- a/Ui/View/AboutPageViewModel.cs +++ b/Ui/View/AboutPageViewModel.cs @@ -1,8 +1,9 @@ using System.Timers; -using System.Windows.Input; using PRM.Service; using Shawn.Utils; using Shawn.Utils.Wpf; +using Shawn.Utils.Wpf.Controls; +using Stylet; namespace PRM.View { @@ -26,9 +27,6 @@ public AboutPageViewModel() checker.CheckUpdateAsync(); }; checker.CheckUpdateAsync(); - - - CurrentVersion = AppVersion.Version; } ~AboutPageViewModel() @@ -37,7 +35,7 @@ public AboutPageViewModel() _checkUpdateTimer?.Dispose(); } - public string CurrentVersion { get; } + public string CurrentVersion => AppVersion.Version; private string _newVersion = ""; @@ -48,17 +46,33 @@ public string NewVersion } private string _newVersionUrl = ""; - public string NewVersionUrl { get => _newVersionUrl; set => SetAndNotifyIfChanged(ref _newVersionUrl, value); } - private void OnNewVersionRelease(string version, string url) + private bool _isBreakingNewVersion; + public bool IsBreakingNewVersion + { + get => _isBreakingNewVersion; + set => SetAndNotifyIfChanged(ref _isBreakingNewVersion, value); + } + + private void OnNewVersionRelease(string version, string url, bool b) { this.NewVersion = version; this.NewVersionUrl = url; + this.IsBreakingNewVersion = b; + var v = IoC.Get().Engagement.BreakingChangeAlertVersion; + if (this.IsBreakingNewVersion + && VersionHelper.Version.FromString(version) > v) + { + Execute.OnUIThreadSync(() => + { + IoC.Get().ShowDialog(IoC.Get()); + }); + } } @@ -74,6 +88,29 @@ public RelayCommand CmdClose } } + private RelayCommand? _cmdUpdate; + public RelayCommand CmdUpdate + { + get + { + return _cmdUpdate ??= new RelayCommand((o) => + { + if (IsBreakingNewVersion) + { + IoC.Get().ShowDialog(IoC.Get(), ownerViewModel: IoC.Get()); + } + else + { +#if FOR_MICROSOFT_STORE_ONLY + HyperlinkHelper.OpenUriBySystem("ms-windows-store://review/?productid=9PNMNF92JNFP"); +#else + HyperlinkHelper.OpenUriBySystem(NewVersionUrl); +#endif + } + }); + } + } + //public void SupportText_OnMouseRightButtonDown(object sender, MouseButtonEventArgs e) //{ // if (e.ClickCount == 3) diff --git a/Ui/View/BreakingChangeUpdateView.xaml b/Ui/View/BreakingChangeUpdateView.xaml new file mode 100644 index 00000000..c45b8342 --- /dev/null +++ b/Ui/View/BreakingChangeUpdateView.xaml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ui/View/BreakingChangeUpdateViewModel.cs b/Ui/View/BreakingChangeUpdateViewModel.cs new file mode 100644 index 00000000..84384b39 --- /dev/null +++ b/Ui/View/BreakingChangeUpdateViewModel.cs @@ -0,0 +1,45 @@ +using PRM.Service; +using PRM.Utils; +using Shawn.Utils.Wpf; +using Shawn.Utils.Wpf.Controls; + +namespace PRM.View +{ + /// + /// Default implementation of IMessageBoxViewModel, and is therefore the ViewModel shown by default by ShowMessageBox + /// + public class BreakingChangeUpdateViewModel : NotifyPropertyChangedBaseScreen + { + public AboutPageViewModel AboutPageViewModel => IoC.Get(); + + + private RelayCommand? _cmdUpdate; + public RelayCommand CmdUpdate + { + get + { + return _cmdUpdate ??= new RelayCommand((o) => + { +#if FOR_MICROSOFT_STORE_ONLY + HyperlinkHelper.OpenUriBySystem("ms-windows-store://review/?productid=9PNMNF92JNFP"); +#else + HyperlinkHelper.OpenUriBySystem(AboutPageViewModel.NewVersionUrl); +#endif + }); + } + } + private RelayCommand? _cmdClose; + public RelayCommand CmdClose + { + get + { + return _cmdClose ??= new RelayCommand((o) => + { + IoC.Get().Engagement.BreakingChangeAlertVersionString = AboutPageViewModel.NewVersion; + IoC.Get().Save(); + this.RequestClose(true); + }); + } + } + } +} diff --git a/Ui/View/Editor/Forms/RdpAppForm.xaml b/Ui/View/Editor/Forms/RdpAppForm.xaml index 8ccade64..999990ab 100644 --- a/Ui/View/Editor/Forms/RdpAppForm.xaml +++ b/Ui/View/Editor/Forms/RdpAppForm.xaml @@ -80,7 +80,7 @@ - + check how to config. diff --git a/Ui/View/Editor/Forms/RdpForm.xaml b/Ui/View/Editor/Forms/RdpForm.xaml index 69fde9d7..10415cbd 100644 --- a/Ui/View/Editor/Forms/RdpForm.xaml +++ b/Ui/View/Editor/Forms/RdpForm.xaml @@ -112,7 +112,7 @@ - (?) @@ -338,7 +338,7 @@ - (?) @@ -440,7 +440,7 @@ - (?) diff --git a/Ui/View/Editor/Forms/VncForm.xaml b/Ui/View/Editor/Forms/VncForm.xaml index 230decc9..ca228725 100644 --- a/Ui/View/Editor/Forms/VncForm.xaml +++ b/Ui/View/Editor/Forms/VncForm.xaml @@ -68,7 +68,7 @@ Caution: RFB protocol over 3.8 are proprietary. If you would like using RFB 3.8+, you have to try your own VNC runner: - + [More details] diff --git a/Ui/View/ErrorReport/ErrorReportWindow.xaml b/Ui/View/ErrorReport/ErrorReportWindow.xaml index 2d2744ef..5c3c8113 100644 --- a/Ui/View/ErrorReport/ErrorReportWindow.xaml +++ b/Ui/View/ErrorReport/ErrorReportWindow.xaml @@ -131,7 +131,7 @@