public Tuple <bool, string, string> CheckUpdate(string url) { try { var html = HttpHelper.Get(url).ToLower(); var vs = Regex.Match(html, @"latest\sversion:\s*([\d|.]*)"); if (vs.Success) { var tmp = vs.ToString(); var version = tmp.Substring(tmp.IndexOf("version:") + "version:".Length + 1).Trim(); if (Compare(_ignoreVersion, version)) { if (Compare(version)) { return(new Tuple <bool, string, string>(true, version, url)); } } } } catch (Exception e) { SimpleLogHelper.Warning(e); } return(new Tuple <bool, string, string>(false, "", url)); }
/// <summary> /// Check if db is existed and writable /// </summary> /// <returns> /// Tuple(is decrypted, error info) /// </returns> private static Tuple <bool, string> CheckIfDbIsWritable() { var path = SystemConfig.Instance.DataSecurity.DbPath; try { var fi = new FileInfo(SystemConfig.Instance.DataSecurity.DbPath); if (!Directory.Exists(fi.DirectoryName)) { Directory.CreateDirectory(fi.DirectoryName); } if (IOPermissionHelper.HasWritePermissionOnFile(path)) { Server.Init(); return(new Tuple <bool, string>(true, "")); } else { return(new Tuple <bool, string>(false, "TXT:db permission denied:" + " " + path)); } } catch (Exception e) { SimpleLogHelper.Error(e); SimpleLogHelper.Error(e.StackTrace); return(new Tuple <bool, string>(false, e.Message)); } }
public void ShowMe() { SimpleLogHelper.Debug("Call shortcut to invoke quick window."); _vmSearchBox.DispNameFilter = ""; if (SystemConfig.Instance.QuickConnect.Enable) { if (_isHidden == true) { lock (_closeLocker) { if (_isHidden == true) { var p = ScreenInfoEx.GetMouseSystemPosition(); var screenEx = ScreenInfoEx.GetCurrentScreenBySystemPosition(p); this.Top = screenEx.VirtualWorkingAreaCenter.Y - this.Height / 2; this.Left = screenEx.VirtualWorkingAreaCenter.X - this.Width / 2; this.Show(); this.Visibility = Visibility.Visible; this.Activate(); this.Topmost = true; // important this.Topmost = false; // important this.Focus(); // important TbKeyWord.Focus(); _isHidden = false; _vmSearchBox.PopupSelectionsIsOpen = false; _vmSearchBox.PopupActionsIsOpen = false; } } } } }
/// <summary> /// use it after Show() has been called /// </summary> public void SetHotKey() { GlobalHotkeyHooker.Instance.Unregist(this); var r = GlobalHotkeyHooker.Instance.Regist(this, SystemConfig.Instance.QuickConnect.HotKeyModifiers, SystemConfig.Instance.QuickConnect.HotKeyKey, this.ShowMe); var title = SystemConfig.Instance.Language.GetText("messagebox_title_warning"); switch (r.Item1) { case GlobalHotkeyHooker.RetCode.Success: break; case GlobalHotkeyHooker.RetCode.ERROR_HOTKEY_NOT_REGISTERED: { var msg = $"{SystemConfig.Instance.Language.GetText("info_hotkey_registered_fail")}: {r.Item2}"; SimpleLogHelper.Warning(msg); MessageBox.Show(msg, title); break; } case GlobalHotkeyHooker.RetCode.ERROR_HOTKEY_ALREADY_REGISTERED: { var msg = $"{SystemConfig.Instance.Language.GetText("info_hotkey_already_registered")}: {r.Item2}"; SimpleLogHelper.Warning(msg); MessageBox.Show(msg, title); break; } default: throw new ArgumentOutOfRangeException(); } }
private void RdpcOnDisconnected(object sender, IMsTscAxEvents_OnDisconnectedEvent e) { _isDisconned = true; ResizeEndStopFireDelegate(); if (this._onResizeEnd != null) { this._onResizeEnd -= ReSizeRdp; } const int UI_ERR_NORMAL_DISCONNECT = 0xb08; string reason = _rdp.GetErrorDescription((uint)e.discReason, (uint)_rdp.ExtendedDisconnectReason); if (e.discReason != UI_ERR_NORMAL_DISCONNECT) { SimpleLogHelper.Warning($"RDP({_rdpServer.DispName}) exit with error code {e.discReason}({reason})"); } if (e.discReason != UI_ERR_NORMAL_DISCONNECT && e.discReason != (int)EDiscReason.exDiscReasonAPIInitiatedDisconnect && e.discReason != (int)EDiscReason.exDiscReasonAPIInitiatedLogoff && reason != "") { string disconnectedText = $"{_rdpServer.DispName}({_rdpServer.Address}) : {reason}"; var t = new Task(() => { System.Windows.MessageBox.Show(disconnectedText, SystemConfig.Instance.Language.GetText("messagebox_title_info"), MessageBoxButton.OK, MessageBoxImage.Warning); }); t.Start(); } base.OnClosed?.Invoke(base.ConnectionId); }
public static void SetExtendedProperty(this AxHost axHost, string propertyName, object value) { try { ((IMsRdpExtendedSettings)axHost.GetOcx()).set_Property(propertyName, ref value); } catch (Exception ex) { SimpleLogHelper.Error(ex, ex.StackTrace); } }
public void ClosePutty() { DelPuttySessionInRegTable(); try { if (_puttyProcess?.HasExited == false) { _puttyProcess?.Kill(); } _puttyProcess = null; } catch (Exception e) { SimpleLogHelper.Error(e); } }
public void ShowRemoteHost(uint serverId) { Debug.Assert(serverId > 0); Debug.Assert(GlobalData.Instance.ServerList.Any(x => x.Id == serverId)); var server = GlobalData.Instance.ServerList.First(x => x.Id == serverId); // update last conn time server.LastConnTime = DateTime.Now; Server.AddOrUpdate(server); // is connected now! activate it then return. if (server.OnlyOneInstance && _protocolHosts.ContainsKey(serverId.ToString())) { if (_protocolHosts[serverId.ToString()].ParentWindow is TabWindow t) { var s = t.Vm?.Items?.First(x => x.Content?.ProtocolServer?.Id == serverId); if (s != null) { t.Vm.SelectedItem = s; } t.Activate(); } return; } // create new remote session TabWindow tab = null; try { if (server.IsConnWithFullScreen()) { // for those people using 2+ monitors in different scale factors, we will try "mstsc.exe" instead of "PRemoteM". if (Screen.AllScreens.Length > 1 && server is ProtocolServerRDP rdp && rdp.RdpFullScreenFlag == ERdpFullScreenFlag.EnableFullAllScreens) { int factor = (int)(new ScreenInfoEx(Screen.PrimaryScreen).ScaleFactor * 100); // check if screens are in different scale factors bool differentScaleFactorFlag = Screen.AllScreens.Select(screen => (int)(new ScreenInfoEx(screen).ScaleFactor * 100)).Any(factor2 => factor != factor2); if (differentScaleFactorFlag || true) { var tmp = Path.GetTempPath(); var rdpFileName = $"{rdp.DispName}_{rdp.Port}_{rdp.UserName}"; var invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); rdpFileName = invalid.Aggregate(rdpFileName, (current, c) => current.Replace(c.ToString(), "")); var rdpFile = Path.Combine(tmp, rdpFileName + ".rdp"); try { File.WriteAllText(rdpFile, rdp.ToRdpConfig().ToString()); var p = new Process { StartInfo = { FileName = "cmd.exe", UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true } }; p.Start(); p.StandardInput.WriteLine("mstsc -admin \"" + rdpFile + "\""); p.StandardInput.WriteLine("exit"); } finally { // delete tmp rdp file, ETA 10s var t = new Task(() => { Thread.Sleep(1000 * 10); if (File.Exists(rdpFile)) { File.Delete(rdpFile); } }); t.Start(); } return; } } var host = ProtocolHostFactory.Get(server); host.OnClosed += OnProtocolClose; host.OnFullScreen2Window += OnFullScreen2Window; AddProtocolHost(host); MoveProtocolHostToFullScreen(host.ConnectionId); host.Conn(); SimpleLogHelper.Debug($@"Start Conn: {server.DispName}({server.GetHashCode()}) by host({host.GetHashCode()}) with full"); } else { switch (SystemConfig.Instance.General.TabMode) { case EnumTabMode.NewItemGoesToGroup: // work in tab by group mode if (_tabWindows.Any(x => x.Value.Vm.Tag == server.GroupName)) { tab = _tabWindows.First(x => x.Value.Vm.Tag == server.GroupName).Value; } break; case EnumTabMode.NewItemGoesToProtocol: // work in tab by protocol mode if (_tabWindows.Any(x => x.Value.Vm.Tag == server.ProtocolDisplayName)) { tab = _tabWindows.First(x => x.Value.Vm.Tag == server.ProtocolDisplayName).Value; } break; default: // work in tab by latest tab mode if (!string.IsNullOrEmpty(_lastTabToken) && _tabWindows.ContainsKey(_lastTabToken)) { tab = _tabWindows[_lastTabToken]; } break; } if (tab == null) { var token = DateTime.Now.Ticks.ToString(); AddTab(new TabWindow(token)); tab = _tabWindows[token]; tab.Show(); _lastTabToken = token; if (SystemConfig.Instance.General.TabMode == EnumTabMode.NewItemGoesToGroup) { tab.Vm.Tag = server.GroupName; } else if (SystemConfig.Instance.General.TabMode == EnumTabMode.NewItemGoesToProtocol) { tab.Vm.Tag = server.ProtocolDisplayName; } } tab.Activate(); var size = tab.GetTabContentSize(); var host = ProtocolHostFactory.Get(server, size.Width, size.Height); host.OnClosed += OnProtocolClose; host.OnFullScreen2Window += OnFullScreen2Window; host.ParentWindow = tab; tab.Vm.Items.Add(new TabItemViewModel() { Content = host, Header = server.DispName, }); tab.Vm.SelectedItem = tab.Vm.Items.Last(); host.Conn(); _protocolHosts.Add(host.ConnectionId, host); SimpleLogHelper.Debug($@"Start Conn: {server.DispName}({server.GetHashCode()}) by host({host.GetHashCode()}) with Tab({tab.GetHashCode()})"); SimpleLogHelper.Debug($@"ProtocolHosts.Count = {_protocolHosts.Count}, FullWin.Count = {_host2FullScreenWindows.Count}, _tabWindows.Count = {_tabWindows.Count}"); } } catch (Exception e) { CloseEmpytTab(); SimpleLogHelper.Error(e); MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
public void MoveProtocolHostToFullScreen(string connectionId) { if (_protocolHosts.ContainsKey(connectionId)) { var host = _protocolHosts[connectionId]; // remove from old parent TabWindow tab = null; { var tabs = _tabWindows.Values.Where(x => x.Vm.Items.Any(y => y.Content == host)).ToArray(); if (tabs.Length > 0) { tab = tabs.First(); foreach (var t in tabs) { var items = t.Vm.Items.ToArray().Where(x => x.Content == host); foreach (var item in items.ToArray()) { t.Vm.Items.Remove(item); if (t.Vm.Items.Count > 0) { t.Vm.SelectedItem = tab.Vm.Items.First(); } SimpleLogHelper.Debug($@"Remove host({host.GetHashCode()}) from tab({t.GetHashCode()})"); } } } } FullScreenWindow full; if (_host2FullScreenWindows.ContainsKey(connectionId)) { full = _host2FullScreenWindows[connectionId]; full.LastTabToken = ""; // full screen placement if (tab != null) { var screenEx = ScreenInfoEx.GetCurrentScreen(tab); full.Top = screenEx.VirtualWorkingAreaCenter.Y - full.Height / 2; full.Left = screenEx.VirtualWorkingAreaCenter.X - full.Width / 2; full.LastTabToken = _lastTabToken; } full.Show(); full.SetProtocolHost(host); host.ParentWindow = full; host.GoFullScreen(); } else { // move to full full = new FullScreenWindow { LastTabToken = "" }; // full screen placement ScreenInfoEx screenEx; if (tab != null) { screenEx = ScreenInfoEx.GetCurrentScreen(tab); full.LastTabToken = _lastTabToken; } else if (host.ProtocolServer is ProtocolServerRDP rdp && rdp.RdpFullScreenFlag == ERdpFullScreenFlag.EnableFullScreen && rdp.AutoSetting.FullScreenLastSessionScreenIndex >= 0 && rdp.AutoSetting.FullScreenLastSessionScreenIndex < Screen.AllScreens.Length) { screenEx = ScreenInfoEx.GetCurrentScreen(rdp.AutoSetting.FullScreenLastSessionScreenIndex); } else { screenEx = ScreenInfoEx.GetCurrentScreen(App.Window); } full.WindowStartupLocation = WindowStartupLocation.Manual; full.Top = screenEx.VirtualWorkingAreaCenter.Y - full.Height / 2; full.Left = screenEx.VirtualWorkingAreaCenter.X - full.Width / 2; full.SetProtocolHost(host); host.ParentWindow = full; full.Loaded += (sender, args) => { host.GoFullScreen(); }; full.Show(); AddFull(full); }
/// <summary> /// Check if db is(can) decrypted by the private key /// </summary> /// <returns> /// Tuple(is decrypted, error info) /// </returns> public Tuple <bool, string> CheckIfDbIsOk(string privateKeyPath = "") { var c1 = CheckIfDbIsWritable(); if (!c1.Item1) { return(c1); } var _privateKeyPath = DB.Config.RSA_PrivateKeyPath; if (!string.IsNullOrEmpty(privateKeyPath)) { _privateKeyPath = privateKeyPath; } // NO RSA if (string.IsNullOrEmpty(DB.Config.RSA_PublicKey) && string.IsNullOrEmpty(_privateKeyPath) && string.IsNullOrEmpty(DB.Config.RSA_SHA1)) { return(new Tuple <bool, string>(true, "")); } if (!File.Exists(_privateKeyPath)) { return(new Tuple <bool, string>(false, SystemConfig.Instance.Language.GetText("system_options_data_security_error_rsa_private_key_not_found"))); } RSA rsaPk = null; RSA rsaPpk = null; try { rsaPpk = new RSA(File.ReadAllText(_privateKeyPath), true); } catch (Exception) { return(new Tuple <bool, string>(false, SystemConfig.Instance.Language.GetText("system_options_data_security_error_rsa_private_key_not_match"))); } // make sure public key is PEM format key try { rsaPk = new RSA(DB.Config.RSA_PublicKey, true); } catch (Exception) { // try to fix public key if (rsaPpk.Verify("SHA1", DB.Config.RSA_SHA1, SystemConfig.AppName)) { DB.Config.RSA_PublicKey = rsaPpk.ToPEM_PKCS1(true); rsaPk = new RSA(File.ReadAllText(_privateKeyPath), true); } } // RSA private key is match public key? try { rsaPpk = new RSA(File.ReadAllText(_privateKeyPath), true); var sha1 = rsaPpk.Sign("SHA1", SystemConfig.AppName); if (!rsaPk.Verify("SHA1", sha1, SystemConfig.AppName)) { throw new Exception("RSA key is not match!"); } DB.Config.RSA_SHA1 = sha1; } catch (Exception e) { SimpleLogHelper.Error(e); return(new Tuple <bool, string>(false, SystemConfig.Instance.Language.GetText("system_options_data_security_error_rsa_private_key_not_match"))); } return(new Tuple <bool, string>(true, "")); }
private void RegPuttySessionInRegTable() { // set key if (_protocolPuttyBase is ProtocolServerSSH server && !string.IsNullOrEmpty(server.PrivateKey)) { var ppk = server.PrivateKey; if (SystemConfig.Instance.DataSecurity.Rsa != null) { ppk = SystemConfig.Instance.DataSecurity.Rsa.DecodeOrNull(ppk); } Debug.Assert(ppk != null); _puttyOption.Set(PuttyRegOptionKey.PublicKeyFile, ppk); } // set color theme _puttyOption.Set(PuttyRegOptionKey.FontHeight, SystemConfig.Instance.Theme.PuttyFontSize); var options = SystemConfig.Instance.Theme.SelectedPuttyTheme; if (options != null) { foreach (var option in options) { try { if (Enum.TryParse(option.Key, out PuttyRegOptionKey key)) { if (option.ValueKind == RegistryValueKind.DWord) { _puttyOption.Set(key, (int)(option.Value)); } else { _puttyOption.Set(key, (string)option.Value); } } } catch (Exception) { SimpleLogHelper.Warning($"Putty theme error: can't set up key(value)=> {option.Key}({option.ValueKind})"); } } } //_puttyOption.Set(PuttyRegOptionKey.Colour0, "255,255,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour1, "255,255,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour2, "51,51,51"); //_puttyOption.Set(PuttyRegOptionKey.Colour3, "85,85,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour4, "0,0,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour5, "0,255,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour6, "77,77,77"); //_puttyOption.Set(PuttyRegOptionKey.Colour7, "85,85,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour8, "187,0,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour9, "255,85,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour10, "152,251,152"); //_puttyOption.Set(PuttyRegOptionKey.Colour11, "85,255,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour12, "240,230,140"); //_puttyOption.Set(PuttyRegOptionKey.Colour13, "255,255,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour14, "205,133,63"); //_puttyOption.Set(PuttyRegOptionKey.Colour15, "135,206,235"); //_puttyOption.Set(PuttyRegOptionKey.Colour16, "255,222,173"); //_puttyOption.Set(PuttyRegOptionKey.Colour17, "255,85,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour18, "255,160,160"); //_puttyOption.Set(PuttyRegOptionKey.Colour19, "255,215,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour20, "245,222,179"); //_puttyOption.Set(PuttyRegOptionKey.Colour21, "255,255,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour0, "192,192,192"); //_puttyOption.Set(PuttyRegOptionKey.Colour1, "255,255,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour2, "0,0,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour3, "85,85,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour4, "0,0,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour5, "0,255,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour6, "0,0,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour7, "85,85,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour8, "255,0,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour9, "255,85,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour10,"0,255,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour11,"85,255,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour12,"187,187,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour13,"255,255,85"); //_puttyOption.Set(PuttyRegOptionKey.Colour14,"0,255,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour15,"0,0,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour16,"0,0,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour17,"255,85,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour18,"0,187,187"); //_puttyOption.Set(PuttyRegOptionKey.Colour19,"85,255,255"); //_puttyOption.Set(PuttyRegOptionKey.Colour20,"187,187,187"); //_puttyOption.Set(PuttyRegOptionKey.Colour21,"255,255,255"); //_puttyOption.Set(PuttyRegOptionKey.UseSystemColours, 0); //_puttyOption.Set(PuttyRegOptionKey.TryPalette, 0); //_puttyOption.Set(PuttyRegOptionKey.ANSIColour, 1); //_puttyOption.Set(PuttyRegOptionKey.Xterm256Colour, 1); //_puttyOption.Set(PuttyRegOptionKey.BoldAsColour, 1); //_puttyOption.Set(PuttyRegOptionKey.Colour0, "211,215,207"); //_puttyOption.Set(PuttyRegOptionKey.Colour1, "238,238,236"); //_puttyOption.Set(PuttyRegOptionKey.Colour2, "46,52,54"); //_puttyOption.Set(PuttyRegOptionKey.Colour3, "85,87,83"); //_puttyOption.Set(PuttyRegOptionKey.Colour4, "0,0,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour5, "0,255,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour6, "46,52,54"); //_puttyOption.Set(PuttyRegOptionKey.Colour7, "85,87,83"); //_puttyOption.Set(PuttyRegOptionKey.Colour8, "204,0,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour9, "239,41,41"); //_puttyOption.Set(PuttyRegOptionKey.Colour10,"78,154,6"); //_puttyOption.Set(PuttyRegOptionKey.Colour11,"138,226,52"); //_puttyOption.Set(PuttyRegOptionKey.Colour12,"196,160,0"); //_puttyOption.Set(PuttyRegOptionKey.Colour13,"252,233,79"); //_puttyOption.Set(PuttyRegOptionKey.Colour14,"52,101,164"); //_puttyOption.Set(PuttyRegOptionKey.Colour15,"114,159,207"); //_puttyOption.Set(PuttyRegOptionKey.Colour16,"117,80,123"); //_puttyOption.Set(PuttyRegOptionKey.Colour17,"173,127,168"); //_puttyOption.Set(PuttyRegOptionKey.Colour18,"6,152,154"); //_puttyOption.Set(PuttyRegOptionKey.Colour19,"52,226,226"); //_puttyOption.Set(PuttyRegOptionKey.Colour20,"211,215,207"); //_puttyOption.Set(PuttyRegOptionKey.Colour21,"238,238,236"); _puttyOption.Save(); }
private void App_OnStartup(object sender, StartupEventArgs startupEvent) { try { { var appDateFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), SystemConfig.AppName); if (!Directory.Exists(appDateFolder)) { Directory.CreateDirectory(appDateFolder); } var logFilePath = Path.Combine(appDateFolder, "PRemoteM.log.md"); SimpleLogHelper.LogFileName = logFilePath; } #region single-instance app var startupMode = PRM.Core.Ulits.StartupMode.Normal; if (startupEvent.Args.Length > 0) { System.Enum.TryParse(startupEvent.Args[0], out startupMode); } if (startupMode == PRM.Core.Ulits.StartupMode.SetSelfStart) { SetSelfStartingHelper.SetSelfStart(); Environment.Exit(0); } if (startupMode == PRM.Core.Ulits.StartupMode.UnsetSelfStart) { SetSelfStartingHelper.UnsetSelfStart(); Environment.Exit(0); } _singleAppMutex = new Mutex(true, PipeName, out var isFirst); if (!isFirst) { try { var client = new NamedPipeClientStream(PipeName); client.Connect(); StreamReader reader = new StreamReader(client); StreamWriter writer = new StreamWriter(client); writer.WriteLine("ActivateMe"); writer.Flush(); client.Dispose(); } catch (Exception e) { SimpleLogHelper.Warning(e); } Environment.Exit(0); } else { Task.Factory.StartNew(() => { NamedPipeServerStream server = null; while (true) { server?.Dispose(); server = new NamedPipeServerStream(PipeName); SimpleLogHelper.Debug("NamedPipeServerStream.WaitForConnection"); server.WaitForConnection(); try { var reader = new StreamReader(server); var line = reader.ReadLine(); if (!string.IsNullOrEmpty(line)) { SimpleLogHelper.Debug("NamedPipeServerStream get: " + line); if (line == "ActivateMe") { if (App.Window != null) { Dispatcher.Invoke(() => { if (App.Window.WindowState == WindowState.Minimized) { App.Window.WindowState = WindowState.Normal; } App.Window.ActivateMe(); }); } } } } catch (Exception e) { SimpleLogHelper.Warning(e); } } }); } #endregion #if DEBUG Shawn.Ulits.ConsoleManager.Show(); #endif #region system check & init #region Init { var appDateFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), SystemConfig.AppName); if (!Directory.Exists(appDateFolder)) { Directory.CreateDirectory(appDateFolder); } SimpleLogHelper.LogFileName = Path.Combine(appDateFolder, "PRemoteM.log.md"); var iniPath = Path.Combine(appDateFolder, SystemConfig.AppName + ".ini"); if (Environment.CurrentDirectory.IndexOf(@"C:\Windows") < 0) { if (File.Exists(SystemConfig.AppName + ".ini") || IOPermissionHelper.HasWritePermissionOnDir("./")) { iniPath = SystemConfig.AppName + ".ini"; } } var ini = new Ini(iniPath); //if (!File.Exists(iniPath)) //{ // // TODO if ini is not existed, then it would be a new user, open guide to set db path //} // Set default folder path SystemConfigLanguage.LanguageJsonDir = Path.Combine(appDateFolder, SystemConfigLanguage.LanguageJsonDir); PuttyColorThemes.ThemeRegFileFolder = Path.Combine(appDateFolder, PuttyColorThemes.ThemeRegFileFolder); var language = new SystemConfigLanguage(this.Resources, ini); var general = new SystemConfigGeneral(ini); var quickConnect = new SystemConfigQuickConnect(ini); var theme = new SystemConfigTheme(this.Resources, ini); var dataSecurity = new SystemConfigDataSecurity(ini); //if (!File.Exists(dataSecurity.DbPath)) //{ // // TODO db is not existed, then tell our user to create new one or select a new one. //} // config create instance (settings & langs) SystemConfig.Init(); SystemConfig.Instance.General = general; SystemConfig.Instance.Language = language; SystemConfig.Instance.QuickConnect = quickConnect; SystemConfig.Instance.DataSecurity = dataSecurity; SystemConfig.Instance.Theme = theme; // server data holder init. GlobalData.Init(); // remote window pool init. RemoteWindowPool.Init(); } #endregion // kill putty process foreach (var process in Process.GetProcessesByName(PuttyHost.PuttyExeName.ToLower().Replace(".exe", ""))) { try { process.Kill(); } catch { } } #endregion #region app start // main window init { Window = new MainWindow(); ShutdownMode = ShutdownMode.OnMainWindowClose; MainWindow = Window; Window.Closed += (o, args) => { AppOnClose(); }; if (!SystemConfig.Instance.General.AppStartMinimized) { ActivateWindow(); } // check if Db is ok var res = SystemConfig.Instance.DataSecurity.CheckIfDbIsOk(); if (!res.Item1) { SimpleLogHelper.Info("Start with 'SystemConfigPage' by 'ErroFlag'."); MessageBox.Show(res.Item2, SystemConfig.Instance.Language.GetText("messagebox_title_error")); ActivateWindow(); Window.VmMain.CmdGoSysOptionsPage.Execute(typeof(SystemConfigDataSecurity)); } else { // load data GlobalData.Instance.ServerListUpdate(); } } // task tray init InitTaskTray(); // quick search init InitQuickSearch(); #endregion } catch (Exception ex) { SimpleLogHelper.Fatal(ex.Message, ex.StackTrace); #if DEBUG MessageBox.Show(ex.Message); MessageBox.Show(ex.StackTrace); #endif AppOnClose(-1); } }
public void ShowRemoteHost(uint id) { Debug.Assert(id > 0); Debug.Assert(GlobalData.Instance.ServerList.Any(x => x.Id == id)); var server = GlobalData.Instance.ServerList.First(x => x.Id == id); // update last conn time server.LastConnTime = DateTime.Now; Server.AddOrUpdate(server); // start conn if (server.OnlyOneInstance && _protocolHosts.ContainsKey(id.ToString())) { _protocolHosts[id.ToString()].ParentWindow?.Activate(); return; } TabWindow tab = null; try { if (server.IsConnWithFullScreen()) { // for those people using 2+ monitor which are in different scale factors, we will try "mstsc.exe" instead of "PRemoteM". if (Screen.AllScreens.Length > 1 && server is ProtocolServerRDP rdp && rdp.RdpFullScreenFlag == ERdpFullScreenFlag.EnableFullAllScreens) { int factor = (int)(new ScreenInfoEx(Screen.PrimaryScreen).ScaleFactor * 100); // check if screens are in different scale factors bool differentScaleFactorFlag = Screen.AllScreens.Select(screen => (int)(new ScreenInfoEx(screen).ScaleFactor * 100)).Any(factor2 => factor != factor2); if (differentScaleFactorFlag) { var tmp = Path.GetTempPath(); var dp = rdp.DispName; var invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); dp = invalid.Aggregate(dp, (current, c) => current.Replace(c.ToString(), "")); var rdpFile = Path.Combine(tmp, dp + ".rdp"); try { File.WriteAllText(rdpFile, rdp.ToRdpConfig().ToString()); var p = new Process { StartInfo = { FileName = "cmd.exe", UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true } }; p.Start(); p.StandardInput.WriteLine("mstsc -admin " + rdpFile); p.StandardInput.WriteLine("exit"); } catch (Exception) { throw; } finally { var t = new Task(() => { Thread.Sleep(1000 * 10); if (File.Exists(rdpFile)) { File.Delete(rdpFile); } }); t.Start(); } return; } } var host = ProtocolHostFactory.Get(server); host.OnClosed += OnProtocolClose; host.OnFullScreen2Window += OnFullScreen2Window; AddProtocolHost(host); MoveProtocolHostToFullScreen(host.ConnectionId); host.Conn(); SimpleLogHelper.Debug($@"Start Conn: {server.DispName}({server.GetHashCode()}) by host({host.GetHashCode()}) with full"); } else { if (!string.IsNullOrEmpty(_lastTabToken) && _tabWindows.ContainsKey(_lastTabToken)) { tab = _tabWindows[_lastTabToken]; } else { var token = DateTime.Now.Ticks.ToString(); AddTab(new TabWindow(token)); tab = _tabWindows[token]; tab.Show(); _lastTabToken = token; } tab.Activate(); var size = tab.GetTabContentSize(); var host = ProtocolHostFactory.Get(server, size.Width, size.Height); host.OnClosed += OnProtocolClose; host.OnFullScreen2Window += OnFullScreen2Window; host.ParentWindow = tab; tab.Vm.Items.Add(new TabItemViewModel() { Content = host, Header = server.DispName, }); tab.Vm.SelectedItem = tab.Vm.Items.Last(); host.Conn(); _protocolHosts.Add(host.ConnectionId, host); SimpleLogHelper.Debug($@"Start Conn: {server.DispName}({server.GetHashCode()}) by host({host.GetHashCode()}) with Tab({tab.GetHashCode()})"); SimpleLogHelper.Debug($@"ProtocolHosts.Count = {_protocolHosts.Count}, FullWin.Count = {_host2FullScreenWindows.Count}, _tabWindows.Count = {_tabWindows.Count}"); } } catch (Exception e) { if (tab?.Vm != null && (tab.Vm?.Items?.Count ?? 0) == 0) { CloseTabWindow(tab.Vm.Token); } SimpleLogHelper.Error(e); MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
private void InitRdp(double width = 0, double height = 0) { _rdp.CreateControl(); #region server info // server info _rdp.Server = _rdpServer.Address; _rdp.UserName = _rdpServer.UserName; _rdp.AdvancedSettings2.RDPPort = _rdpServer.GetPort(); var secured = (MSTSCLib.IMsTscNonScriptable)_rdp.GetOcx(); secured.ClearTextPassword = _rdpServer.GetDecryptPassWord(); _rdp.FullScreenTitle = _rdpServer.DispName + " - " + _rdpServer.SubTitle; #endregion // enable CredSSP, will use CredSsp if the client supports. _rdp.AdvancedSettings7.EnableCredSspSupport = true; _rdp.AdvancedSettings2.EncryptionEnabled = 1; _rdp.AdvancedSettings5.AuthenticationLevel = 0; _rdp.AdvancedSettings5.EnableAutoReconnect = true; // setting PublicMode to false allows the saving of credentials, which prevents _rdp.AdvancedSettings6.PublicMode = false; _rdp.AdvancedSettings5.EnableWindowsKey = 1; _rdp.AdvancedSettings5.GrabFocusOnConnect = true; _rdp.AdvancedSettings2.keepAliveInterval = 1000 * 60 * 5; // 1000 = 1000 ms _rdp.AdvancedSettings2.overallConnectionTimeout = 600; // The new time, in seconds. The maximum value is 600, which represents 10 minutes. //// ref: https://docs.microsoft.com/en-us/windows/win32/termserv/imsrdpclientadvancedsettings6-connecttoadministerserver //_rdp.AdvancedSettings7.ConnectToAdministerServer = true; #region Others // enable CredSSP, will use CredSsp if the client supports. _rdp.AdvancedSettings9.EnableCredSspSupport = true; //- 0: If server authentication fails, connect to the computer without warning (Connect and don't warn me) //- 1: If server authentication fails, don't establish a connection (Don't connect) //- 2: If server authentication fails, show a warning and allow me to connect or refuse the connection (Warn me) //- 3: No authentication requirement specified. _rdp.AdvancedSettings9.AuthenticationLevel = 0; // setting PublicMode to false allows the saving of credentials, which prevents _rdp.AdvancedSettings9.PublicMode = false; _rdp.AdvancedSettings9.EnableAutoReconnect = true; // - 0 Apply key combinations only locally at the client computer. // - 1 Apply key combinations at the remote server. // - 2 Apply key combinations to the remote server only when the client is running in full-screen mode. This is the default value. _rdp.SecuredSettings3.KeyboardHookMode = 2; #endregion #region conn bar _rdp.AdvancedSettings6.DisplayConnectionBar = _rdpServer.IsFullScreenWithConnectionBar; _rdp.AdvancedSettings6.ConnectionBarShowPinButton = true; _rdp.AdvancedSettings6.PinConnectionBar = false; _rdp.AdvancedSettings6.ConnectionBarShowMinimizeButton = true; _rdp.AdvancedSettings6.ConnectionBarShowRestoreButton = true; _rdp.AdvancedSettings6.BitmapVirtualCache32BppSize = 48; #endregion #region Redirect _rdp.AdvancedSettings9.RedirectDrives = _rdpServer.EnableDiskDrives; _rdp.AdvancedSettings9.RedirectClipboard = _rdpServer.EnableClipboard; _rdp.AdvancedSettings9.RedirectPrinters = _rdpServer.EnablePrinters; _rdp.AdvancedSettings9.RedirectPOSDevices = _rdpServer.EnablePorts; _rdp.AdvancedSettings9.RedirectSmartCards = _rdpServer.EnableSmartCardsAndWinHello; if (_rdpServer.EnableKeyCombinations) { // - 0 Apply key combinations only locally at the client computer. // - 1 Apply key combinations at the remote server. // - 2 Apply key combinations to the remote server only when the client is running in full-screen mode. This is the default value. _rdp.SecuredSettings3.KeyboardHookMode = 1; } else { _rdp.SecuredSettings3.KeyboardHookMode = 0; } if (_rdpServer.EnableSounds) { // - 0 Redirect sounds to the client. This is the default value. // - 1 Play sounds at the remote computer. // - 2 Disable sound redirection; do not play sounds at the server. _rdp.SecuredSettings3.AudioRedirectionMode = 0; // - 0 (Audio redirection is enabled and the option for redirection is "Bring to this computer". This is the default mode.) // - 1 (Audio redirection is enabled and the option is "Leave at remote computer". The "Leave at remote computer" option is supported only when connecting remotely to a host computer that is running Windows Vista. If the connection is to a host computer that is running Windows Server 2008, the option "Leave at remote computer" is changed to "Do not play".) // - 2 (Audio redirection is enabled and the mode is "Do not play".) _rdp.AdvancedSettings6.AudioRedirectionMode = 0; // - 0 Dynamic audio quality. This is the default audio quality setting. The server dynamically adjusts audio output quality in response to network conditions and the client and server capabilities. // - 1 Medium audio quality. The server uses a fixed but compressed format for audio output. // - 2 High audio quality. The server provides audio output in uncompressed PCM format with lower processing overhead for latency. _rdp.AdvancedSettings8.AudioQualityMode = 0; } else { // - 2 Disable sound redirection; do not play sounds at the server. _rdp.SecuredSettings3.AudioRedirectionMode = 2; _rdp.AdvancedSettings6.AudioRedirectionMode = 2; } if (_rdpServer.EnableAudioCapture) { // indicates whether the default audio input device is redirected from the client to the remote session _rdp.AdvancedSettings8.AudioCaptureRedirectionMode = true; } else { _rdp.AdvancedSettings8.AudioCaptureRedirectionMode = false; } #endregion #region Display ReadScaleFactor(); _rdp.SetExtendedProperty("DesktopScaleFactor", _primaryScaleFactor); _rdp.SetExtendedProperty("DeviceScaleFactor", (uint)100); if (_rdpServer.RdpWindowResizeMode == ERdpWindowResizeMode.Stretch || _rdpServer.RdpWindowResizeMode == ERdpWindowResizeMode.StretchFullScreen) { _rdp.AdvancedSettings2.SmartSizing = true; } // to enhance user experience, i let the form handled full screen _rdp.AdvancedSettings6.ContainerHandledFullScreen = 1; if (_rdpServer.RdpFullScreenFlag != ERdpFullScreenFlag.EnableFullAllScreens) { switch (_rdpServer.RdpWindowResizeMode) { case ERdpWindowResizeMode.Stretch: case ERdpWindowResizeMode.Fixed: _rdp.DesktopWidth = (int)(_rdpServer.RdpWidth / (_primaryScaleFactor / 100.0)); _rdp.DesktopHeight = (int)(_rdpServer.RdpHeight / (_primaryScaleFactor / 100.0)); break; case ERdpWindowResizeMode.StretchFullScreen: case ERdpWindowResizeMode.FixedFullScreen: var screenSize = GetScreenSize(); _rdp.DesktopWidth = (int)(screenSize.Width); _rdp.DesktopHeight = (int)(screenSize.Height); break; case ERdpWindowResizeMode.AutoResize: default: if (width > 100 && height > 100) { _rdp.DesktopWidth = (int)(width * (_primaryScaleFactor / 100.0)); _rdp.DesktopHeight = (int)(height * (_primaryScaleFactor / 100.0)); } else { _rdp.DesktopWidth = (int)(800 * (_primaryScaleFactor / 100.0)); _rdp.DesktopHeight = (int)(600 * (_primaryScaleFactor / 100.0)); } break; } } switch (_rdpServer.RdpFullScreenFlag) { case ERdpFullScreenFlag.Disable: base.CanFullScreen = false; break; case ERdpFullScreenFlag.EnableFullScreen: base.CanFullScreen = true; if (_rdpServer.IsConnWithFullScreen || (_rdpServer.AutoSetting?.FullScreenLastSessionIsFullScreen ?? false)) { var screenSize = GetScreenSize(); _rdp.DesktopWidth = (int)(screenSize.Width); _rdp.DesktopHeight = (int)(screenSize.Height); _rdp.FullScreen = true; } break; case ERdpFullScreenFlag.EnableFullAllScreens: base.CanFullScreen = true; if (Screen.AllScreens.Length == 1) { var screenSize = GetScreenSize(); _rdp.DesktopWidth = (int)(screenSize.Width); _rdp.DesktopHeight = (int)(screenSize.Height); } ((IMsRdpClientNonScriptable5)_rdp.GetOcx()).UseMultimon = true; break; default: throw new ArgumentOutOfRangeException(); } #endregion #region Performance // ref: https://docs.microsoft.com/en-us/windows/win32/termserv/imsrdpclientadvancedsettings-performanceflags int nDisplayPerformanceFlag = 0; if (_rdpServer.DisplayPerformance != EDisplayPerformance.Auto) { _rdp.AdvancedSettings9.BandwidthDetection = false; // ref: https://docs.microsoft.com/en-us/windows/win32/termserv/imsrdpclientadvancedsettings7-networkconnectiontype // CONNECTION_TYPE_MODEM (1 (0x1)) Modem (56 Kbps) // CONNECTION_TYPE_BROADBAND_LOW (2 (0x2)) Low-speed broadband (256 Kbps to 2 Mbps) CONNECTION_TYPE_SATELLITE (3 (0x3)) Satellite (2 Mbps to 16 Mbps, with high latency) // CONNECTION_TYPE_BROADBAND_HIGH (4 (0x4)) High-speed broadband (2 Mbps to 10 Mbps) CONNECTION_TYPE_WAN (5 (0x5)) Wide area network (WAN) (10 Mbps or higher, with high latency) // CONNECTION_TYPE_LAN (6 (0x6)) Local area network (LAN) (10 Mbps or higher) _rdp.AdvancedSettings8.NetworkConnectionType = 1; switch (_rdpServer.DisplayPerformance) { case EDisplayPerformance.Auto: break; case EDisplayPerformance.Low: // 8,16,24,32 _rdp.ColorDepth = 8; nDisplayPerformanceFlag += 0x00000001; //TS_PERF_DISABLE_WALLPAPER; Wallpaper on the desktop is not displayed. nDisplayPerformanceFlag += 0x00000002; //TS_PERF_DISABLE_FULLWINDOWDRAG; Full-window drag is disabled; only the window outline is displayed when the window is moved. nDisplayPerformanceFlag += 0x00000004; //TS_PERF_DISABLE_MENUANIMATIONS; Menu animations are disabled. nDisplayPerformanceFlag += 0x00000008; //TS_PERF_DISABLE_THEMING ; Themes are disabled. nDisplayPerformanceFlag += 0x00000020; //TS_PERF_DISABLE_CURSOR_SHADOW; No shadow is displayed for the cursor. nDisplayPerformanceFlag += 0x00000040; //TS_PERF_DISABLE_CURSORSETTINGS; Cursor blinking is disabled. break; case EDisplayPerformance.Middle: _rdp.ColorDepth = 16; nDisplayPerformanceFlag += 0x00000001; //TS_PERF_DISABLE_WALLPAPER; Wallpaper on the desktop is not displayed. nDisplayPerformanceFlag += 0x00000002; //TS_PERF_DISABLE_FULLWINDOWDRAG; Full-window drag is disabled; only the window outline is displayed when the window is moved. nDisplayPerformanceFlag += 0x00000004; //TS_PERF_DISABLE_MENUANIMATIONS; Menu animations are disabled. nDisplayPerformanceFlag += 0x00000008; //TS_PERF_DISABLE_THEMING ; Themes are disabled. nDisplayPerformanceFlag += 0x00000020; //TS_PERF_DISABLE_CURSOR_SHADOW; No shadow is displayed for the cursor. nDisplayPerformanceFlag += 0x00000040; //TS_PERF_DISABLE_CURSORSETTINGS; Cursor blinking is disabled. nDisplayPerformanceFlag += 0x00000080; //TS_PERF_ENABLE_FONT_SMOOTHING; Enable font smoothing. nDisplayPerformanceFlag += 0x00000100; //TS_PERF_ENABLE_DESKTOP_COMPOSITION ; Enable desktop composition. break; case EDisplayPerformance.High: _rdp.ColorDepth = 32; nDisplayPerformanceFlag += 0x00000080; //TS_PERF_ENABLE_FONT_SMOOTHING; Enable font smoothing. nDisplayPerformanceFlag += 0x00000100; //TS_PERF_ENABLE_DESKTOP_COMPOSITION ; Enable desktop composition. break; default: throw new ArgumentOutOfRangeException(); } } SimpleLogHelper.Debug("RdpInit: DisplayPerformance = " + _rdpServer.DisplayPerformance + ", flag = " + Convert.ToString(nDisplayPerformanceFlag, 2)); _rdp.AdvancedSettings9.PerformanceFlags = nDisplayPerformanceFlag; #endregion }