mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-18 14:39:32 +08:00
Compare commits
1 Commits
v1.77.2-pr
...
sharedlibr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
141b326a20 |
@@ -1,14 +0,0 @@
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: mRemoteNGDocumentation/conf.py
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF
|
||||
formats:
|
||||
- pdf
|
||||
34
CHANGELOG.md
34
CHANGELOG.md
@@ -5,57 +5,33 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- #2086: Replace WebClient with async HttpClient for updater.
|
||||
- #1850: Minify config xml
|
||||
- #1770: Added missing RDP performance settings
|
||||
- #1516: added API to access credential vault (Thycotic Secret Server) by specifying SSAPI:ID as username
|
||||
- #1476: Configurable backups. Can now edit/set backup frequency, backup path, and max number of backup files.
|
||||
- #1427: Fix RDP local desktop scale not taking effect on remote
|
||||
- #1770: Added missing RDP performance settings
|
||||
- #1332: Added option to hide menu strip container
|
||||
- #870: Added option to push inheritance settings to child nodes recursively
|
||||
- #545: Option to minimize to system tray on closing
|
||||
- #503: SSH Execute a single command after login
|
||||
- #420: SSH tunneling implemented
|
||||
- #327: Added Alternative Shell for RDP settings
|
||||
- #319: Override quick connect username when using user@domain
|
||||
- #283: Support for native PowerShell remoting as new protocol
|
||||
- #xxx: Add external connector to retrieve ip address from Amazon EC2 Instance IDs
|
||||
- #1850: Minify config xml
|
||||
### Changed
|
||||
- #2102: Extended the field RenderingEngine from 10 chars to 16
|
||||
- #2022: Replaced CefSharp with WebView2
|
||||
- #2014: Revised icons
|
||||
- #2013: Removed components check
|
||||
- #2011: Removed screenshot manager
|
||||
- #2010: Redesigned menus
|
||||
- #2005: Removed in-app documentation
|
||||
- #1777: Cleaned up VisualStudio project structure
|
||||
- #1767: Turned about window into a simple popup form
|
||||
- #1766: Converted components check page into options page
|
||||
- #1690: Replaced GeckoFX (Firefox) with CefSharp (Chromium)
|
||||
- #1325: Language resource files cleanup
|
||||
- #xxxx: Secret Server connector via new field "API User ID" instead of SSAPI: prefix
|
||||
### Fixed
|
||||
- #2098: Fix failed BinaryFileTest
|
||||
- #2097: Fix failed tests related to mRemoteNGTests.UI.Window.ConfigWindowTests
|
||||
- #2096: Corrected encryption code of LegacyRijndaelCryptographyProvider
|
||||
- #2089: Fixed the exception thrown by menu buttons "Documentation" and "Website"
|
||||
- #2087: Fixed application crash, when the update file is launched from the application
|
||||
- #2079: Fixed theme files not being copied to output directory
|
||||
- #2012: Updated PuTTYNG to v0.76
|
||||
- #1884: Allow setting Port when using MSSQL
|
||||
- #1783: Added missing inheritance properties to SQL scripts
|
||||
- #1773: Connection issue with MySql - Missing fields in
|
||||
- #1773: Connection issue with mysql - Missing fields in
|
||||
- #1756: Cannot type any character on MultiSSH toolbar
|
||||
- #1720: Show configuration file name in title of password prompt form
|
||||
- #1713: Sound redirection does not work if Clipboard redirection is set to No
|
||||
- #1632: 1.77.1 breaks RDP drive and sound redirection
|
||||
- #1610: Menu bar changes to English when canceling options form
|
||||
- #1610: Menu bar changes to english when cancelling options form
|
||||
- #1595: Unhandled exception when trying to browse through non existent multi ssh history with keyboard key strokes
|
||||
- #1589: Update SQL tables instead of rewriting them
|
||||
- #1465: REGRESSION: Smart Cards redirection to Remote Desktop not working
|
||||
- #1363: Don't show "Disk Usage" button in installer
|
||||
- #1337: Unhandled exception after closing mRemoteNG
|
||||
- #359: Making a VNC connection to an unreachable host causes the application to not respond for 20-30 seconds
|
||||
- #618: Do not break the Windows Clipboard Chain when exiting.
|
||||
|
||||
## [1.77.1] - 2019-09-02
|
||||
### Added
|
||||
|
||||
59
COPYING.TXT
59
COPYING.TXT
@@ -278,3 +278,62 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
127
CREDITS.md
Normal file
127
CREDITS.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# Contributors
|
||||
|
||||
## Current mRemoteNG dev team
|
||||
|
||||
[David Sparer](http://github.com/sparerd)
|
||||
[Sean Kaim](http://github.com/kmscode)
|
||||
[Faryan Rezagholi](http://github.com/farosch)
|
||||
[Bennett Blodinger](http://github.com/benwa)
|
||||
|
||||
[Joe Cefoli](http://github.com/jcefoli)
|
||||
[countchappy](http://github.com/countchappy)
|
||||
Tony Lambert
|
||||
[Julien Roncaglia](http://github.com/vbfox)
|
||||
[peterchenadded](http://github.com/peterchenadded)
|
||||
[Brandon Wulf](http://github.com/mrwulf)
|
||||
[Pedro Rodrigues](http://github.com/pedro2555)
|
||||
[dekelMP](http://github.com/dekelMP)
|
||||
[Bruce](http://github.com/brucetp)
|
||||
[Camilo Alvarez](http://github.com/jotatsu)
|
||||
[DamianBis](http://github.com/DamianBis)
|
||||
[pfjason](http://github.com/pfjason)
|
||||
[sirLoaf](http://github.com/sirLoaf)
|
||||
[Fyers](http://github.com/Fyers)
|
||||
[Vladimir Semenov](http://github.com/sli-pro)
|
||||
[Stephan](http://github.com/st-schuler)
|
||||
[Aleksey Reytsman](http://github.com/areytsman)
|
||||
[Cristian Abelleira](http://github.com/CrAbelleira)
|
||||
[MitchellBot](http://github.com/MitchellBot)
|
||||
[Filippo Ferrazini](http://github.com/Filippo125)
|
||||
|
||||
## Past Contributors
|
||||
|
||||
Felix Deimel - mRemote original developer
|
||||
Riley McArdle - mRemoteNG original developer
|
||||
|
||||
[Hayato Iriumi](http://github.com/hiriumi)
|
||||
Jason Barbier
|
||||
Wiktor Beryt
|
||||
Lionel Caignec
|
||||
Ruben d'Arco
|
||||
Holger Henke
|
||||
Tom Hiller
|
||||
Apisitt Rattana
|
||||
Andreas Rehm
|
||||
David Vidmar
|
||||
[Brandhor](http://github.com/Brandhor)
|
||||
[Dimitrij](http://github.com/Kvarkas)
|
||||
|
||||
## Translators
|
||||
|
||||
Eugenio "Ryo567" Martínez
|
||||
Mathieu Pape
|
||||
Emanuel Silva
|
||||
Robert Siwiec
|
||||
Hayato Iriumi
|
||||
[Sebastien Thieury](http://github.com/SebThieu)
|
||||
Riza Emet
|
||||
[Lukas Plachy](http://github.com/rheingold)
|
||||
Gyuha Shin
|
||||
[Stefan](http://github.com/polluks)
|
||||
[emazv72](http://github.com/emazv72)
|
||||
[Vladimir Semenov](http://github.com/sli-pro)
|
||||
[Marco Sousa](http://github.com/marcomsousa)
|
||||
[wwj402](http://github.com/wwj402)
|
||||
[Fyers](http://github.com/Fyers)
|
||||
[pablomh](http://github.com/pablomh)
|
||||
[Damian Szczepanik](http://github.com/damianszczepanik)
|
||||
[Mant1kor](http://github.com/Mant1kor)
|
||||
|
||||
# Included Source Code
|
||||
|
||||
**[Command Line Arguments Parser](http://www.codeproject.com/KB/recipes/command_line.aspx)**
|
||||
Copyright © 2002 Richard Lopes
|
||||
MIT License
|
||||
|
||||
**[FilteredPropertyGrid](http://www.codeproject.com/KB/cs/FilteredPropertyGrid.aspx)**
|
||||
Copyright © 2006 Azuria
|
||||
|
||||
**[InputBox](http://www.csharp-examples.net/inputbox/)**
|
||||
Copyright © 2016 Jan Slama
|
||||
|
||||
**[IP TextBox](http://www.codeproject.com/Articles/11576/IP-TextBox)**
|
||||
Copyright © 2005 mawnkay
|
||||
|
||||
**[PortableSettingsProvider](https://github.com/crdx/PortableSettingsProvider)**
|
||||
Copyright © 2014 crdx
|
||||
|
||||
**[ADTree](http://www.codeproject.com/KB/selection/ADPickerCtrl.aspx)**
|
||||
Copyright © 2004 Marc Merritt © 2008 Felix Deimel
|
||||
|
||||
# Included Components
|
||||
|
||||
**[CefSharp](https://github.com/cefsharp/CefSharp)**
|
||||
Copyright © The CefSharp Authors
|
||||
MIT License
|
||||
|
||||
**[DockPanel Suite](https://github.com/dockpanelsuite/dockpanelsuite)**
|
||||
Copyright © 2018 @roken and @lextm (formerly Weifen Luo)
|
||||
MIT License
|
||||
|
||||
**[log4net](http://logging.apache.org/log4net/)**
|
||||
Copyright © 2001-2015 The Apache Software Foundation
|
||||
Apache License Version 2.0
|
||||
|
||||
**[PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/)**
|
||||
Copyright © 1997-2017 Simon Tatham
|
||||
MIT License
|
||||
|
||||
**[Silk Icon Set](http://www.famfamfam.com/)**
|
||||
Copyright © 2005-2008 FAMFAMFAM
|
||||
Creative Commons Attribution 2.5 License
|
||||
|
||||
**[SSH.NET](https://github.com/sshnet/SSH.NET)**
|
||||
Copyright © 2016
|
||||
MIT License
|
||||
|
||||
**[VncSharp](https://github.com/humphd/VncSharp) (Archived)**
|
||||
Copyright © 2004-2009 David Humphrey
|
||||
GNU General Public License (GPL) Version 2
|
||||
|
||||
**[ObjectListView](https://sourceforge.net/projects/objectlistview/)**
|
||||
Copyright © 2006-2016 Phillip Piper
|
||||
GNU General Public License (GPL) Version 3
|
||||
|
||||
**[ConsoleControl](https://github.com/dwmkerr/consolecontrol)**
|
||||
Copyright © 2015 Dave Kerr
|
||||
MIT License
|
||||
180
ExternalConnectors/AWS/AWSConnectionForm.Designer.cs
generated
180
ExternalConnectors/AWS/AWSConnectionForm.Designer.cs
generated
@@ -1,180 +0,0 @@
|
||||
namespace ExternalConnectors.AWS
|
||||
{
|
||||
partial class AWSConnectionForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tbAccesKeyID = new System.Windows.Forms.TextBox();
|
||||
this.tbAccesKey = new System.Windows.Forms.TextBox();
|
||||
this.btnOK = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tbAccesKeyID
|
||||
//
|
||||
this.tbAccesKeyID.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tbAccesKeyID.Location = new System.Drawing.Point(152, 4);
|
||||
this.tbAccesKeyID.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.tbAccesKeyID.Name = "tbAccesKeyID";
|
||||
this.tbAccesKeyID.Size = new System.Drawing.Size(490, 23);
|
||||
this.tbAccesKeyID.TabIndex = 0;
|
||||
//
|
||||
// tbAccesKey
|
||||
//
|
||||
this.tbAccesKey.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tbAccesKey.Location = new System.Drawing.Point(152, 43);
|
||||
this.tbAccesKey.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.tbAccesKey.Name = "tbAccesKey";
|
||||
this.tbAccesKey.Size = new System.Drawing.Size(490, 23);
|
||||
this.tbAccesKey.TabIndex = 2;
|
||||
//
|
||||
// btnOK
|
||||
//
|
||||
this.btnOK.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.btnOK.Location = new System.Drawing.Point(219, 12);
|
||||
this.btnOK.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.btnOK.Name = "btnOK";
|
||||
this.btnOK.Size = new System.Drawing.Size(88, 26);
|
||||
this.btnOK.TabIndex = 10;
|
||||
this.btnOK.Text = "OK";
|
||||
this.btnOK.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(338, 12);
|
||||
this.btnCancel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(88, 26);
|
||||
this.btnCancel.TabIndex = 11;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 22.92994F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 77.07006F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tbAccesKeyID, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tbAccesKey, 1, 1);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(646, 102);
|
||||
this.tableLayoutPanel1.TabIndex = 12;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label1.Location = new System.Drawing.Point(4, 0);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(140, 39);
|
||||
this.label1.TabIndex = 2;
|
||||
this.label1.Text = "Access Key ID";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label2.Location = new System.Drawing.Point(4, 39);
|
||||
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(140, 39);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "Access Key";
|
||||
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 5;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 93F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 93F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.btnOK, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.btnCancel, 3, 0);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 112);
|
||||
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 1;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(646, 50);
|
||||
this.tableLayoutPanel2.TabIndex = 13;
|
||||
//
|
||||
// AWSConnectionForm
|
||||
//
|
||||
this.AcceptButton = this.btnOK;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(646, 162);
|
||||
this.Controls.Add(this.tableLayoutPanel2);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.Name = "AWSConnectionForm";
|
||||
this.Text = "AWS EC2 API Login Data";
|
||||
this.Activated += new System.EventHandler(this.AWSConnectionForm_Activated);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public System.Windows.Forms.TextBox tbAccesKeyID;
|
||||
public System.Windows.Forms.TextBox tbAccesKey;
|
||||
private System.Windows.Forms.Button btnOK;
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace ExternalConnectors.AWS
|
||||
{
|
||||
public partial class AWSConnectionForm : Form
|
||||
{
|
||||
public AWSConnectionForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
}
|
||||
|
||||
private void AWSConnectionForm_Activated(object sender, EventArgs e)
|
||||
{
|
||||
tbAccesKeyID.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -1,119 +0,0 @@
|
||||
using Amazon;
|
||||
using Amazon.EC2;
|
||||
using Amazon.EC2.Model;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace ExternalConnectors.AWS
|
||||
{
|
||||
public class EC2FetchDataService
|
||||
{
|
||||
private static DateTime lastFetch;
|
||||
private static List<InstanceInfo>? lastData;
|
||||
|
||||
// input must be in format "AWSAPI:instanceid" where instanceid is the ec2 instance id, e.g. i-066f750a76c97583d
|
||||
public static async Task<string> GetEC2InstanceDataAsync(string input, string region)
|
||||
{
|
||||
// get secret id
|
||||
if (!input.StartsWith("AWSAPI:"))
|
||||
throw new Exception("calling this function requires AWSAPI: input");
|
||||
string InstanceID = input[7..];
|
||||
|
||||
// init connection credentials, display popup if necessary
|
||||
AWSConnectionData.Init();
|
||||
var alldata = await GetEC2IPDataAsync(region);
|
||||
var found = alldata.Where(x => x.InstanceId == InstanceID).SingleOrDefault();
|
||||
return (found == null) ? "" : found.PublicIP;
|
||||
}
|
||||
|
||||
private static async Task<List<InstanceInfo>> GetEC2IPDataAsync(string region)
|
||||
{
|
||||
// caching
|
||||
TimeSpan timeSpan = DateTime.Now - lastFetch;
|
||||
if (timeSpan.TotalMinutes < 1 && lastData != null)
|
||||
return lastData;
|
||||
|
||||
//AWSConfigs.AWSRegion = AWSConnectionData.region;
|
||||
AWSConfigs.AWSRegion = region;
|
||||
string awsAccessKeyId = AWSConnectionData.awsKeyID;
|
||||
string awsSecretAccessKey = AWSConnectionData.awsKey;
|
||||
|
||||
var _client = new AmazonEC2Client(awsAccessKeyId, awsSecretAccessKey, RegionEndpoint.EUCentral1);
|
||||
bool done = false;
|
||||
|
||||
List<InstanceInfo> instanceList = new();
|
||||
var request = new DescribeInstancesRequest();
|
||||
while (!done)
|
||||
{
|
||||
DescribeInstancesResponse response = await _client.DescribeInstancesAsync(request);
|
||||
|
||||
foreach (var reservation in response.Reservations)
|
||||
{
|
||||
foreach (var instance in reservation.Instances)
|
||||
{
|
||||
string vmname = "";
|
||||
foreach (var tag in instance.Tags)
|
||||
{
|
||||
if (tag.Key == "Name")
|
||||
{
|
||||
vmname = tag.Value;
|
||||
}
|
||||
}
|
||||
InstanceInfo inf = new(instance, vmname);
|
||||
instanceList.Add(inf);
|
||||
}
|
||||
}
|
||||
|
||||
request.NextToken = response.NextToken;
|
||||
|
||||
if (response.NextToken == null)
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
lastData = instanceList.OrderBy(x => x.Name).ToList();
|
||||
lastFetch = DateTime.Now;
|
||||
return lastData;
|
||||
}
|
||||
|
||||
|
||||
public static class AWSConnectionData
|
||||
{
|
||||
private static readonly RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\mRemoteAWSInterface");
|
||||
|
||||
public static string awsKeyID = "";
|
||||
public static string awsKey = "";
|
||||
//public static string _region = "eu-central-1";
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (awsKey != "")
|
||||
return;
|
||||
// display gui and ask for data
|
||||
AWSConnectionForm f = new();
|
||||
f.tbAccesKeyID.Text = "" + key.GetValue("KeyID");
|
||||
f.tbAccesKey.Text = "" + key.GetValue("Key");
|
||||
//f.tbRegion.Text = "" + key.GetValue("Region");
|
||||
//if (f.tbRegion.Text == null || f.tbRegion.Text.Length < 2)
|
||||
// f.tbRegion.Text = region;
|
||||
_ = f.ShowDialog();
|
||||
|
||||
if (f.DialogResult != DialogResult.OK)
|
||||
return;
|
||||
|
||||
// store values to memory
|
||||
awsKeyID = f.tbAccesKeyID.Text;
|
||||
awsKey = f.tbAccesKey.Text;
|
||||
//region = f.tbRegion.Text;
|
||||
|
||||
|
||||
// write values to registry
|
||||
key.SetValue("KeyID", awsKeyID);
|
||||
key.SetValue("Key", awsKey);
|
||||
//key.SetValue("Region", region);
|
||||
key.Close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using Amazon.EC2.Model;
|
||||
using System;
|
||||
|
||||
namespace ExternalConnectors.AWS
|
||||
{
|
||||
public class InstanceInfo
|
||||
{
|
||||
public string InstanceId { get; }
|
||||
public string Name { get; }
|
||||
public string Status { get; }
|
||||
public string PublicIP { get; }
|
||||
public string PrivateIP { get; }
|
||||
public InstanceInfo(Instance instance, string name)
|
||||
{
|
||||
InstanceId = instance.InstanceId;
|
||||
Name = name;
|
||||
|
||||
switch(instance.State.Code)
|
||||
{
|
||||
case 0: Status = "Pending"; break;
|
||||
case 16: Status = "Running"; break;
|
||||
case 32: Status = "Shutdown"; break;
|
||||
case 48: Status = "Terminated"; break;
|
||||
case 64: Status = "Stopping"; break;
|
||||
case 80: Status = "Stopped"; break;
|
||||
default: Status = "Unknown"; break;
|
||||
};
|
||||
|
||||
PublicIP = instance.PublicIpAddress ?? "";
|
||||
PrivateIP = instance.PrivateIpAddress ?? "";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
<UseWindowsForms>True</UseWindowsForms>
|
||||
<Platforms>x64</Platforms>
|
||||
<Configurations>Debug;Release;Debug Portable;Release Portable</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AWSSDK.Core" Version="3.7.5.13" />
|
||||
<PackageReference Include="AWSSDK.EC2" Version="3.7.54" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="AWS\AWSConnectionForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="TSS\SSConnectionForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
256
ExternalConnectors/TSS/SSConnectionForm.Designer.cs
generated
256
ExternalConnectors/TSS/SSConnectionForm.Designer.cs
generated
@@ -1,256 +0,0 @@
|
||||
namespace ExternalConnectors.TSS
|
||||
{
|
||||
partial class SSConnectionForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tbSSURL = new System.Windows.Forms.TextBox();
|
||||
this.tbUsername = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.tbPassword = new System.Windows.Forms.TextBox();
|
||||
this.btnOK = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.cbUseSSO = new System.Windows.Forms.CheckBox();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tbSSURL
|
||||
//
|
||||
this.tbSSURL.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tbSSURL.Location = new System.Drawing.Point(260, 4);
|
||||
this.tbSSURL.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.tbSSURL.Name = "tbSSURL";
|
||||
this.tbSSURL.Size = new System.Drawing.Size(536, 23);
|
||||
this.tbSSURL.TabIndex = 0;
|
||||
//
|
||||
// tbUsername
|
||||
//
|
||||
this.tbUsername.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tbUsername.Location = new System.Drawing.Point(260, 35);
|
||||
this.tbUsername.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.tbUsername.Name = "tbUsername";
|
||||
this.tbUsername.Size = new System.Drawing.Size(536, 23);
|
||||
this.tbUsername.TabIndex = 2;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label3.Location = new System.Drawing.Point(4, 62);
|
||||
this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(248, 23);
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Password";
|
||||
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// tbPassword
|
||||
//
|
||||
this.tbPassword.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tbPassword.Location = new System.Drawing.Point(260, 66);
|
||||
this.tbPassword.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.tbPassword.Name = "tbPassword";
|
||||
this.tbPassword.Size = new System.Drawing.Size(536, 23);
|
||||
this.tbPassword.TabIndex = 4;
|
||||
this.tbPassword.UseSystemPasswordChar = true;
|
||||
//
|
||||
// btnOK
|
||||
//
|
||||
this.btnOK.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.btnOK.Location = new System.Drawing.Point(296, 12);
|
||||
this.btnOK.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.btnOK.Name = "btnOK";
|
||||
this.btnOK.Size = new System.Drawing.Size(88, 26);
|
||||
this.btnOK.TabIndex = 10;
|
||||
this.btnOK.Text = "OK";
|
||||
this.btnOK.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(415, 12);
|
||||
this.btnCancel.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(88, 26);
|
||||
this.btnCancel.TabIndex = 11;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 32.06997F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67.93003F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tbSSURL, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tbUsername, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tbPassword, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.cbUseSSO, 0, 3);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 4;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(800, 108);
|
||||
this.tableLayoutPanel1.TabIndex = 12;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label5.Location = new System.Drawing.Point(260, 85);
|
||||
this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(536, 23);
|
||||
this.label5.TabIndex = 15;
|
||||
this.label5.Text = "For SSO to work, additional IIS configuration is required!";
|
||||
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label1.Location = new System.Drawing.Point(4, 0);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(248, 31);
|
||||
this.label1.TabIndex = 2;
|
||||
this.label1.Text = "Secret Server URL";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label2.Location = new System.Drawing.Point(4, 31);
|
||||
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(248, 31);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "DOMAIN\\Username";
|
||||
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// cbUseSSO
|
||||
//
|
||||
this.cbUseSSO.AutoSize = true;
|
||||
this.cbUseSSO.Location = new System.Drawing.Point(4, 89);
|
||||
this.cbUseSSO.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0);
|
||||
this.cbUseSSO.Name = "cbUseSSO";
|
||||
this.cbUseSSO.Size = new System.Drawing.Size(69, 19);
|
||||
this.cbUseSSO.TabIndex = 14;
|
||||
this.cbUseSSO.Text = "Use SSO";
|
||||
this.cbUseSSO.UseVisualStyleBackColor = true;
|
||||
this.cbUseSSO.CheckedChanged += new System.EventHandler(this.cbUseSSO_CheckedChanged);
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 5;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 93F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 23F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 93F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.btnOK, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.btnCancel, 3, 0);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 148);
|
||||
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 1;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(800, 50);
|
||||
this.tableLayoutPanel2.TabIndex = 13;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label4.Location = new System.Drawing.Point(0, 108);
|
||||
this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(341, 15);
|
||||
this.label4.TabIndex = 14;
|
||||
this.label4.Text = "URL is the base URL, like https://cred.domain.local/SecretServer";
|
||||
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// SSConnectionForm
|
||||
//
|
||||
this.AcceptButton = this.btnOK;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(800, 198);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.tableLayoutPanel2);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.Name = "SSConnectionForm";
|
||||
this.Text = "Secret Server API Login Data";
|
||||
this.Activated += new System.EventHandler(this.SSConnectionForm_Activated);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.Label label3;
|
||||
|
||||
public System.Windows.Forms.TextBox tbSSURL;
|
||||
public System.Windows.Forms.TextBox tbUsername;
|
||||
public System.Windows.Forms.TextBox tbPassword;
|
||||
private System.Windows.Forms.Button btnOK;
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
public System.Windows.Forms.CheckBox cbUseSSO;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private Label label5;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
namespace ExternalConnectors.TSS
|
||||
{
|
||||
public partial class SSConnectionForm : Form
|
||||
{
|
||||
public SSConnectionForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void SSConnectionForm_Activated(object sender, EventArgs e)
|
||||
{
|
||||
SetVisibility();
|
||||
if (cbUseSSO.Checked)
|
||||
btnOK.Focus();
|
||||
else
|
||||
tbPassword.Focus();
|
||||
}
|
||||
|
||||
private void cbUseSSO_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
SetVisibility();
|
||||
}
|
||||
private void SetVisibility()
|
||||
{
|
||||
bool ch = cbUseSSO.Checked;
|
||||
tbPassword.Enabled = !ch;
|
||||
tbUsername.Enabled = !ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -1,364 +0,0 @@
|
||||
//----------------------
|
||||
// <auto-generated>
|
||||
// Generated using the NSwag toolchain v13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
|
||||
// </auto-generated>
|
||||
//----------------------
|
||||
|
||||
#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
|
||||
#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
|
||||
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
|
||||
#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
|
||||
#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."
|
||||
#pragma warning disable 8073 // Disable "CS8073 The result of the expression is always 'false' since a value of type 'T' is never equal to 'null' of type 'T?'"
|
||||
#pragma warning disable 3016 // Disable "CS3016 Arrays as attribute arguments is not CLS-compliant"
|
||||
|
||||
namespace SecretServerAuthentication.TSS
|
||||
{
|
||||
using System = global::System;
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))")]
|
||||
public partial class OAuth2ServiceClient
|
||||
{
|
||||
private string _baseUrl = "";
|
||||
private System.Net.Http.HttpClient _httpClient;
|
||||
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
|
||||
|
||||
public OAuth2ServiceClient(string baseUrl, System.Net.Http.HttpClient httpClient)
|
||||
{
|
||||
BaseUrl = baseUrl;
|
||||
_httpClient = httpClient;
|
||||
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
|
||||
}
|
||||
|
||||
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
|
||||
{
|
||||
var settings = new Newtonsoft.Json.JsonSerializerSettings();
|
||||
UpdateJsonSerializerSettings(settings);
|
||||
return settings;
|
||||
}
|
||||
|
||||
public string BaseUrl
|
||||
{
|
||||
get { return _baseUrl; }
|
||||
set { _baseUrl = value; }
|
||||
}
|
||||
|
||||
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
|
||||
|
||||
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
|
||||
|
||||
|
||||
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
|
||||
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
|
||||
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
|
||||
/// <summary>Retrieve or Refresh Access Token</summary>
|
||||
/// <param name="grant_type">Authentication grant type. Use 'password' when authenticating, and 'refresh_token' when refreshing a token.</param>
|
||||
/// <param name="username">Secret Server authentication username. Required when authenticating.</param>
|
||||
/// <param name="password">Secret Server authentication password. Required when authenticating.</param>
|
||||
/// <param name="refresh_token">The refresh token. Required when refreshing a token.</param>
|
||||
/// <returns>Successful retrieval of an access token</returns>
|
||||
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||
public System.Threading.Tasks.Task<TokenResponse> AuthorizeAsync(Grant_type grant_type, string username, string password, string refresh_token)
|
||||
{
|
||||
return AuthorizeAsync(grant_type, username, password, refresh_token, System.Threading.CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
|
||||
/// <summary>Retrieve or Refresh Access Token</summary>
|
||||
/// <param name="grant_type">Authentication grant type. Use 'password' when authenticating, and 'refresh_token' when refreshing a token.</param>
|
||||
/// <param name="username">Secret Server authentication username. Required when authenticating.</param>
|
||||
/// <param name="password">Secret Server authentication password. Required when authenticating.</param>
|
||||
/// <param name="refresh_token">The refresh token. Required when refreshing a token.</param>
|
||||
/// <returns>Successful retrieval of an access token</returns>
|
||||
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||
public async System.Threading.Tasks.Task<TokenResponse> AuthorizeAsync(Grant_type grant_type, string username, string password, string refresh_token, System.Threading.CancellationToken cancellationToken)
|
||||
{
|
||||
var urlBuilder_ = new System.Text.StringBuilder();
|
||||
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/oauth2/token");
|
||||
|
||||
var client_ = _httpClient;
|
||||
var disposeClient_ = false;
|
||||
try
|
||||
{
|
||||
using (var request_ = new System.Net.Http.HttpRequestMessage())
|
||||
{
|
||||
var keyValues_ = new System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>>();
|
||||
if (grant_type == null)
|
||||
throw new System.ArgumentNullException("grant_type");
|
||||
else
|
||||
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("grant_type", ConvertToString(grant_type, System.Globalization.CultureInfo.InvariantCulture)));
|
||||
if (username != null)
|
||||
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("username", ConvertToString(username, System.Globalization.CultureInfo.InvariantCulture)));
|
||||
if (password != null)
|
||||
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("password", ConvertToString(password, System.Globalization.CultureInfo.InvariantCulture)));
|
||||
if (refresh_token != null)
|
||||
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("refresh_token", ConvertToString(refresh_token, System.Globalization.CultureInfo.InvariantCulture)));
|
||||
request_.Content = new System.Net.Http.FormUrlEncodedContent(keyValues_);
|
||||
request_.Method = new System.Net.Http.HttpMethod("POST");
|
||||
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
||||
|
||||
PrepareRequest(client_, request_, urlBuilder_);
|
||||
|
||||
var url_ = urlBuilder_.ToString();
|
||||
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
|
||||
|
||||
PrepareRequest(client_, request_, url_);
|
||||
|
||||
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
|
||||
var disposeResponse_ = true;
|
||||
try
|
||||
{
|
||||
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
|
||||
if (response_.Content != null && response_.Content.Headers != null)
|
||||
{
|
||||
foreach (var item_ in response_.Content.Headers)
|
||||
headers_[item_.Key] = item_.Value;
|
||||
}
|
||||
|
||||
ProcessResponse(client_, response_);
|
||||
|
||||
var status_ = (int)response_.StatusCode;
|
||||
if (status_ == 200)
|
||||
{
|
||||
var objectResponse_ = await ReadObjectResponseAsync<TokenResponse>(response_, headers_, cancellationToken).ConfigureAwait(false);
|
||||
if (objectResponse_.Object == null)
|
||||
{
|
||||
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||
}
|
||||
return objectResponse_.Object;
|
||||
}
|
||||
else
|
||||
if (status_ == 400)
|
||||
{
|
||||
var objectResponse_ = await ReadObjectResponseAsync<TokenErrorResponse>(response_, headers_, cancellationToken).ConfigureAwait(false);
|
||||
if (objectResponse_.Object == null)
|
||||
{
|
||||
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||
}
|
||||
throw new ApiException<TokenErrorResponse>("An error occurred", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (disposeResponse_)
|
||||
response_.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (disposeClient_)
|
||||
client_.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected struct ObjectResponseResult<T>
|
||||
{
|
||||
public ObjectResponseResult(T responseObject, string responseText)
|
||||
{
|
||||
this.Object = responseObject;
|
||||
this.Text = responseText;
|
||||
}
|
||||
|
||||
public T Object { get; }
|
||||
|
||||
public string Text { get; }
|
||||
}
|
||||
|
||||
public bool ReadResponseAsString { get; set; }
|
||||
|
||||
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Threading.CancellationToken cancellationToken)
|
||||
{
|
||||
if (response == null || response.Content == null)
|
||||
{
|
||||
return new ObjectResponseResult<T>(default(T), string.Empty);
|
||||
}
|
||||
|
||||
if (ReadResponseAsString)
|
||||
{
|
||||
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
|
||||
return new ObjectResponseResult<T>(typedBody, responseText);
|
||||
}
|
||||
catch (Newtonsoft.Json.JsonException exception)
|
||||
{
|
||||
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
|
||||
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
|
||||
using (var streamReader = new System.IO.StreamReader(responseStream))
|
||||
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
|
||||
{
|
||||
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
|
||||
var typedBody = serializer.Deserialize<T>(jsonTextReader);
|
||||
return new ObjectResponseResult<T>(typedBody, string.Empty);
|
||||
}
|
||||
}
|
||||
catch (Newtonsoft.Json.JsonException exception)
|
||||
{
|
||||
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
|
||||
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
if (value is System.Enum)
|
||||
{
|
||||
var name = System.Enum.GetName(value.GetType(), value);
|
||||
if (name != null)
|
||||
{
|
||||
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
|
||||
if (field != null)
|
||||
{
|
||||
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
|
||||
as System.Runtime.Serialization.EnumMemberAttribute;
|
||||
if (attribute != null)
|
||||
{
|
||||
return attribute.Value != null ? attribute.Value : name;
|
||||
}
|
||||
}
|
||||
|
||||
var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
|
||||
return converted == null ? string.Empty : converted;
|
||||
}
|
||||
}
|
||||
else if (value is bool)
|
||||
{
|
||||
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
|
||||
}
|
||||
else if (value is byte[])
|
||||
{
|
||||
return System.Convert.ToBase64String((byte[])value);
|
||||
}
|
||||
else if (value.GetType().IsArray)
|
||||
{
|
||||
var array = System.Linq.Enumerable.OfType<object>((System.Array)value);
|
||||
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
|
||||
}
|
||||
|
||||
var result = System.Convert.ToString(value, cultureInfo);
|
||||
return result == null ? "" : result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>API access token response</summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
|
||||
public partial class TokenResponse
|
||||
{
|
||||
/// <summary>Authentication token</summary>
|
||||
[Newtonsoft.Json.JsonProperty("access_token", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public string Access_token { get; set; }
|
||||
|
||||
/// <summary>Authentication token type</summary>
|
||||
[Newtonsoft.Json.JsonProperty("token_type", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public TokenResponseToken_type Token_type { get; set; }
|
||||
|
||||
/// <summary>Authentication token expiration time, in seconds</summary>
|
||||
[Newtonsoft.Json.JsonProperty("expires_in", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public string Expires_in { get; set; }
|
||||
|
||||
/// <summary>Refresh token. This is only provided when the server is set to allow refresh tokens for web services and when the session timeout duration is not set to Unlimited.</summary>
|
||||
[Newtonsoft.Json.JsonProperty("refresh_token", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public string Refresh_token { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>API access token error response</summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
|
||||
public partial class TokenErrorResponse
|
||||
{
|
||||
/// <summary>Authentication token</summary>
|
||||
[Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public string Message { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Authentication grant type. Use 'password' when authenticating, and 'refresh_token' when refreshing a token.</summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
|
||||
public enum Grant_type
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"password")]
|
||||
Password = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"refresh_token")]
|
||||
Refresh_token = 1,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
|
||||
public enum TokenResponseToken_type
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"bearer")]
|
||||
Bearer = 0,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))")]
|
||||
public partial class ApiException : System.Exception
|
||||
{
|
||||
public int StatusCode { get; private set; }
|
||||
|
||||
public string Response { get; private set; }
|
||||
|
||||
public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }
|
||||
|
||||
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Exception innerException)
|
||||
: base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
Response = response;
|
||||
Headers = headers;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))")]
|
||||
public partial class ApiException<TResult> : ApiException
|
||||
{
|
||||
public TResult Result { get; private set; }
|
||||
|
||||
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, TResult result, System.Exception innerException)
|
||||
: base(message, statusCode, response, headers, innerException)
|
||||
{
|
||||
Result = result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma warning restore 1591
|
||||
#pragma warning restore 1573
|
||||
#pragma warning restore 472
|
||||
#pragma warning restore 114
|
||||
#pragma warning restore 108
|
||||
#pragma warning restore 3016
|
||||
@@ -1,184 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using SecretServerAuthentication.TSS;
|
||||
using SecretServerRestClient.TSS;
|
||||
|
||||
namespace ExternalConnectors.TSS
|
||||
{
|
||||
public class SecretServerInterface
|
||||
{
|
||||
private static class SSConnectionData
|
||||
{
|
||||
public static string ssUsername = "";
|
||||
public static string ssPassword = "";
|
||||
public static string ssUrl = "";
|
||||
public static bool ssSSO = false;
|
||||
|
||||
public static bool initdone = false;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (ssPassword != "" || initdone == true)
|
||||
return;
|
||||
|
||||
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\mRemoteSSInterface");
|
||||
try
|
||||
{
|
||||
// display gui and ask for data
|
||||
SSConnectionForm f = new SSConnectionForm();
|
||||
string? un = key.GetValue("Username") as string;
|
||||
f.tbUsername.Text = un ?? "";
|
||||
|
||||
string? url = key.GetValue("URL") as string;
|
||||
if (url == null || !url.Contains("://"))
|
||||
url = "https://cred.domain.local/SecretServer";
|
||||
f.tbSSURL.Text = url;
|
||||
|
||||
var b = key.GetValue("SSO");
|
||||
if (b == null || (string)b != "True")
|
||||
ssSSO = false;
|
||||
else
|
||||
{
|
||||
ssSSO = true;
|
||||
initdone = true;
|
||||
}
|
||||
f.cbUseSSO.Checked = ssSSO;
|
||||
|
||||
// show dialog
|
||||
while(true)
|
||||
{
|
||||
_ = f.ShowDialog();
|
||||
|
||||
if (f.DialogResult != DialogResult.OK)
|
||||
return;
|
||||
|
||||
// store values to memory
|
||||
ssUsername = f.tbUsername.Text;
|
||||
ssPassword = f.tbPassword.Text;
|
||||
ssUrl = f.tbSSURL.Text;
|
||||
ssSSO = f.cbUseSSO.Checked;
|
||||
|
||||
// check connection first
|
||||
try
|
||||
{
|
||||
if (TestCredentials() == true)
|
||||
break;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MessageBox.Show("TestCredentials failed - please check your credentials");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// write values to registry
|
||||
key.SetValue("Username", ssUsername);
|
||||
key.SetValue("URL", ssUrl);
|
||||
key.SetValue("SSO", ssSSO);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
key.Close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TestCredentials()
|
||||
{
|
||||
string authUsername = SSConnectionData.ssUsername;
|
||||
string authPassword = SSConnectionData.ssPassword;
|
||||
string baseURL = SSConnectionData.ssUrl;
|
||||
|
||||
if (SSConnectionData.ssSSO)
|
||||
{
|
||||
// checking creds doesn't really make sense here, as we can't modify them anyway if something is wrong
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
// Authenticate:
|
||||
var tokenClient = new OAuth2ServiceClient(baseURL, httpClient);
|
||||
// call below will throw an exception if the creds are invalid
|
||||
var token = tokenClient.AuthorizeAsync(Grant_type.Password, authUsername, authPassword, null).Result;
|
||||
// here we can be sure the creds are ok - return success state
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FetchSecret(int secretID, out string secretUsername, out string secretPassword, out string secretDomain)
|
||||
{
|
||||
string authUsername = SSConnectionData.ssUsername;
|
||||
string authPassword = SSConnectionData.ssPassword;
|
||||
string baseURL = SSConnectionData.ssUrl;
|
||||
|
||||
SecretModel secret;
|
||||
if (SSConnectionData.ssSSO)
|
||||
{
|
||||
// REQUIRES IIS CONFIG! https://docs.thycotic.com/ss/11.0.0/api-scripting/webservice-iwa-powershell
|
||||
var handler = new HttpClientHandler() { UseDefaultCredentials = true };
|
||||
using (var httpClient = new HttpClient(handler))
|
||||
{
|
||||
// Call REST API:
|
||||
var client = new SecretsServiceClient($"{baseURL}/winauthwebservices/api", httpClient);
|
||||
secret = client.GetSecretAsync(false, true, secretID, null).Result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
// Authenticate:
|
||||
var tokenClient = new OAuth2ServiceClient(baseURL, httpClient);
|
||||
var token = tokenClient.AuthorizeAsync(Grant_type.Password, authUsername, authPassword, null).Result;
|
||||
var tokenResult = token.Access_token;
|
||||
|
||||
// Set credentials (token):
|
||||
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenResult);
|
||||
|
||||
// Call REST API:
|
||||
var client = new SecretsServiceClient($"{baseURL}/api", httpClient);
|
||||
secret = client.GetSecretAsync(false, true, secretID, null).Result;
|
||||
}
|
||||
}
|
||||
|
||||
// clear return variables
|
||||
secretDomain = "";
|
||||
secretUsername = "";
|
||||
secretPassword = "";
|
||||
|
||||
// parse data and extract what we need
|
||||
foreach (var item in secret.Items)
|
||||
{
|
||||
if (item.FieldName.ToLower().Equals("domain"))
|
||||
secretDomain = item.ItemValue;
|
||||
else if (item.FieldName.ToLower().Equals("username"))
|
||||
secretUsername = item.ItemValue;
|
||||
else if (item.FieldName.ToLower().Equals("password"))
|
||||
secretPassword = item.ItemValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// input must be in form "SSAPI:xxxx" where xxx is the secret id to fetch
|
||||
public static void FetchSecretFromServer(string input, out string username, out string password, out string domain)
|
||||
{
|
||||
// get secret id
|
||||
if (!input.StartsWith("SSAPI:"))
|
||||
throw new Exception("calling this function requires SSAPI: input");
|
||||
int secretID = Int32.Parse(input.Substring(6));
|
||||
|
||||
// init connection credentials, display popup if necessary
|
||||
SSConnectionData.Init();
|
||||
|
||||
// get the secret
|
||||
FetchSecret(secretID, out username, out password, out domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
72
README.MD
72
README.MD
@@ -2,7 +2,7 @@
|
||||
|
||||
<br/><br/>
|
||||
<p align="center">
|
||||
<img width="450" src="https://github.com/mRemoteNG/mRemoteNG/blob/develop/mRemoteNGProjectFiles/Header_dark.png">
|
||||
<img width="500" src="https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/develop/Tools/img/logo.png">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -23,9 +23,7 @@
|
||||
<a href="https://gitter.im/mRemoteNG/PublicChat">
|
||||
<img alt="Gitter" src="https://img.shields.io/gitter/room/mRemoteNG/PublicChat?label=Join%20the%20Chat&logo=Gitter&style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://www.paypal.com/paypalme/mremoteng">
|
||||
<a href="https://www.paypal.me/DavidSparer">
|
||||
<img alt="PayPal" src="https://img.shields.io/badge/%24-PayPal-blue.svg?label=Donate&logo=PayPal&style=flat-square">
|
||||
</a>
|
||||
<a href="bitcoin:16fUnHUM3k7W9Fvpc6dug7TAdfeGEcLbSg">
|
||||
@@ -47,11 +45,11 @@
|
||||
|
||||
---
|
||||
|
||||
| Channel | Build Status | Downloads |
|
||||
| Update Channel | Build Status | Downloads |
|
||||
| ---------------|--------------|-----------|
|
||||
| Stable |  | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.20) |
|
||||
| Preview |  | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.77.1) |
|
||||
| Nightly |  | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/2022.01.07-1.77.2-nb) |
|
||||
| Stable | [](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/master) | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.20) |
|
||||
| Prerelease | [](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/develop) | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.77.1) |
|
||||
| Nightly build | [](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/develop) | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.77.2-nb) |
|
||||
|
||||
## Features
|
||||
|
||||
@@ -75,11 +73,24 @@ For a detailed feature list and general usage support, refer to the [Documentati
|
||||
- [Windows 11](https://en.wikipedia.org/wiki/Windows_11)
|
||||
- [Windows 10](https://en.wikipedia.org/wiki/Windows_10)
|
||||
- [Windows 8.1](https://en.wikipedia.org/wiki/Windows_8.1)
|
||||
- [Windows Server 2022](https://en.wikipedia.org/wiki/Windows_Server_2022)
|
||||
- [Windows Server 2019](https://en.wikipedia.org/wiki/Windows_Server_2019)
|
||||
- [Windows Server 2016](https://en.wikipedia.org/wiki/Windows_Server_2016)
|
||||
- [Windows Server 2012 R2](https://en.wikipedia.org/wiki/Windows_Server_2012_R2)
|
||||
|
||||
### Packaging
|
||||
|
||||
Downloads are provided in three different packages.
|
||||
|
||||
#### Binary package
|
||||
|
||||
The binary package of mRemoteNG is a compiled version of mRemoteNG which comes in an MSI installer.
|
||||
This is the most common way to install mRemoteNG and get up and running.
|
||||
|
||||
#### Portable package
|
||||
|
||||
The portable package contains a modified version of the executable which stores and loads all your settings from files in the application's directory.
|
||||
This package can be used to run mRemoteNG from a USB stick and preserve your configuration wherever you go.
|
||||
|
||||
#### Source package
|
||||
|
||||
This contains the source code from which mRemoteNG is build.
|
||||
@@ -87,8 +98,8 @@ You will need to compile it yourself using Visual Studio.
|
||||
|
||||
### Minimum Requirements
|
||||
|
||||
* [Microsoft Visual C++ Redistributable for Visual Studio 2015 - 2022](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)
|
||||
* [Microsoft .NET 6.0](https://dotnet.microsoft.com/download/dotnet/6.0)
|
||||
* [Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)
|
||||
* [Microsoft .NET Framework 4.0](https://www.microsoft.com/en-us/download/details.aspx?id=17851)
|
||||
* Microsoft Terminal Service Client 6.0 or later
|
||||
* Needed if you use RDP. mstscax.dll and/or msrdp.ocx be registered.
|
||||
|
||||
@@ -102,16 +113,41 @@ mRemoteNG is available as a redistributable MSI package or as a portable ZIP pac
|
||||
|
||||
The MSI package of mRemoteNG can be installed using the command line:
|
||||
|
||||
`msiexec /i [/qn] C:\Path\To\mRemoteNG-Installer.exe [INSTALLDIR=value] [IGNOREPREREQUISITES=value] [/lv* <log path>]`
|
||||
`msiexec /i C:\Path\To\mRemoteNG-Installer.exe [INSTALLDIR=value] [IGNOREPREREQUISITES=value]`
|
||||
|
||||
| Argument/Property | Value | Description |
|
||||
| Property | Value | Description |
|
||||
|-|-|-|
|
||||
| /qn | `Silent Installation` | Will run the installer silently in the background. |
|
||||
| /lv* | `Silent Installation` | Will write a logfile to the specified location. (For paths that contain spaces, enclose the path in double quotes) |
|
||||
| INSTALLDIR | `folder path` | Allows you to set the installation directory from the command line. (For paths that contain spaces, enclose the path in double quotes) |
|
||||
| INSTALLDIR | `folder path` | This allows you to set the installation directory from the command line. For paths that contain spaces, enclose the path in double quotes (""). This overrides any value found in the registry. |
|
||||
| IGNOREPREREQUISITES | `0` or `1` | When set to `1`, the installer will not be halted if any prerequisite check is not met. You must still run the installer as administrator. |
|
||||
|
||||
## Manual Uninstall
|
||||
#### Examples
|
||||
|
||||
**Install to a custom folder**
|
||||
|
||||
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi INSTALLDIR="D:\Work Apps\mRemoteNG"`
|
||||
|
||||
**Ignore prerequisites during a normal install**
|
||||
|
||||
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi IGNOREPREREQUISITES=1`
|
||||
|
||||
**Ignore prerequisites during a silent install**
|
||||
|
||||
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi /qn IGNOREPREREQUISITES=1`
|
||||
|
||||
### Troubleshooting installation
|
||||
|
||||
Turn on verbose logging by using the `/lv* <log path>` argument at the command line.
|
||||
|
||||
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi /l*v C:\mremoteng_install.log`
|
||||
|
||||
## Uninstall
|
||||
|
||||
### Standard Uninstall
|
||||
|
||||
mRemoteNG basic binary package can be uninstalled with Windows Control Panel. If for some reason it does not work please
|
||||
follow information provided below for Manual Uninstall.
|
||||
|
||||
### Manual Uninstall
|
||||
|
||||
_If you are using the Portable version, simply deleting the folder that contains mRemoteNG should be sufficient. These uninstall instructions are only necessary for the normal binary .MSI installed version of mRemoteNG_
|
||||
|
||||
@@ -141,5 +177,5 @@ Check out the [Wiki page](https://github.com/mRemoteNG/mRemoteNG/wiki) on how to
|
||||
|
||||
</br>
|
||||
<p align="center">
|
||||
<img alt="Developed with ReSharper" src="https://github.com/mRemoteNG/mRemoteNG/blob/develop/mRemoteNGProjectFiles/icon_ReSharper.png">
|
||||
<img alt="Developed with ReSharper" src="https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/develop/Tools/img/icon_ReSharper.png">
|
||||
</p>
|
||||
|
||||
331
SharedLibraryNG/HotkeyControl.cs
Normal file
331
SharedLibraryNG/HotkeyControl.cs
Normal file
@@ -0,0 +1,331 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
|
||||
//
|
||||
// Hotkey selection control, written by serenity@exscape.org, 2006-08-03
|
||||
// Please mail me if you find a bug.
|
||||
//
|
||||
|
||||
namespace SharedLibraryNG
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple control that allows the user to select pretty much any valid hotkey combination
|
||||
/// </summary>
|
||||
public class HotkeyControl : TextBox
|
||||
{
|
||||
private const string KeySeparator = " + ";
|
||||
|
||||
// These variables store the current hotkey and modifier(s)
|
||||
private Keys _keyCode = Keys.None;
|
||||
private Keys _modifiers = Keys.None;
|
||||
|
||||
// ArrayLists used to enforce the use of proper modifiers.
|
||||
// Shift+A isn't a valid hotkey, for instance, as it would screw up when the user is typing.
|
||||
private readonly ArrayList _needNonShiftModifier;
|
||||
private readonly ArrayList _needNonAltGrModifier;
|
||||
|
||||
private readonly ContextMenu _emptyContextMenu = new ContextMenu();
|
||||
|
||||
/// <summary>
|
||||
/// Used to make sure that there is no right-click menu available
|
||||
/// </summary>
|
||||
public override ContextMenu ContextMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return _emptyContextMenu;
|
||||
}
|
||||
// ReSharper disable once ValueParameterNotUsed
|
||||
set
|
||||
{
|
||||
base.ContextMenu = _emptyContextMenu;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the control to be non-multiline
|
||||
/// </summary>
|
||||
public override bool Multiline
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Multiline;
|
||||
}
|
||||
// ReSharper disable once ValueParameterNotUsed
|
||||
set
|
||||
{
|
||||
// Ignore what the user wants; force Multiline to false
|
||||
base.Multiline = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new HotkeyControl
|
||||
/// </summary>
|
||||
public HotkeyControl()
|
||||
{
|
||||
// Handle events that occurs when keys are pressed
|
||||
KeyUp += HotkeyControl_KeyUp;
|
||||
|
||||
// Fill the ArrayLists that contain all invalid hotkey combinations
|
||||
_needNonShiftModifier = new ArrayList();
|
||||
_needNonAltGrModifier = new ArrayList();
|
||||
PopulateModifierLists();
|
||||
}
|
||||
|
||||
protected override void OnCreateControl()
|
||||
{
|
||||
base.OnCreateControl();
|
||||
|
||||
ContextMenu = _emptyContextMenu; // Disable right-clicking
|
||||
Multiline = false;
|
||||
Text = "None";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the ArrayLists specifying disallowed hotkeys
|
||||
/// such as Shift+A, Ctrl+Alt+4 (would produce a dollar sign) etc
|
||||
/// </summary>
|
||||
private void PopulateModifierLists()
|
||||
{
|
||||
// Shift + 0 - 9, A - Z
|
||||
for (var k = Keys.D0; k <= Keys.Z; k++)
|
||||
_needNonShiftModifier.Add((int)k);
|
||||
|
||||
// Shift + Numpad keys
|
||||
for (var k = Keys.NumPad0; k <= Keys.NumPad9; k++)
|
||||
_needNonShiftModifier.Add((int)k);
|
||||
|
||||
// Shift + Misc (,;<./ etc)
|
||||
for (var k = Keys.Oem1; k <= Keys.OemBackslash; k++)
|
||||
_needNonShiftModifier.Add((int)k);
|
||||
|
||||
// Misc keys that we can't loop through
|
||||
_needNonShiftModifier.Add((int)Keys.Insert);
|
||||
_needNonShiftModifier.Add((int)Keys.Help);
|
||||
_needNonShiftModifier.Add((int)Keys.Multiply);
|
||||
_needNonShiftModifier.Add((int)Keys.Add);
|
||||
_needNonShiftModifier.Add((int)Keys.Subtract);
|
||||
_needNonShiftModifier.Add((int)Keys.Divide);
|
||||
_needNonShiftModifier.Add((int)Keys.Decimal);
|
||||
_needNonShiftModifier.Add((int)Keys.Return);
|
||||
_needNonShiftModifier.Add((int)Keys.Escape);
|
||||
_needNonShiftModifier.Add((int)Keys.NumLock);
|
||||
_needNonShiftModifier.Add((int)Keys.Scroll);
|
||||
_needNonShiftModifier.Add((int)Keys.Pause);
|
||||
|
||||
// Ctrl+Alt + 0 - 9
|
||||
for (var k = Keys.D0; k <= Keys.D9; k++)
|
||||
_needNonAltGrModifier.Add((int)k);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires when all keys are released. If the current hotkey isn't valid, reset it.
|
||||
/// Otherwise, do nothing and keep the text and hotkey as it was.
|
||||
/// </summary>
|
||||
void HotkeyControl_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (_keyCode == Keys.None && ModifierKeys == Keys.None) ResetHotkey();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles some misc keys, such as Ctrl+Delete and Shift+Insert
|
||||
/// </summary>
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
var keyCode = keyData & Keys.KeyCode;
|
||||
var modifiers = keyData & Keys.Modifiers;
|
||||
|
||||
if (keyData == Keys.Back || keyData == Keys.Delete)
|
||||
{
|
||||
ResetHotkey();
|
||||
return true;
|
||||
}
|
||||
|
||||
_keyCode = keyCode;
|
||||
_modifiers = modifiers;
|
||||
Redraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current hotkey and resets the TextBox
|
||||
/// </summary>
|
||||
public void ResetHotkey()
|
||||
{
|
||||
_keyCode = Keys.None;
|
||||
_modifiers = Keys.None;
|
||||
Text = "None";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to get/set the hotkey (e.g. Keys.A)
|
||||
/// </summary>
|
||||
public Keys KeyCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _keyCode;
|
||||
}
|
||||
set
|
||||
{
|
||||
_keyCode = value;
|
||||
Redraw(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to get/set the modifier keys (e.g. Keys.Alt | Keys.Control)
|
||||
/// </summary>
|
||||
public Keys HotkeyModifiers
|
||||
{
|
||||
get
|
||||
{
|
||||
return _modifiers;
|
||||
}
|
||||
set
|
||||
{
|
||||
_modifiers = value;
|
||||
Redraw(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redraws the TextBox when necessary.
|
||||
/// </summary>
|
||||
/// <param name="validate">Specifies whether this function was called by the Hotkey/HotkeyModifiers properties or by the user.</param>
|
||||
private void Redraw(bool validate = true)
|
||||
{
|
||||
// Only validate input if it comes from the user
|
||||
if (validate)
|
||||
{
|
||||
// No modifier or shift only, AND a hotkey that needs another modifier
|
||||
if ((_modifiers == Keys.Shift || _modifiers == Keys.None) &&
|
||||
_needNonShiftModifier.Contains((int) _keyCode))
|
||||
{
|
||||
if (_modifiers == Keys.None)
|
||||
{
|
||||
// Set Ctrl+Alt as the modifier unless Ctrl+Alt+<key> won't work...
|
||||
if (_needNonAltGrModifier.Contains((int) _keyCode) == false)
|
||||
_modifiers = Keys.Alt | Keys.Control;
|
||||
else // ... in that case, use Shift+Alt instead.
|
||||
_modifiers = Keys.Alt | Keys.Shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
// User pressed Shift and an invalid key (e.g. a letter or a number),
|
||||
// that needs another set of modifier keys
|
||||
_keyCode = Keys.None;
|
||||
Text = _modifiers + " + Invalid Key";
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Check all Ctrl+Alt keys
|
||||
if ((_modifiers == (Keys.Alt | Keys.Control)) &&
|
||||
_needNonAltGrModifier.Contains((int) _keyCode))
|
||||
{
|
||||
// Ctrl+Alt+4 etc won't work; reset hotkey and tell the user
|
||||
_keyCode = Keys.None;
|
||||
Text = _modifiers + " + Invalid Key";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't allow modifiers keys for _keyCode
|
||||
if (_keyCode == Keys.ShiftKey ||
|
||||
_keyCode == Keys.LShiftKey ||
|
||||
_keyCode == Keys.RShiftKey ||
|
||||
_keyCode == Keys.ControlKey ||
|
||||
_keyCode == Keys.LControlKey ||
|
||||
_keyCode == Keys.RControlKey ||
|
||||
_keyCode == Keys.Menu ||
|
||||
_keyCode == Keys.LMenu ||
|
||||
_keyCode == Keys.RMenu ||
|
||||
_keyCode == Keys.LWin ||
|
||||
_keyCode == Keys.RWin)
|
||||
_keyCode = Keys.None;
|
||||
|
||||
if (_modifiers == Keys.None)
|
||||
{
|
||||
if (_keyCode == Keys.None)
|
||||
{
|
||||
ResetHotkey();
|
||||
return;
|
||||
}
|
||||
|
||||
// We get here if we've got a hotkey that is valid without a modifier,
|
||||
// like F1-F12, Media-keys etc.
|
||||
Text = _keyCode.ToString();
|
||||
return;
|
||||
}
|
||||
|
||||
Text = string.Join(KeySeparator, new[] { KeysToString(_modifiers), KeysToString(_keyCode) });
|
||||
}
|
||||
|
||||
public static string KeysToString(Keys keys)
|
||||
{
|
||||
if (keys == Keys.None) return "None";
|
||||
|
||||
var modifiers = (keys & Keys.Modifiers);
|
||||
var keyCode = (keys & Keys.KeyCode);
|
||||
|
||||
var strings = new List<string>();
|
||||
|
||||
if (modifiers != 0)
|
||||
{
|
||||
var modifierStrings = new List<string>(modifiers.ToString().Replace(", ", ",").Split(','));
|
||||
modifierStrings.Sort(new KeyModifierComparer());
|
||||
strings.AddRange(modifierStrings);
|
||||
}
|
||||
|
||||
if (keyCode != 0)
|
||||
{
|
||||
var keyString = keyCode.ToString();
|
||||
var keyHashtable = new Dictionary<string, string>
|
||||
{
|
||||
{"Next", "PageDown"},
|
||||
{"Oemcomma", ","},
|
||||
{"OemMinus", "-"},
|
||||
{"OemOpenBrackets", "["},
|
||||
{"OemPeriod", "."},
|
||||
{"Oemplus", "="},
|
||||
{"OemQuestion", "/"},
|
||||
{"Oemtilde", "`"},
|
||||
{"D0", "0"},
|
||||
{"D1", "1"},
|
||||
{"D2", "2"},
|
||||
{"D3", "3"},
|
||||
{"D4", "4"},
|
||||
{"D5", "5"},
|
||||
{"D6", "6"},
|
||||
{"D7", "7"},
|
||||
{"D8", "8"},
|
||||
{"D9", "9"},
|
||||
};
|
||||
if (keyHashtable.ContainsKey(keyString)) keyString = keyHashtable[keyString];
|
||||
strings.Add(keyString);
|
||||
}
|
||||
|
||||
return string.Join(KeySeparator, strings.ToArray());
|
||||
}
|
||||
|
||||
private class KeyModifierComparer : IComparer<string>
|
||||
{
|
||||
private static readonly List<string> ModifierOrder = new List<string>
|
||||
{
|
||||
"control",
|
||||
"alt",
|
||||
"shift",
|
||||
};
|
||||
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
var xIndex = ModifierOrder.IndexOf(x.ToLowerInvariant());
|
||||
var yIndex = ModifierOrder.IndexOf(y.ToLowerInvariant());
|
||||
return xIndex - yIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
258
SharedLibraryNG/KeyboardHook.cs
Normal file
258
SharedLibraryNG/KeyboardHook.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
//
|
||||
// Based on code from Stephen Toub's MSDN blog at
|
||||
// http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SharedLibraryNG
|
||||
{
|
||||
public class KeyboardHook
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool PostMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, HookKeyMsgData lParam);
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
[Flags]
|
||||
public enum ModifierKeys
|
||||
{
|
||||
None = 0x0000,
|
||||
Shift = 0x0001,
|
||||
LeftShift = 0x002,
|
||||
RightShift = 0x004,
|
||||
Control = 0x0008,
|
||||
LeftControl = 0x010,
|
||||
RightControl = 0x20,
|
||||
Alt = 0x0040,
|
||||
LeftAlt = 0x0080,
|
||||
RightAlt = 0x0100,
|
||||
Win = 0x0200,
|
||||
LeftWin = 0x0400,
|
||||
RightWin = 0x0800,
|
||||
}
|
||||
|
||||
protected class KeyNotificationEntry
|
||||
: IEquatable<KeyNotificationEntry>
|
||||
{
|
||||
public IntPtr WindowHandle;
|
||||
public Int32 KeyCode;
|
||||
public ModifierKeys ModifierKeys;
|
||||
public Boolean Block;
|
||||
|
||||
public bool Equals(KeyNotificationEntry obj)
|
||||
{
|
||||
return (WindowHandle == obj.WindowHandle &&
|
||||
KeyCode == obj.KeyCode &&
|
||||
ModifierKeys == obj.ModifierKeys &&
|
||||
Block == obj.Block);
|
||||
}
|
||||
}
|
||||
|
||||
public const string HookKeyMsgName = "HOOKKEYMSG-{56BE0940-34DA-11E1-B308-C6714824019B}";
|
||||
private static Int32 _hookKeyMsg;
|
||||
public static Int32 HookKeyMsg
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hookKeyMsg == 0)
|
||||
{
|
||||
_hookKeyMsg = Win32.RegisterWindowMessage(HookKeyMsgName).ToInt32();
|
||||
if (_hookKeyMsg == 0)
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
}
|
||||
return _hookKeyMsg;
|
||||
}
|
||||
}
|
||||
|
||||
// this is a custom structure that will be passed to
|
||||
// the requested hWnd via a WM_APP_HOOKKEYMSG message
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class HookKeyMsgData
|
||||
{
|
||||
public Int32 KeyCode;
|
||||
public ModifierKeys ModifierKeys;
|
||||
public Boolean WasBlocked;
|
||||
}
|
||||
|
||||
private static int _referenceCount;
|
||||
private static IntPtr _hook;
|
||||
private static readonly Win32.LowLevelKeyboardProcDelegate LowLevelKeyboardProcStaticDelegate = LowLevelKeyboardProc;
|
||||
private static readonly List<KeyNotificationEntry> NotificationEntries = new List<KeyNotificationEntry>();
|
||||
|
||||
public KeyboardHook()
|
||||
{
|
||||
_referenceCount++;
|
||||
SetHook();
|
||||
}
|
||||
|
||||
~KeyboardHook()
|
||||
{
|
||||
_referenceCount--;
|
||||
if (_referenceCount < 1) UnsetHook();
|
||||
}
|
||||
|
||||
private static void SetHook()
|
||||
{
|
||||
if (_hook != IntPtr.Zero) return;
|
||||
|
||||
var curProcess = Process.GetCurrentProcess();
|
||||
var curModule = curProcess.MainModule;
|
||||
|
||||
var hook = Win32.SetWindowsHookEx(Win32.WH_KEYBOARD_LL, LowLevelKeyboardProcStaticDelegate, Win32.GetModuleHandle(curModule.ModuleName), 0);
|
||||
if (hook == IntPtr.Zero)
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
|
||||
_hook = hook;
|
||||
}
|
||||
|
||||
private static void UnsetHook()
|
||||
{
|
||||
if (_hook == IntPtr.Zero) return;
|
||||
|
||||
Win32.UnhookWindowsHookEx(_hook);
|
||||
_hook = IntPtr.Zero;
|
||||
}
|
||||
|
||||
private static IntPtr LowLevelKeyboardProc(Int32 nCode, IntPtr wParam, Win32.KBDLLHOOKSTRUCT lParam)
|
||||
{
|
||||
var wParamInt = wParam.ToInt32();
|
||||
var result = 0;
|
||||
|
||||
if (nCode == Win32.HC_ACTION)
|
||||
{
|
||||
switch (wParamInt)
|
||||
{
|
||||
case Win32.WM_KEYDOWN:
|
||||
case Win32.WM_SYSKEYDOWN:
|
||||
case Win32.WM_KEYUP:
|
||||
case Win32.WM_SYSKEYUP:
|
||||
result = OnKey(wParamInt, lParam);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != 0) return new IntPtr(result);
|
||||
|
||||
return Win32.CallNextHookEx(_hook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
private static int OnKey(Int32 msg, Win32.KBDLLHOOKSTRUCT key)
|
||||
{
|
||||
var result = 0;
|
||||
|
||||
foreach (var notificationEntry in NotificationEntries)
|
||||
if (GetFocusWindow() == notificationEntry.WindowHandle && notificationEntry.KeyCode == key.vkCode)
|
||||
{
|
||||
var modifierKeys = GetModifierKeyState();
|
||||
if (!ModifierKeysMatch(notificationEntry.ModifierKeys, modifierKeys)) continue;
|
||||
|
||||
var wParam = new IntPtr(msg);
|
||||
var lParam = new HookKeyMsgData
|
||||
{
|
||||
KeyCode = key.vkCode,
|
||||
ModifierKeys = modifierKeys,
|
||||
WasBlocked = notificationEntry.Block,
|
||||
};
|
||||
|
||||
if (!PostMessage(notificationEntry.WindowHandle, HookKeyMsg, wParam, lParam))
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
|
||||
if (notificationEntry.Block) result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IntPtr GetFocusWindow()
|
||||
{
|
||||
var guiThreadInfo = new Win32.GUITHREADINFO();
|
||||
if (!Win32.GetGUIThreadInfo(0, guiThreadInfo))
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
return Win32.GetAncestor(guiThreadInfo.hwndFocus, Win32.GA_ROOT);
|
||||
}
|
||||
|
||||
protected static Dictionary<Int32, ModifierKeys> ModifierKeyTable = new Dictionary<Int32, ModifierKeys>
|
||||
{
|
||||
{ Win32.VK_SHIFT, ModifierKeys.Shift },
|
||||
{ Win32.VK_LSHIFT, ModifierKeys.LeftShift },
|
||||
{ Win32.VK_RSHIFT, ModifierKeys.RightShift },
|
||||
{ Win32.VK_CONTROL, ModifierKeys.Control },
|
||||
{ Win32.VK_LCONTROL, ModifierKeys.LeftControl },
|
||||
{ Win32.VK_RCONTROL, ModifierKeys.RightControl },
|
||||
{ Win32.VK_MENU, ModifierKeys.Alt },
|
||||
{ Win32.VK_LMENU, ModifierKeys.LeftAlt },
|
||||
{ Win32.VK_RMENU, ModifierKeys.RightAlt },
|
||||
{ Win32.VK_LWIN, ModifierKeys.LeftWin },
|
||||
{ Win32.VK_RWIN, ModifierKeys.RightWin },
|
||||
};
|
||||
|
||||
public static ModifierKeys GetModifierKeyState()
|
||||
{
|
||||
var modifierKeyState = ModifierKeys.None;
|
||||
|
||||
foreach (KeyValuePair<Int32, ModifierKeys> pair in ModifierKeyTable)
|
||||
{
|
||||
if ((Win32.GetAsyncKeyState(pair.Key) & Win32.KEYSTATE_PRESSED) != 0) modifierKeyState |= pair.Value;
|
||||
}
|
||||
|
||||
if ((modifierKeyState & ModifierKeys.LeftWin) != 0) modifierKeyState |= ModifierKeys.Win;
|
||||
if ((modifierKeyState & ModifierKeys.RightWin) != 0) modifierKeyState |= ModifierKeys.Win;
|
||||
|
||||
return modifierKeyState;
|
||||
}
|
||||
|
||||
public static Boolean ModifierKeysMatch(ModifierKeys requestedKeys, ModifierKeys pressedKeys)
|
||||
{
|
||||
if ((requestedKeys & ModifierKeys.Shift) != 0) pressedKeys &= ~(ModifierKeys.LeftShift | ModifierKeys.RightShift);
|
||||
if ((requestedKeys & ModifierKeys.Control) != 0) pressedKeys &= ~(ModifierKeys.LeftControl | ModifierKeys.RightControl);
|
||||
if ((requestedKeys & ModifierKeys.Alt) != 0) pressedKeys &= ~(ModifierKeys.LeftAlt | ModifierKeys.RightAlt);
|
||||
if ((requestedKeys & ModifierKeys.Win) != 0) pressedKeys &= ~(ModifierKeys.LeftWin | ModifierKeys.RightWin);
|
||||
return requestedKeys == pressedKeys;
|
||||
}
|
||||
|
||||
public static void RequestKeyNotification(IntPtr windowHandle, Int32 keyCode, Boolean block)
|
||||
{
|
||||
RequestKeyNotification(windowHandle, keyCode, ModifierKeys.None, block);
|
||||
}
|
||||
|
||||
public static void RequestKeyNotification(IntPtr windowHandle, Int32 keyCode, ModifierKeys modifierKeys = ModifierKeys.None, Boolean block = false)
|
||||
{
|
||||
var newNotificationEntry = new KeyNotificationEntry
|
||||
{
|
||||
WindowHandle = windowHandle,
|
||||
KeyCode = keyCode,
|
||||
ModifierKeys = modifierKeys,
|
||||
Block = block,
|
||||
};
|
||||
|
||||
foreach (var notificationEntry in NotificationEntries)
|
||||
if (notificationEntry == newNotificationEntry) return;
|
||||
|
||||
NotificationEntries.Add(newNotificationEntry);
|
||||
}
|
||||
|
||||
public static void CancelKeyNotification(IntPtr windowHandle, Int32 keyCode, Boolean block)
|
||||
{
|
||||
CancelKeyNotification(windowHandle, keyCode, ModifierKeys.None, block);
|
||||
}
|
||||
|
||||
public static void CancelKeyNotification(IntPtr windowHandle, Int32 keyCode, ModifierKeys modifierKeys = ModifierKeys.None, Boolean block = false)
|
||||
{
|
||||
var notificationEntry = new KeyNotificationEntry
|
||||
{
|
||||
WindowHandle = windowHandle,
|
||||
KeyCode = keyCode,
|
||||
ModifierKeys = modifierKeys,
|
||||
Block = block,
|
||||
};
|
||||
|
||||
NotificationEntries.Remove(notificationEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
SharedLibraryNG/Properties/AssemblyInfo.cs
Normal file
36
SharedLibraryNG/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SharedLibraryNG")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SharedLibraryNG")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("f4470853-f933-4203-9d2a-b3c731e225c7")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
55
SharedLibraryNG/SharedLibraryNG.csproj
Normal file
55
SharedLibraryNG/SharedLibraryNG.csproj
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{0F615504-5F30-4CF2-8341-1DE7FEC95A23}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SharedLibraryNG</RootNamespace>
|
||||
<AssemblyName>SharedLibraryNG</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="HotkeyControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="KeyboardHook.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Win32.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
171
SharedLibraryNG/Win32.cs
Normal file
171
SharedLibraryNG/Win32.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SharedLibraryNG
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
public static class Win32
|
||||
{
|
||||
#region Functions
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, Int32 dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, KBDLLHOOKSTRUCT lParam);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr RegisterWindowMessage(string lpString);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetGUIThreadInfo(Int32 idThread, GUITHREADINFO lpgui);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetAncestor(IntPtr hwnd, UInt32 gaFlags);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern Int16 GetAsyncKeyState(Int32 vKey);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delegates
|
||||
|
||||
public delegate IntPtr LowLevelKeyboardProcDelegate(Int32 nCode, IntPtr wParam, KBDLLHOOKSTRUCT lParam);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Structures
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class KBDLLHOOKSTRUCT
|
||||
{
|
||||
public Int32 vkCode;
|
||||
public Int32 scanCode;
|
||||
public Int32 flags;
|
||||
public Int32 time;
|
||||
public IntPtr dwExtraInfo;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int left;
|
||||
public int top;
|
||||
public int right;
|
||||
public int bottom;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class GUITHREADINFO
|
||||
{
|
||||
public GUITHREADINFO()
|
||||
{
|
||||
cbSize = Convert.ToInt32(Marshal.SizeOf(this));
|
||||
}
|
||||
|
||||
public Int32 cbSize;
|
||||
public Int32 flags;
|
||||
public IntPtr hwndActive;
|
||||
public IntPtr hwndFocus;
|
||||
public IntPtr hwndCapture;
|
||||
public IntPtr hwndMenuOwner;
|
||||
public IntPtr hwndMoveSize;
|
||||
public IntPtr hwndCaret;
|
||||
public RECT rcCaret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constants
|
||||
|
||||
// GetAncestor
|
||||
public const int GA_ROOT = 2;
|
||||
|
||||
// SetWindowsHookEx
|
||||
public const int WH_KEYBOARD_LL = 13;
|
||||
|
||||
// LowLevelKeyboardProcDelegate
|
||||
public const int HC_ACTION = 0;
|
||||
|
||||
// SendMessage
|
||||
public const int WM_KEYDOWN = 0x0100;
|
||||
public const int WM_KEYUP = 0x0101;
|
||||
public const int WM_SYSKEYDOWN = 0x0104;
|
||||
public const int WM_SYSKEYUP = 0x0105;
|
||||
|
||||
// GetAsyncKeyState
|
||||
public const int KEYSTATE_PRESSED = 0x8000;
|
||||
|
||||
#region Virtual Keys
|
||||
public const int VK_CANCEL = 0x0003;
|
||||
public const int VK_BACK = 0x0008;
|
||||
public const int VK_TAB = 0x0009;
|
||||
public const int VK_CLEAR = 0x000C;
|
||||
public const int VK_RETURN = 0x000D;
|
||||
public const int VK_PAUSE = 0x0013;
|
||||
public const int VK_ESCAPE = 0x001B;
|
||||
public const int VK_SNAPSHOT = 0x002C;
|
||||
public const int VK_INSERT = 0x002D;
|
||||
public const int VK_DELETE = 0x002E;
|
||||
public const int VK_HOME = 0x0024;
|
||||
public const int VK_END = 0x0023;
|
||||
public const int VK_PRIOR = 0x0021;
|
||||
public const int VK_NEXT = 0x0022;
|
||||
public const int VK_LEFT = 0x0025;
|
||||
public const int VK_UP = 0x0026;
|
||||
public const int VK_RIGHT = 0x0027;
|
||||
public const int VK_DOWN = 0x0028;
|
||||
public const int VK_SELECT = 0x0029;
|
||||
public const int VK_PRINT = 0x002A;
|
||||
public const int VK_EXECUTE = 0x002B;
|
||||
public const int VK_HELP = 0x002F;
|
||||
public const int VK_LWIN = 0x005B;
|
||||
public const int VK_RWIN = 0x005C;
|
||||
public const int VK_APPS = 0x005D;
|
||||
public const int VK_F1 = 0x0070;
|
||||
public const int VK_F2 = 0x0071;
|
||||
public const int VK_F3 = 0x0072;
|
||||
public const int VK_F4 = 0x0073;
|
||||
public const int VK_F5 = 0x0074;
|
||||
public const int VK_F6 = 0x0075;
|
||||
public const int VK_F7 = 0x0076;
|
||||
public const int VK_F8 = 0x0077;
|
||||
public const int VK_F9 = 0x0078;
|
||||
public const int VK_F10 = 0x0079;
|
||||
public const int VK_F11 = 0x007A;
|
||||
public const int VK_F12 = 0x007B;
|
||||
public const int VK_SHIFT = 0x0010;
|
||||
public const int VK_LSHIFT = 0x00A0;
|
||||
public const int VK_RSHIFT = 0x00A1;
|
||||
public const int VK_CONTROL = 0x0011;
|
||||
public const int VK_LCONTROL = 0x00A2;
|
||||
public const int VK_RCONTROL = 0x00A3;
|
||||
public const int VK_MENU = 0x0012;
|
||||
public const int VK_LMENU = 0x00A4;
|
||||
public const int VK_RMENU = 0x00A5;
|
||||
|
||||
public const int VK_OEM_1 = 0x00BA;
|
||||
public const int VK_OEM_2 = 0x00BF;
|
||||
public const int VK_OEM_3 = 0x00C0;
|
||||
public const int VK_OEM_4 = 0x00DB;
|
||||
public const int VK_OEM_5 = 0x00DC;
|
||||
public const int VK_OEM_6 = 0x00DD;
|
||||
public const int VK_OEM_7 = 0x00DE;
|
||||
public const int VK_OEM_8 = 0x00DF;
|
||||
public const int VK_OEM_102 = 0x00E2;
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// ReSharper restore InconsistentNaming
|
||||
}
|
||||
}
|
||||
BIN
Tools/7zip/7za.dll
Normal file
BIN
Tools/7zip/7za.dll
Normal file
Binary file not shown.
BIN
Tools/7zip/7za.exe
Normal file
BIN
Tools/7zip/7za.exe
Normal file
Binary file not shown.
BIN
Tools/7zip/7zxa.dll
Normal file
BIN
Tools/7zip/7zxa.dll
Normal file
Binary file not shown.
31
Tools/7zip/License.txt
Normal file
31
Tools/7zip/License.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
7-Zip Extra
|
||||
~~~~~~~~~~~
|
||||
License for use and distribution
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright (C) 1999-2019 Igor Pavlov.
|
||||
|
||||
7-Zip Extra files are under the GNU LGPL license.
|
||||
|
||||
|
||||
Notes:
|
||||
You can use 7-Zip Extra on any computer, including a computer in a commercial
|
||||
organization. You don't need to register or pay for 7-Zip.
|
||||
|
||||
|
||||
GNU LGPL information
|
||||
--------------------
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You can receive a copy of the GNU Lesser General Public License from
|
||||
http://www.gnu.org/
|
||||
|
||||
111
Tools/7zip/history.txt
Normal file
111
Tools/7zip/history.txt
Normal file
@@ -0,0 +1,111 @@
|
||||
7-Zip Extra history
|
||||
-------------------
|
||||
|
||||
This file contains only information about changes related to that package exclusively.
|
||||
The full history of changes is listed in history.txt in main 7-Zip program.
|
||||
|
||||
|
||||
19.00 2019-02-21
|
||||
-------------------------
|
||||
- Encryption strength for 7z archives was increased:
|
||||
the size of random initialization vector was increased from 64-bit to 128-bit,
|
||||
and the pseudo-random number generator was improved.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
18.06 2018-12-30
|
||||
-------------------------
|
||||
- The speed for LZMA/LZMA2 compressing was increased by 3-10%,
|
||||
and there are minor changes in compression ratio.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
18.05 2018-04-30
|
||||
-------------------------
|
||||
- The speed for LZMA/LZMA2 compressing was increased
|
||||
by 8% for fastest/fast compression levels and
|
||||
by 3% for normal/maximum compression levels.
|
||||
|
||||
|
||||
18.03 beta 2018-03-04
|
||||
-------------------------
|
||||
- The speed for single-thread LZMA/LZMA2 decoding
|
||||
was increased by 30% in x64 version and by 3% in x86 version.
|
||||
- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
|
||||
if there are multiple independent data chunks in LZMA2 stream.
|
||||
|
||||
|
||||
9.35 beta 2014-12-07
|
||||
------------------------------
|
||||
- SFX modules were moved to LZMA SDK package.
|
||||
|
||||
|
||||
9.34 alpha 2014-06-22
|
||||
------------------------------
|
||||
- Minimum supported system now is Windows 2000 for EXE and DLL files.
|
||||
- all EXE and DLL files use msvcrt.dll.
|
||||
- 7zr.exe now support AES encryption.
|
||||
|
||||
|
||||
9.18 2010-11-02
|
||||
------------------------------
|
||||
- New small SFX module for installers.
|
||||
|
||||
|
||||
9.17 2010-10-04
|
||||
------------------------------
|
||||
- New 7-Zip plugin for FAR Manager x64.
|
||||
|
||||
|
||||
9.10 2009-12-30
|
||||
------------------------------
|
||||
- 7-Zip for installers now supports LZMA2.
|
||||
|
||||
|
||||
9.09 2009-12-12
|
||||
------------------------------
|
||||
- LZMA2 compression method support.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
4.65 2009-02-03
|
||||
------------------------------
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
4.38 beta 2006-04-13
|
||||
------------------------------
|
||||
- SFX for installers now supports new properties in config file:
|
||||
Progress, Directory, ExecuteFile, ExecuteParameters.
|
||||
|
||||
|
||||
4.34 beta 2006-02-27
|
||||
------------------------------
|
||||
- ISetProperties::SetProperties:
|
||||
it's possible to specify desirable number of CPU threads:
|
||||
PROPVARIANT: name=L"mt", vt = VT_UI4, ulVal = NumberOfThreads
|
||||
If "mt" is not defined, 7za.dll will check number of processors in system to set
|
||||
number of desirable threads.
|
||||
Now 7za.dll can use:
|
||||
2 threads for LZMA compressing
|
||||
N threads for BZip2 compressing
|
||||
4 threads for BZip2 decompressing
|
||||
Other codecs use only one thread.
|
||||
Note: 7za.dll can use additional "small" threads with low CPU load.
|
||||
- It's possible to call ISetProperties::SetProperties to specify "mt" property for decoder.
|
||||
|
||||
|
||||
4.33 beta 2006-02-05
|
||||
------------------------------
|
||||
- Compressing speed and Memory requirements were increased.
|
||||
Default dictionary size was increased: Fastest: 64 KB, Fast: 1 MB,
|
||||
Normal: 4 MB, Max: 16 MB, Ultra: 64 MB.
|
||||
- 7z/LZMA now can use only these match finders: HC4, BT2, BT3, BT4
|
||||
|
||||
|
||||
4.27 2005-09-21
|
||||
------------------------------
|
||||
- Some GUIDs/interfaces were changed.
|
||||
IStream.h:
|
||||
ISequentialInStream::Read now works as old ReadPart
|
||||
ISequentialOutStream::Write now works as old WritePart
|
||||
124
Tools/7zip/readme.txt
Normal file
124
Tools/7zip/readme.txt
Normal file
@@ -0,0 +1,124 @@
|
||||
7-Zip Extra 19.00
|
||||
-----------------
|
||||
|
||||
7-Zip Extra is package of extra modules of 7-Zip.
|
||||
|
||||
7-Zip Copyright (C) 1999-2019 Igor Pavlov.
|
||||
|
||||
7-Zip is free software. Read License.txt for more information about license.
|
||||
|
||||
Source code of binaries can be found at:
|
||||
http://www.7-zip.org/
|
||||
|
||||
This package contains the following files:
|
||||
|
||||
7za.exe - standalone console version of 7-Zip with reduced formats support.
|
||||
7za.dll - library for working with 7z archives
|
||||
7zxa.dll - library for extracting from 7z archives
|
||||
License.txt - license information
|
||||
readme.txt - this file
|
||||
|
||||
Far\ - plugin for Far Manager
|
||||
x64\ - binaries for x64
|
||||
|
||||
|
||||
All 32-bit binaries can work in:
|
||||
Windows 2000 / 2003 / 2008 / XP / Vista / 7 / 8 / 10
|
||||
and in any Windows x64 version with WoW64 support.
|
||||
All x64 binaries can work in any Windows x64 version.
|
||||
|
||||
All binaries use msvcrt.dll.
|
||||
|
||||
7za.exe
|
||||
-------
|
||||
|
||||
7za.exe - is a standalone console version of 7-Zip with reduced formats support.
|
||||
|
||||
Extra: 7za.exe : support for only some formats of 7-Zip.
|
||||
7-Zip: 7z.exe with 7z.dll : support for all formats of 7-Zip.
|
||||
|
||||
7za.exe and 7z.exe from 7-Zip have same command line interface.
|
||||
7za.exe doesn't use external DLL files.
|
||||
|
||||
You can read Help File (7-zip.chm) from 7-Zip package for description
|
||||
of all commands and switches for 7za.exe and 7z.exe.
|
||||
|
||||
7za.exe features:
|
||||
|
||||
- High compression ratio in 7z format
|
||||
- Supported formats:
|
||||
- Packing / unpacking: 7z, xz, ZIP, GZIP, BZIP2 and TAR
|
||||
- Unpacking only: Z, lzma, CAB.
|
||||
- Highest compression ratio for ZIP and GZIP formats.
|
||||
- Fast compression and decompression
|
||||
- Strong AES-256 encryption in 7z and ZIP formats.
|
||||
|
||||
Note: LZMA SDK contains 7zr.exe - more reduced version of 7za.exe.
|
||||
But you can use 7zr.exe as "public domain" code.
|
||||
|
||||
|
||||
|
||||
DLL files
|
||||
---------
|
||||
|
||||
7za.dll and 7zxa.dll are reduced versions of 7z.dll from 7-Zip.
|
||||
7za.dll and 7zxa.dll support only 7z format.
|
||||
Note: 7z.dll is main DLL file that works with all archive types in 7-Zip.
|
||||
|
||||
7za.dll and 7zxa.dll support the following decoding methods:
|
||||
- LZMA, LZMA2, PPMD, BCJ, BCJ2, COPY, 7zAES, BZip2, Deflate.
|
||||
|
||||
7za.dll also supports 7z encoding with the following encoding methods:
|
||||
- LZMA, LZMA2, PPMD, BCJ, BCJ2, COPY, 7zAES.
|
||||
|
||||
7za.dll and 7zxa.dll work via COM interfaces.
|
||||
But these DLLs don't use standard COM interfaces for objects creating.
|
||||
|
||||
Look also example code that calls DLL functions (in source code of 7-Zip):
|
||||
|
||||
7zip\UI\Client7z
|
||||
|
||||
Another example of binary that uses these interface is 7-Zip itself.
|
||||
The following binaries from 7-Zip use 7z.dll:
|
||||
- 7z.exe (console version)
|
||||
- 7zG.exe (GUI version)
|
||||
- 7zFM.exe (7-Zip File Manager)
|
||||
|
||||
Note: The source code of LZMA SDK also contains the code for similar DLLs
|
||||
(DLLs without BZip2, Deflate support). And these files from LZMA SDK can be
|
||||
used as "public domain" code. If you use LZMA SDK files, you don't need to
|
||||
follow GNU LGPL rules, if you want to change the code.
|
||||
|
||||
|
||||
|
||||
|
||||
License FAQ
|
||||
-----------
|
||||
|
||||
Can I use the EXE or DLL files from 7-Zip in a commercial application?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Yes, but you are required to specify in documentation for your application:
|
||||
(1) that you used parts of the 7-Zip program,
|
||||
(2) that 7-Zip is licensed under the GNU LGPL license and
|
||||
(3) you must give a link to www.7-zip.org, where the source code can be found.
|
||||
|
||||
|
||||
Can I use the source code of 7-Zip in a commercial application?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Since 7-Zip is licensed under the GNU LGPL you must follow the rules of that license.
|
||||
In brief, it means that any LGPL'ed code must remain licensed under the LGPL.
|
||||
For instance, you can change the code from 7-Zip or write a wrapper for some
|
||||
code from 7-Zip and compile it into a DLL; but, the source code of that DLL
|
||||
(including your modifications / additions / wrapper) must be licensed under
|
||||
the LGPL or GPL.
|
||||
Any other code in your application can be licensed as you wish. This scheme allows
|
||||
users and developers to change LGPL'ed code and recompile that DLL. That is the
|
||||
idea of free software. Read more here: http://www.gnu.org/.
|
||||
|
||||
|
||||
|
||||
Note: You can look also LZMA SDK, which is available under a more liberal license.
|
||||
|
||||
|
||||
---
|
||||
End of document
|
||||
15
Tools/copy_puttyng.ps1
Normal file
15
Tools/copy_puttyng.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
Write-Output "Copying PUTTYNG to correct directory"
|
||||
Copy-Item -Path (Join-Path -Path $SolutionDir -ChildPath "mRemoteNG\Resources\PuTTYNG.exe") -Destination $TargetDir -Force
|
||||
|
||||
Write-Output ""
|
||||
21
Tools/copy_release_installer.ps1
Normal file
21
Tools/copy_release_installer.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
param (
|
||||
[string]
|
||||
$SourcePath,
|
||||
|
||||
[string]
|
||||
$DestinationDir
|
||||
)
|
||||
|
||||
Write-Host $SourcePath
|
||||
Write-Host $DestinationDir
|
||||
|
||||
if (!(Test-Path -Path $DestinationDir))
|
||||
{
|
||||
New-Item -Path $DestinationDir -ItemType "directory"
|
||||
}
|
||||
|
||||
$sourceFiles = Get-ChildItem -Path $SourcePath -Recurse | ?{$_.Extension -match "exe|msi"}
|
||||
foreach ($item in $sourceFiles)
|
||||
{
|
||||
Copy-Item -Path $item.FullName -Destination $DestinationDir -Force
|
||||
}
|
||||
19
Tools/copy_themes.ps1
Normal file
19
Tools/copy_themes.ps1
Normal file
@@ -0,0 +1,19 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
Write-Output "Copying THEMES folder to output"
|
||||
|
||||
$sourceFiles = [io.path]::combine($SolutionDir , 'mRemoteNG\Resources\Themes' )
|
||||
$DestinationDir = [io.path]::combine($TargetDir , 'Themes')
|
||||
|
||||
robocopy $sourceFiles $DestinationDir *.vstheme /s
|
||||
|
||||
Write-Output ""
|
||||
17
Tools/copy_tiles.ps1
Normal file
17
Tools/copy_tiles.ps1
Normal file
@@ -0,0 +1,17 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
Write-Output "Copying TILES folder to output"
|
||||
|
||||
$sourceFiles = [io.path]::combine($SolutionDir , 'mRemoteNG\Resources\Tiles' )
|
||||
robocopy $sourceFiles $TargetDir *.*
|
||||
|
||||
Write-Output ""
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
Tools/img/logo.png
Normal file
BIN
Tools/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@@ -25,9 +25,9 @@ param (
|
||||
$ExcludeFromSigning
|
||||
)
|
||||
|
||||
Write-Output "+===========================================================================================+"
|
||||
Write-Output "| Beginning mRemoteNG Installer Post Build |"
|
||||
Write-Output "+===========================================================================================+"
|
||||
Write-Output "+=================================================================+"
|
||||
Write-Output "| Beginning mRemoteNG Installer Post Build |"
|
||||
Write-Output "+=================================================================+"
|
||||
Format-Table -AutoSize -Wrap -InputObject @{
|
||||
"SolutionDir" = $SolutionDir
|
||||
"TargetDir" = $TargetDir
|
||||
@@ -40,4 +40,5 @@ Format-Table -AutoSize -Wrap -InputObject @{
|
||||
|
||||
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning -SolutionDir $SolutionDir
|
||||
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath -SolutionDir $SolutionDir
|
||||
& "$PSScriptRoot\rename_and_copy_installer.ps1" -SolutionDir $SolutionDir
|
||||
& "$PSScriptRoot\rename_installer_with_version.ps1" -SolutionDir $SolutionDir
|
||||
& "$PSScriptRoot\copy_release_installer.ps1" -SourcePath $TargetDir -DestinationDir (Join-Path -Path $SolutionDir -ChildPath "Release")
|
||||
@@ -25,9 +25,9 @@ param (
|
||||
$ExcludeFromSigning
|
||||
)
|
||||
|
||||
Write-Output "+===========================================================================================+"
|
||||
Write-Output "| Beginning mRemoteNG Post Build |"
|
||||
Write-Output "+===========================================================================================+"
|
||||
Write-Output "+=================================================================+"
|
||||
Write-Output "| Beginning mRemoteNG Post Build |"
|
||||
Write-Output "+=================================================================+"
|
||||
Format-Table -AutoSize -Wrap -InputObject @{
|
||||
"SolutionDir" = $SolutionDir
|
||||
"TargetDir" = $TargetDir
|
||||
@@ -37,25 +37,16 @@ Format-Table -AutoSize -Wrap -InputObject @{
|
||||
"ExcludeFromSigning" = $ExcludeFromSigning
|
||||
}
|
||||
|
||||
# Move dlls resurses into folder
|
||||
#Remove-Item -Path "$TargetDir\libs" -Recurse -ErrorAction Ignore
|
||||
#New-Item -ItemType "directory" -Force -Path $TargetDir -Name "libs"
|
||||
#Move-Item -Path "$TargetDir\*.dll" -Destination "$TargetDir\libs" -force
|
||||
|
||||
|
||||
###
|
||||
|
||||
# Move lang resurses into folder
|
||||
#Remove-Item -Path "$TargetDir\languages" -Recurse -ErrorAction Ignore
|
||||
#New-Item -ItemType "directory" -Force -Path $TargetDir -Name "languages"
|
||||
#"cs-CZ,de,el,en-US,es-AR,es,fr,hu,it,lt,ja-JP,ko-KR,nb-NO,nl,pt,pt-BR,pl,ru,uk,tr-TR,zh-CN,zh-TW,fi-FI".Split(",") | ForEach {
|
||||
# Move-Item -Path "$TargetDir\$_" -Destination "$TargetDir\languages" -force
|
||||
# }
|
||||
###
|
||||
|
||||
& "$PSScriptRoot\copy_puttyng.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
|
||||
& "$PSScriptRoot\copy_themes.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
|
||||
& "$PSScriptRoot\copy_tiles.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
|
||||
& "$PSScriptRoot\sphinx_docs.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
|
||||
& "$PSScriptRoot\set_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName
|
||||
& "$PSScriptRoot\verify_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName
|
||||
& "$PSScriptRoot\tidy_files_for_release.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning -SolutionDir $SolutionDir
|
||||
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath -SolutionDir $SolutionDir
|
||||
& "$PSScriptRoot\zip_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\zip_symbols.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\zip_portable_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
@@ -1,13 +0,0 @@
|
||||
param (
|
||||
[string]
|
||||
$SolutionDir
|
||||
)
|
||||
|
||||
|
||||
$targetVersionedFile = "$SolutionDir\mRemoteNG\bin\x64\Release\mRemoteNG.exe"
|
||||
$version = &"$SolutionDir\Tools\exes\sigcheck.exe" /accepteula -q -n $targetVersionedFile
|
||||
$src = $SolutionDir + "mRemoteNGInstaller\Installer\bin\Release\en-US\mRemoteNG-Installer.msi"
|
||||
$dst = $SolutionDir + "mRemoteNG\bin\x64\Release\mRemoteNG-Installer-" + $version + ".msi"
|
||||
|
||||
# Copy file
|
||||
Copy-Item $src -Destination $dst -Force
|
||||
29
Tools/rename_installer_with_version.ps1
Normal file
29
Tools/rename_installer_with_version.ps1
Normal file
@@ -0,0 +1,29 @@
|
||||
param (
|
||||
[string]
|
||||
$SolutionDir
|
||||
)
|
||||
|
||||
$renameTarget = $SolutionDir + "InstallerProjects\Installer\bin\Release\en-US\mRemoteNG-Installer.msi"
|
||||
|
||||
Write-Host $SolutionDir
|
||||
Write-Host $renameTarget
|
||||
|
||||
$targetVersionedFile = "$SolutionDir\mRemoteNG\bin\Release\mRemoteNG.exe"
|
||||
$version = &"$SolutionDir\Tools\exes\sigcheck.exe" /accepteula -q -n $targetVersionedFile
|
||||
|
||||
|
||||
$renameTargetFileObject = Get-Item -Path $renameTarget -ErrorAction SilentlyContinue
|
||||
if ($renameTargetFileObject)
|
||||
{
|
||||
# Build the new file name
|
||||
$oldFileName = $renameTargetFileObject.Name
|
||||
$newFileName = $oldFileName -replace "$("\"+$renameTargetFileObject.Extension)",$("-"+$version+$renameTargetFileObject.Extension)
|
||||
Write-Host $oldFileName
|
||||
Write-Host $newFileName
|
||||
|
||||
# Delete any items that already exist with the new name (effectively an overwrite)
|
||||
Remove-Item -Path "$($renameTargetFileObject.Directory.FullName)\$newFileName" -ErrorAction SilentlyContinue
|
||||
|
||||
# Rename file
|
||||
Rename-Item -Path $renameTarget -NewName $newFileName -ErrorAction SilentlyContinue
|
||||
}
|
||||
33
Tools/sphinx_docs.ps1
Normal file
33
Tools/sphinx_docs.ps1
Normal file
@@ -0,0 +1,33 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
Write-Output "Building HTML-Documentation with Sphinx"
|
||||
|
||||
$path_HelpFilesDir = Join-Path -Path $TargetDir -ChildPath "Help"
|
||||
$path_SphinxSourceDir = Join-Path -Path $SolutionDir -ChildPath "mRemoteNG\Documentation"
|
||||
|
||||
# Remove stale Help files, if they exist
|
||||
if (Test-Path -Path $path_HelpFilesDir) {
|
||||
Remove-Item -Path $path_HelpFilesDir -Recurse -Force
|
||||
}
|
||||
|
||||
# Build docs
|
||||
sphinx-build $path_SphinxSourceDir $path_HelpFilesDir
|
||||
|
||||
# Place dummy html file if build failed
|
||||
if (-Not (Test-Path $path_HelpFilesDir\index.html -PathType Leaf)) {
|
||||
New-Item -Path $path_HelpFilesDir -ItemType "directory"
|
||||
New-Item $path_HelpFilesDir\index.html
|
||||
Set-Content $path_HelpFilesDir\index.html 'Welcome to mRemoteNG!'
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
@@ -7,15 +7,15 @@ param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
Write-Output ""
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
# Remove unnecessary files from Release versions
|
||||
if ($ConfigurationName -match "Release")
|
||||
{
|
||||
if ($ConfigurationName -match "Release") {
|
||||
Write-Output "Removing unnecessary files from Release versions"
|
||||
|
||||
$test = Join-Path -Path $TargetDir -ChildPath "app.publish"
|
||||
if (Test-Path $test -PathType Container)
|
||||
{
|
||||
if (Test-Path $test -PathType Container) {
|
||||
Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "app.publish") -Recurse -Force
|
||||
}
|
||||
|
||||
@@ -29,18 +29,10 @@ if ($ConfigurationName -match "Release")
|
||||
) -Exclude @(
|
||||
"mRemoteNG.VisualElementsManifest.xml"
|
||||
)
|
||||
if ($filesToDelete)
|
||||
{
|
||||
Write-Output "Unnecessary files are detected and will be removed"
|
||||
Remove-Item -Path $filesToDelete.FullName
|
||||
Write-Output $filesToDelete.FullName
|
||||
} else
|
||||
{
|
||||
Write-Output " No unnecessary files are detected"
|
||||
}
|
||||
Remove-Item -Path $filesToDelete.FullName
|
||||
Write-Output $filesToDelete.FullName
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
Write-Output "We will not remove anything - this is not a release build."
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ param (
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
|
||||
# validate release versions and if the certificate value was passed
|
||||
if ($ConfigurationName -match "Release" -And ($CertificatePath)) {
|
||||
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Write-Output ""
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
$ConfigurationName = $ConfigurationName.Trim()
|
||||
Write-Output "Config Name (trimmed): '$($ConfigurationName)'"
|
||||
$exe = Join-Path -Path $TargetDir -ChildPath $TargetFileName
|
||||
$Version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($exe).FileVersion
|
||||
Write-Output "Version is $($version)"
|
||||
|
||||
# Fix for AppVeyor
|
||||
if(!([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))) {
|
||||
if(!(test-path "Release")) {
|
||||
New-Item -ItemType Directory -Force -Path "Release" | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
# Package debug symbols zip file
|
||||
if ($ConfigurationName -match "Release") {
|
||||
Write-Output "Packaging debug symbols"
|
||||
|
||||
if ($ConfigurationName -match "Portable") {
|
||||
$zipFilePrefix = "mRemoteNG-Portable-symbols"
|
||||
} else {
|
||||
$zipFilePrefix = "mRemoteNG-symbols"
|
||||
}
|
||||
|
||||
$debugFile = Join-Path -Path $TargetDir -ChildPath "mRemoteNG.pdb"
|
||||
|
||||
# AppVeyor build
|
||||
if(!([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))) {
|
||||
$outputZipPath = Join-Path -Path $SolutionDir -ChildPath "Release\$zipFilePrefix-$($version).zip"
|
||||
7z a $outputZipPath $debugFile
|
||||
}
|
||||
# Local build
|
||||
else {
|
||||
if (!(Test-Path -Path $debugFile -PathType Leaf))
|
||||
{
|
||||
$outputZipPath = "$($SolutionDir)Release\$zipFilePrefix-$($version).zip"
|
||||
Compress-Archive $debugFile $outputZipPath -Force
|
||||
} else {
|
||||
write-host "File do not exist:" $debugFile", nothing to compress"
|
||||
}
|
||||
}
|
||||
|
||||
Remove-Item $debugFile
|
||||
}
|
||||
|
||||
# Package portable release zip file
|
||||
if ($ConfigurationName -eq "Release Portable") {
|
||||
Write-Output "Packaging portable ZIP file"
|
||||
|
||||
# AppVeyor build
|
||||
if(!([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))) {
|
||||
$outputZipPath = Join-Path -Path $SolutionDir -ChildPath "Release\mRemoteNG-Portable-$($version).zip"
|
||||
7z a -bt -bd -bb1 -mx=9 -tzip -y -r $outputZipPath $TargetDir\*
|
||||
}
|
||||
# Local build
|
||||
else {
|
||||
if ($Source)
|
||||
{
|
||||
$outputZipPath="$($SolutionDir)\Release\mRemoteNG-Portable-$($version).zip"
|
||||
Compress-Archive $Source $outputZipPath -Force
|
||||
} else {
|
||||
write-host "File do not exist:" $Source", nothing to compress"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
64
Tools/zip_portable_files.ps1
Normal file
64
Tools/zip_portable_files.ps1
Normal file
@@ -0,0 +1,64 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
if(-not [string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {
|
||||
Write-Output "Too early to run via Appveyor - artifacts don't get generated properly. Exiting"
|
||||
Exit
|
||||
}
|
||||
|
||||
Write-Output "Solution Dir: '$($SolutionDir)'"
|
||||
Write-Output "Target Dir: '$($TargetDir)'"
|
||||
$ConfigurationName = $ConfigurationName.Trim()
|
||||
Write-Output "Config Name (tirmmed): '$($ConfigurationName)'"
|
||||
|
||||
|
||||
# Windows Sysinternals Sigcheck from http://technet.microsoft.com/en-us/sysinternals/bb897441
|
||||
$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe"
|
||||
$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe"
|
||||
|
||||
# Package Zip
|
||||
if ($ConfigurationName -eq "Release Portable") {
|
||||
Write-Output "Packaging Release Portable ZIP"
|
||||
|
||||
$version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteNG\bin\$($ConfigurationName)\mRemoteNG.exe"
|
||||
|
||||
Write-Output "Version is $($version)"
|
||||
|
||||
$PortableZip="$($SolutionDir)Release\mRemoteNG-Portable-$($version).zip"
|
||||
|
||||
$tempFolderPath = Join-Path -Path $SolutionDir -ChildPath "mRemoteNG\bin\package"
|
||||
Remove-Item -Recurse $tempFolderPath -ErrorAction SilentlyContinue | Out-Null
|
||||
New-Item $tempFolderPath -ItemType "directory" | Out-Null
|
||||
|
||||
Copy-Item "$($SolutionDir)mRemoteNG\Resources\PuTTYNG.exe" -Destination $tempFolderPath
|
||||
|
||||
#Write-Output "$($SolutionDir)mRemoteNG\bin\$ConfigurationName"
|
||||
#Write-Output "$($SolutionDir)mRemoteNG\bin\package"
|
||||
Copy-Item "$($SolutionDir)mRemoteNG\bin\$ConfigurationName\*" -Destination $tempFolderPath -Recurse -Force
|
||||
# Delete any PDB files that accidentally get copied into the temp folder
|
||||
Get-ChildItem -Path $tempFolderPath -Filter "*.pdb" | Remove-Item
|
||||
Copy-Item "$($SolutionDir)*.txt" -Destination $tempFolderPath
|
||||
|
||||
Write-Output "Creating portable ZIP file $($PortableZip)"
|
||||
Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue
|
||||
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip (Join-Path -Path $tempFolderPath -ChildPath "*.*")
|
||||
#& $SEVENZIP a -bt -mx=9 -tzip -y $PortableZip "$($SolutionDir)*.TXT"
|
||||
}
|
||||
else {
|
||||
Write-Output "We will not zip anything - this isnt a portable release build."
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
56
Tools/zip_symbols.ps1
Normal file
56
Tools/zip_symbols.ps1
Normal file
@@ -0,0 +1,56 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
if(-not [string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {
|
||||
Write-Output "Too early to run via Appveyor - artifacts don't get generated properly. Exiting"
|
||||
Exit
|
||||
}
|
||||
|
||||
Write-Output "Solution Dir: '$($SolutionDir)'"
|
||||
Write-Output "Target Dir: '$($TargetDir)'"
|
||||
$ConfigurationName = $ConfigurationName.Trim()
|
||||
Write-Output "Config Name (trimmed): '$($ConfigurationName)'"
|
||||
|
||||
|
||||
# Windows Sysinternals Sigcheck from http://technet.microsoft.com/en-us/sysinternals/bb897441
|
||||
$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe"
|
||||
$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe"
|
||||
|
||||
# Package Zip
|
||||
if ($ConfigurationName -match "Release") {
|
||||
Write-Output "Packaging debug symbols"
|
||||
|
||||
$version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteNG\bin\$($ConfigurationName)\mRemoteNG.exe"
|
||||
|
||||
Write-Output "Version is $($version)"
|
||||
|
||||
if ($ConfigurationName -match "Portable") {
|
||||
$zipFilePrefix = "mRemoteNG-Portable-symbols"
|
||||
} else {
|
||||
$zipFilePrefix = "mRemoteNG-symbols"
|
||||
}
|
||||
|
||||
$outputZipPath="$($SolutionDir)Release\$zipFilePrefix-$($version).zip"
|
||||
|
||||
Write-Output "Creating debug symbols ZIP file $($outputZipPath)"
|
||||
Remove-Item -Force $outputZipPath -ErrorAction SilentlyContinue
|
||||
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $outputZipPath (Join-Path -Path $TargetDir -ChildPath "*.pdb")
|
||||
}
|
||||
else {
|
||||
Write-Output "We will not package debug symbols - this isnt a release build."
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
177
mRemoteNG.sln
177
mRemoteNG.sln
@@ -1,11 +1,11 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31912.275
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28803.352
|
||||
MinimumVisualStudioVersion = 14.0.25420.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNG", "mRemoteNG\mRemoteNG.csproj", "{4934A491-40BC-4E5B-9166-EA1169A220F6}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mRemoteNG", "mRemoteNG\mRemoteNG.csproj", "{4934A491-40BC-4E5B-9166-EA1169A220F6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNGTests", "mRemoteNGTests\mRemoteNGTests.csproj", "{1453B37F-8621-499E-B0B2-6091F76DC0BB}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mRemoteNGTests", "mRemoteNGTests\mRemoteNGTests.csproj", "{1453B37F-8621-499E-B0B2-6091F76DC0BB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mRemoteNGInstaller", "mRemoteNGInstaller", "{4FE795BE-646E-4F1B-BAD0-A68EA26394DD}"
|
||||
EndProject
|
||||
@@ -16,63 +16,130 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Installer", "mRemoteNGInsta
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04} = {5423D985-CB48-4344-B47F-E8C6D60C8B04}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNGSpecs", "mRemoteNGSpecs\mRemoteNGSpecs.csproj", "{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mRemoteNGSpecs", "mRemoteNGSpecs\mRemoteNGSpecs.csproj", "{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalConnectors", "ExternalConnectors\ExternalConnectors.csproj", "{A56A2029-79B8-492A-ABE5-D2BFE05801BD}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedLibraryNG", "SharedLibraryNG\SharedLibraryNG.csproj", "{0F615504-5F30-4CF2-8341-1DE7FEC95A23}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug Portable|x64 = Debug Portable|x64
|
||||
Debug|x64 = Debug|x64
|
||||
Release Installer|x64 = Release Installer|x64
|
||||
Release Portable|x64 = Release Portable|x64
|
||||
Release|x64 = Release|x64
|
||||
Debug Portable|Any CPU = Debug Portable|Any CPU
|
||||
Debug Portable|x86 = Debug Portable|x86
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release Installer|Any CPU = Release Installer|Any CPU
|
||||
Release Installer|x86 = Release Installer|x86
|
||||
Release Portable|Any CPU = Release Portable|Any CPU
|
||||
Release Portable|x86 = Release Portable|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x64.ActiveCfg = Debug Portable|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x64.Build.0 = Debug Portable|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x64.Build.0 = Debug|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x64.ActiveCfg = Release|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x64.Build.0 = Release|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x64.ActiveCfg = Release Portable|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x64.Build.0 = Release Portable|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x64.ActiveCfg = Release|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x64.Build.0 = Release|x64
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x64.ActiveCfg = Debug Portable|x64
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x64.ActiveCfg = Release|x64
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x64.ActiveCfg = Release Portable|x64
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x64.Build.0 = Release Portable|x64
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x64.ActiveCfg = Release|x64
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x64.Build.0 = Release|x64
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|x64.ActiveCfg = Debug Portable|x64
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x64.ActiveCfg = Release|x64
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x64.Build.0 = Release|x64
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Portable|x64.ActiveCfg = Release Portable|x64
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x64.ActiveCfg = Release|x64
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|x64.ActiveCfg = Debug Portable|x64
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x64.ActiveCfg = Release|x64
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x64.Build.0 = Release|x64
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|x64.ActiveCfg = Release Portable|x64
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|x64.ActiveCfg = Release|x64
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|x64.ActiveCfg = Debug Portable|x64
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|x64.ActiveCfg = Release|x64
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|x64.ActiveCfg = Release Portable|x64
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|x64.ActiveCfg = Release|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug Portable|x64.ActiveCfg = Debug Portable|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug Portable|x64.Build.0 = Debug Portable|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|x64.Build.0 = Debug|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer|x64.ActiveCfg = Release|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer|x64.Build.0 = Release|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Portable|x64.ActiveCfg = Release Portable|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Portable|x64.Build.0 = Release Portable|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|x64.ActiveCfg = Release|x64
|
||||
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|x64.Build.0 = Release|x64
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.Build.0 = Debug Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.Build.0 = Debug|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.ActiveCfg = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.Build.0 = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.Build.0 = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|Any CPU.Build.0 = Release Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.ActiveCfg = Release Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.Build.0 = Release Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|Any CPU.Build.0 = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.ActiveCfg = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.Build.0 = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.Build.0 = Debug Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.Build.0 = Debug|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.ActiveCfg = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.Build.0 = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.Build.0 = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|Any CPU.Build.0 = Release Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.ActiveCfg = Release Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.Build.0 = Release Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|Any CPU.Build.0 = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.ActiveCfg = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.Build.0 = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.ActiveCfg = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.Build.0 = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|x86.ActiveCfg = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.Build.0 = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|Any CPU.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|Any CPU.Build.0 = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x86.Build.0 = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Portable|Any CPU.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Portable|x86.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|Any CPU.Build.0 = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x86.ActiveCfg = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.ActiveCfg = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.Build.0 = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.Build.0 = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|x86.ActiveCfg = Release Portable|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|x86.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|Any CPU.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|Any CPU.Build.0 = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|x86.ActiveCfg = Debug|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|x86.Build.0 = Debug|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x86.Build.0 = Debug|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|Any CPU.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|Any CPU.Build.0 = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|x86.Build.0 = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|Any CPU.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|Any CPU.Build.0 = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|x86.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|x86.Build.0 = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|x86.ActiveCfg = Release|x86
|
||||
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|x86.Build.0 = Release|x86
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug Portable|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug Portable|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug Portable|x86.ActiveCfg = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug Portable|x86.Build.0 = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Installer|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Installer|Any CPU.Build.0 = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Installer|x86.ActiveCfg = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Installer|x86.Build.0 = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Portable|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Portable|Any CPU.Build.0 = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Portable|x86.ActiveCfg = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Portable|x86.Build.0 = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -5,9 +5,9 @@ using Microsoft.Win32;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Properties;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.UI.TaskDialog;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
namespace mRemoteNG.App
|
||||
{
|
||||
|
||||
@@ -6,8 +6,8 @@ using mRemoteNG.Config.Import;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.App
|
||||
{
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace mRemoteNG.App.Info
|
||||
namespace mRemoteNG.App.Info
|
||||
{
|
||||
public static class ConnectionsFileInfo
|
||||
{
|
||||
public static readonly string DefaultConnectionsPath = SettingsFileInfo.SettingsPath;
|
||||
public static readonly string DefaultConnectionsFile = "confCons.xml";
|
||||
public static readonly string DefaultConnectionsFileNew = "confConsNew.xml";
|
||||
public static readonly Version ConnectionFileVersion = new Version(2, 9);
|
||||
public static readonly double ConnectionFileVersion = 2.8;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ namespace mRemoteNG.App.Info
|
||||
public const string UrlDonate = "https://mremoteng.org/contribute";
|
||||
public const string UrlForum = "https://www.reddit.com/r/mRemoteNG";
|
||||
public const string UrlBugs = "https://bugs.mremoteng.org";
|
||||
public const string UrlDocumentation = "https://mremoteng.readthedocs.io/en/latest/";
|
||||
public static string ApplicationVersion = Application.ProductVersion;
|
||||
public static readonly string ProductName = Application.ProductName;
|
||||
|
||||
|
||||
@@ -8,16 +8,17 @@ namespace mRemoteNG.App.Info
|
||||
public static class UpdateChannelInfo
|
||||
{
|
||||
public const string STABLE = "Stable";
|
||||
public const string PREVIEW = "Preview";
|
||||
public const string NIGHTLY = "Nightly";
|
||||
public const string BETA = "Beta";
|
||||
public const string DEV = "Development";
|
||||
|
||||
/* no #if here since they are used for unit tests as well */
|
||||
public const string STABLE_PORTABLE = "update-portable.txt";
|
||||
public const string PREVIEW_PORTABLE = "preview-update-portable.txt";
|
||||
public const string NIGHTLY_PORTABLE = "nightly-update-portable.txt";
|
||||
public const string BETA_PORTABLE = "beta-update-portable.txt";
|
||||
public const string DEV_PORTABLE = "dev-update-portable.txt";
|
||||
|
||||
public const string STABLE_MSI = "update.txt";
|
||||
public const string PREVIEW_MSI = "preview-update.txt";
|
||||
public const string NIGHTLY_MSI = "nightly-update.txt";
|
||||
public const string BETA_MSI = "beta-update.txt";
|
||||
public const string DEV_MSI = "dev-update.txt";
|
||||
|
||||
|
||||
public static Uri GetUpdateChannelInfo()
|
||||
@@ -39,10 +40,10 @@ namespace mRemoteNG.App.Info
|
||||
{
|
||||
case STABLE:
|
||||
return STABLE_MSI;
|
||||
case PREVIEW:
|
||||
return PREVIEW_MSI;
|
||||
case NIGHTLY:
|
||||
return NIGHTLY_MSI;
|
||||
case BETA:
|
||||
return BETA_MSI;
|
||||
case DEV:
|
||||
return DEV_MSI;
|
||||
default:
|
||||
return STABLE_MSI;
|
||||
}
|
||||
@@ -54,10 +55,10 @@ namespace mRemoteNG.App.Info
|
||||
{
|
||||
case STABLE:
|
||||
return STABLE_PORTABLE;
|
||||
case PREVIEW:
|
||||
return PREVIEW_PORTABLE;
|
||||
case NIGHTLY:
|
||||
return NIGHTLY_PORTABLE;
|
||||
case BETA:
|
||||
return BETA_PORTABLE;
|
||||
case DEV:
|
||||
return DEV_PORTABLE;
|
||||
default:
|
||||
return STABLE_PORTABLE;
|
||||
}
|
||||
@@ -71,7 +72,7 @@ namespace mRemoteNG.App.Info
|
||||
|
||||
private static bool IsValidChannel(string s)
|
||||
{
|
||||
return s.Equals(STABLE) || s.Equals(PREVIEW) || s.Equals(NIGHTLY);
|
||||
return s.Equals(STABLE) || s.Equals(BETA) || s.Equals(DEV);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using log4net.Appender;
|
||||
@@ -36,7 +35,6 @@ namespace mRemoteNG.App
|
||||
public void SetLogPath(string path)
|
||||
{
|
||||
var repository = LogManager.GetRepository("mRemoteNG");
|
||||
XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
|
||||
var appenders = repository.GetAppenders();
|
||||
|
||||
foreach (var appender in appenders)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -71,12 +71,6 @@ namespace mRemoteNG.App
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
|
||||
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern bool ChangeClipboardChain(
|
||||
IntPtr hWndRemove, // handle to window to remove
|
||||
IntPtr hWndNewNext // handle to next window
|
||||
);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
@@ -112,6 +106,7 @@ namespace mRemoteNG.App
|
||||
internal static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
|
||||
|
||||
[DllImport("kernel32", SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static extern bool CloseHandle(IntPtr handle);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -102,10 +102,6 @@ namespace mRemoteNG.App
|
||||
if (Settings.Default.UseSQLServer)
|
||||
{
|
||||
ConnectionsService.LastSqlUpdate = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectionsService.LastFileUpdate = System.IO.File.GetLastWriteTime(connectionFileName);
|
||||
}
|
||||
|
||||
// re-enable sql update checking after updates are loaded
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Config.Connections;
|
||||
using mRemoteNG.Config.Putty;
|
||||
using mRemoteNG.Properties;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
// ReSharper disable ArrangeAccessorOwnerBody
|
||||
|
||||
@@ -61,34 +60,8 @@ namespace mRemoteNG.App
|
||||
|
||||
private static void SaveConnections()
|
||||
{
|
||||
DateTime lastUpdate;
|
||||
DateTime updateDate;
|
||||
DateTime currentDate = DateTime.Now;
|
||||
|
||||
//OBSOLETE: Settings.Default.SaveConsOnExit is obsolete and should be removed in a future release
|
||||
if (Settings.Default.SaveConsOnExit || (Settings.Default.SaveConnectionsFrequency == (int)ConnectionsBackupFrequencyEnum.OnExit))
|
||||
{
|
||||
if (Settings.Default.SaveConsOnExit)
|
||||
Runtime.ConnectionsService.SaveConnections();
|
||||
return;
|
||||
}
|
||||
lastUpdate = Runtime.ConnectionsService.UsingDatabase ? Runtime.ConnectionsService.LastSqlUpdate : Runtime.ConnectionsService.LastFileUpdate;
|
||||
|
||||
switch (Settings.Default.SaveConnectionsFrequency)
|
||||
{
|
||||
case (int)ConnectionsBackupFrequencyEnum.Daily:
|
||||
updateDate = lastUpdate.AddDays(1);
|
||||
break;
|
||||
case (int)ConnectionsBackupFrequencyEnum.Weekly:
|
||||
updateDate = lastUpdate.AddDays(7);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentDate >= updateDate)
|
||||
{
|
||||
Runtime.ConnectionsService.SaveConnections();
|
||||
}
|
||||
}
|
||||
|
||||
private static void SaveSettings(Control quickConnectToolStrip,
|
||||
@@ -120,7 +93,7 @@ namespace mRemoteNG.App
|
||||
private static void RunUpdateFile()
|
||||
{
|
||||
if (UpdatePending)
|
||||
Process.Start(new ProcessStartInfo(_updateFilePath) { UseShellExecute = true });
|
||||
Process.Start(_updateFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.App.Initialization;
|
||||
using mRemoteNG.App.Update;
|
||||
@@ -66,7 +65,7 @@ namespace mRemoteNG.App
|
||||
Runtime.ConnectionsService.RemoteConnectionsSyncronizer.Enable();
|
||||
}
|
||||
|
||||
public async Task CheckForUpdate()
|
||||
public void CheckForUpdate()
|
||||
{
|
||||
if (_appUpdate == null)
|
||||
{
|
||||
@@ -88,9 +87,32 @@ namespace mRemoteNG.App
|
||||
return;
|
||||
}
|
||||
|
||||
_appUpdate.GetUpdateInfoCompletedEvent += GetUpdateInfoCompleted;
|
||||
_appUpdate.GetUpdateInfoAsync();
|
||||
}
|
||||
|
||||
private void GetUpdateInfoCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
if (_frmMain.InvokeRequired)
|
||||
{
|
||||
_frmMain.Invoke(new AsyncCompletedEventHandler(GetUpdateInfoCompleted), sender, e);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _appUpdate.GetUpdateInfoAsync();
|
||||
_appUpdate.GetUpdateInfoCompletedEvent -= GetUpdateInfoCompleted;
|
||||
|
||||
if (e.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Error != null)
|
||||
{
|
||||
throw e.Error;
|
||||
}
|
||||
|
||||
if (_appUpdate.IsUpdateAvailable())
|
||||
{
|
||||
Windows.Show(WindowType.Update);
|
||||
@@ -98,7 +120,7 @@ namespace mRemoteNG.App
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("CheckForUpdate() failed.", ex);
|
||||
Runtime.MessageCollector.AddExceptionMessage("GetUpdateInfoCompleted() failed.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
using mRemoteNG.Properties;
|
||||
#if !PORTABLE
|
||||
using mRemoteNG.Tools;
|
||||
@@ -21,30 +21,29 @@ namespace mRemoteNG.App.Update
|
||||
{
|
||||
public class AppUpdater
|
||||
{
|
||||
private const int _bufferLength = 8192;
|
||||
private WebProxy _webProxy;
|
||||
private HttpClient _httpClient;
|
||||
private CancellationTokenSource _changeLogCancelToken;
|
||||
private CancellationTokenSource _getUpdateInfoCancelToken;
|
||||
private Thread _getUpdateInfoThread;
|
||||
private Thread _getChangeLogThread;
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public UpdateInfo CurrentUpdateInfo { get; private set; }
|
||||
|
||||
public string ChangeLog { get; private set; }
|
||||
|
||||
public bool IsGetUpdateInfoRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
return _getUpdateInfoCancelToken != null;
|
||||
}
|
||||
get { return _getUpdateInfoThread != null && _getUpdateInfoThread.IsAlive; }
|
||||
}
|
||||
|
||||
private bool IsGetChangeLogRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
return _changeLogCancelToken != null;
|
||||
}
|
||||
get { return _getChangeLogThread != null && _getChangeLogThread.IsAlive; }
|
||||
}
|
||||
|
||||
public bool IsDownloadUpdateRunning
|
||||
{
|
||||
get { return _downloadUpdateWebClient != null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -53,10 +52,10 @@ namespace mRemoteNG.App.Update
|
||||
|
||||
public AppUpdater()
|
||||
{
|
||||
SetDefaultProxySettings();
|
||||
SetProxySettings();
|
||||
}
|
||||
|
||||
private void SetDefaultProxySettings()
|
||||
private void SetProxySettings()
|
||||
{
|
||||
var shouldWeUseProxy = Settings.Default.UpdateUseProxy;
|
||||
var proxyAddress = Settings.Default.UpdateProxyAddress;
|
||||
@@ -79,14 +78,13 @@ namespace mRemoteNG.App.Update
|
||||
if (useProxy && !string.IsNullOrEmpty(address))
|
||||
{
|
||||
_webProxy = port != 0 ? new WebProxy(address, port) : new WebProxy(address);
|
||||
|
||||
_webProxy.Credentials = useAuthentication ? new NetworkCredential(username, password) : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_webProxy = null;
|
||||
}
|
||||
|
||||
UpdateHttpClient();
|
||||
}
|
||||
|
||||
public bool IsUpdateAvailable()
|
||||
@@ -98,24 +96,54 @@ namespace mRemoteNG.App.Update
|
||||
|
||||
return CurrentUpdateInfo.Version > GeneralAppInfo.GetApplicationVersion();
|
||||
}
|
||||
|
||||
public async Task DownloadUpdateAsync(IProgress<int> progress)
|
||||
|
||||
public void GetUpdateInfoAsync()
|
||||
{
|
||||
if (IsGetUpdateInfoRunning)
|
||||
{
|
||||
_getUpdateInfoCancelToken.Cancel();
|
||||
_getUpdateInfoCancelToken.Dispose();
|
||||
_getUpdateInfoCancelToken = null;
|
||||
_getUpdateInfoThread.Abort();
|
||||
}
|
||||
|
||||
_getUpdateInfoThread = new Thread(GetUpdateInfo);
|
||||
_getUpdateInfoThread.SetApartmentState(ApartmentState.STA);
|
||||
_getUpdateInfoThread.IsBackground = true;
|
||||
_getUpdateInfoThread.Start();
|
||||
}
|
||||
|
||||
public void GetChangeLogAsync()
|
||||
{
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling GetChangeLogAsync().");
|
||||
}
|
||||
|
||||
if (IsGetChangeLogRunning)
|
||||
{
|
||||
_getChangeLogThread.Abort();
|
||||
}
|
||||
|
||||
_getChangeLogThread = new Thread(GetChangeLog);
|
||||
_getChangeLogThread.SetApartmentState(ApartmentState.STA);
|
||||
_getChangeLogThread.IsBackground = true;
|
||||
_getChangeLogThread.Start();
|
||||
}
|
||||
|
||||
public void DownloadUpdateAsync()
|
||||
{
|
||||
if (_downloadUpdateWebClient != null)
|
||||
{
|
||||
throw new InvalidOperationException("A previous call to DownloadUpdateAsync() is still in progress.");
|
||||
}
|
||||
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync().");
|
||||
throw new InvalidOperationException(
|
||||
"CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync().");
|
||||
}
|
||||
#if !PORTABLE
|
||||
CurrentUpdateInfo.UpdateFilePath = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi"));
|
||||
CurrentUpdateInfo.UpdateFilePath =
|
||||
Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi"));
|
||||
#else
|
||||
var sfd = new SaveFileDialog
|
||||
{
|
||||
@@ -132,38 +160,135 @@ namespace mRemoteNG.App.Update
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
try
|
||||
DownloadUpdateWebClient.DownloadFileAsync(CurrentUpdateInfo.DownloadAddress,
|
||||
CurrentUpdateInfo.UpdateFilePath);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private WebClient _downloadUpdateWebClient;
|
||||
|
||||
private WebClient DownloadUpdateWebClient
|
||||
{
|
||||
get
|
||||
{
|
||||
_getUpdateInfoCancelToken = new CancellationTokenSource();
|
||||
using var response = await _httpClient.GetAsync(CurrentUpdateInfo.DownloadAddress, HttpCompletionOption.ResponseHeadersRead, _getUpdateInfoCancelToken.Token);
|
||||
var buffer = new byte[_bufferLength];
|
||||
var totalBytes = response.Content.Headers.ContentLength ?? 0;
|
||||
var readBytes = 0L;
|
||||
|
||||
await using (var httpStream = await response.Content.ReadAsStreamAsync(_getUpdateInfoCancelToken.Token))
|
||||
if (_downloadUpdateWebClient != null)
|
||||
{
|
||||
await using var fileStream = new FileStream(CurrentUpdateInfo.UpdateFilePath, FileMode.Create,
|
||||
FileAccess.Write, FileShare.None, _bufferLength, true);
|
||||
|
||||
while (readBytes <= totalBytes || !_getUpdateInfoCancelToken.IsCancellationRequested)
|
||||
{
|
||||
var bytesRead =
|
||||
await httpStream.ReadAsync(buffer, 0, _bufferLength, _getUpdateInfoCancelToken.Token);
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
progress.Report(100);
|
||||
break;
|
||||
}
|
||||
|
||||
await fileStream.WriteAsync(buffer, 0, bytesRead, _getUpdateInfoCancelToken.Token);
|
||||
|
||||
readBytes += bytesRead;
|
||||
|
||||
var percentComplete = (int)(readBytes * 100 / totalBytes);
|
||||
progress.Report(percentComplete);
|
||||
}
|
||||
return _downloadUpdateWebClient;
|
||||
}
|
||||
|
||||
_downloadUpdateWebClient = CreateWebClient();
|
||||
|
||||
_downloadUpdateWebClient.DownloadProgressChanged += DownloadUpdateProgressChanged;
|
||||
_downloadUpdateWebClient.DownloadFileCompleted += DownloadUpdateCompleted;
|
||||
|
||||
return _downloadUpdateWebClient;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private WebClient CreateWebClient()
|
||||
{
|
||||
var webClient = new WebClient();
|
||||
webClient.Headers.Add("user-agent", GeneralAppInfo.UserAgent);
|
||||
webClient.Proxy = _webProxy;
|
||||
return webClient;
|
||||
}
|
||||
|
||||
private static DownloadStringCompletedEventArgs NewDownloadStringCompletedEventArgs(string result,
|
||||
Exception exception,
|
||||
bool cancelled,
|
||||
object userToken)
|
||||
{
|
||||
var type = typeof(DownloadStringCompletedEventArgs);
|
||||
const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
Type[] argumentTypes = {typeof(string), typeof(Exception), typeof(bool), typeof(object)};
|
||||
var constructor = type.GetConstructor(bindingFlags, null, argumentTypes, null);
|
||||
object[] arguments = {result, exception, cancelled, userToken};
|
||||
|
||||
if (constructor == null)
|
||||
return null;
|
||||
return (DownloadStringCompletedEventArgs)constructor.Invoke(arguments);
|
||||
}
|
||||
|
||||
private DownloadStringCompletedEventArgs DownloadString(Uri address)
|
||||
{
|
||||
var webClient = CreateWebClient();
|
||||
var result = string.Empty;
|
||||
Exception exception = null;
|
||||
var cancelled = false;
|
||||
|
||||
try
|
||||
{
|
||||
result = webClient.DownloadString(address);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
cancelled = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
|
||||
return NewDownloadStringCompletedEventArgs(result, exception, cancelled, null);
|
||||
}
|
||||
|
||||
private void GetUpdateInfo()
|
||||
{
|
||||
var e = DownloadString(UpdateChannelInfo.GetUpdateChannelInfo());
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
CurrentUpdateInfo = UpdateInfo.FromString(e.Result);
|
||||
|
||||
Settings.Default.CheckForUpdatesLastCheck = DateTime.UtcNow;
|
||||
if (!Settings.Default.UpdatePending)
|
||||
{
|
||||
Settings.Default.UpdatePending = IsUpdateAvailable();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
e = NewDownloadStringCompletedEventArgs(e.Result, ex, e.Cancelled, null);
|
||||
}
|
||||
}
|
||||
|
||||
GetUpdateInfoCompletedEventEvent?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void GetChangeLog()
|
||||
{
|
||||
var e = DownloadString(CurrentUpdateInfo.ChangeLogAddress);
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
ChangeLog = e.Result;
|
||||
}
|
||||
|
||||
GetChangeLogCompletedEventEvent?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void DownloadUpdateProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||
{
|
||||
DownloadUpdateProgressChangedEventEvent?.Invoke(sender, e);
|
||||
}
|
||||
|
||||
private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
var raiseEventArgs = e;
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
#if !PORTABLE
|
||||
var updateAuthenticode = new Authenticode(CurrentUpdateInfo.UpdateFilePath)
|
||||
{
|
||||
@@ -182,85 +307,101 @@ namespace mRemoteNG.App.Update
|
||||
}
|
||||
#endif
|
||||
|
||||
using var checksum = SHA512.Create();
|
||||
await using var stream = File.OpenRead(CurrentUpdateInfo.UpdateFilePath);
|
||||
var hash = await checksum.ComputeHashAsync(stream);
|
||||
var hashString = BitConverter.ToString(hash).Replace("-", "").ToUpperInvariant();
|
||||
if (!hashString.Equals(CurrentUpdateInfo.Checksum))
|
||||
throw new Exception("SHA512 Hashes didn't match!");
|
||||
} finally{
|
||||
_getUpdateInfoCancelToken?.Dispose();
|
||||
_getUpdateInfoCancelToken = null;
|
||||
using (var cksum = SHA512.Create())
|
||||
{
|
||||
using (var stream = File.OpenRead(CurrentUpdateInfo.UpdateFilePath))
|
||||
{
|
||||
var hash = cksum.ComputeHash(stream);
|
||||
var hashString = BitConverter.ToString(hash).Replace("-", "").ToUpperInvariant();
|
||||
if (!hashString.Equals(CurrentUpdateInfo.Checksum))
|
||||
throw new Exception("SHA512 Hashes didn't match!");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
raiseEventArgs = new AsyncCompletedEventArgs(ex, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEventArgs.Cancelled || raiseEventArgs.Error != null)
|
||||
{
|
||||
File.Delete(CurrentUpdateInfo.UpdateFilePath);
|
||||
}
|
||||
|
||||
DownloadUpdateCompletedEventEvent?.Invoke(this, raiseEventArgs);
|
||||
|
||||
_downloadUpdateWebClient.Dispose();
|
||||
_downloadUpdateWebClient = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
#region Events
|
||||
|
||||
private void UpdateHttpClient()
|
||||
private AsyncCompletedEventHandler GetUpdateInfoCompletedEventEvent;
|
||||
|
||||
public event AsyncCompletedEventHandler GetUpdateInfoCompletedEvent
|
||||
{
|
||||
if (_httpClient != null)
|
||||
add
|
||||
{
|
||||
_httpClient.Dispose();
|
||||
GetUpdateInfoCompletedEventEvent =
|
||||
(AsyncCompletedEventHandler)Delegate.Combine(GetUpdateInfoCompletedEventEvent, value);
|
||||
}
|
||||
|
||||
var httpClientHandler = new HttpClientHandler();
|
||||
if (_webProxy != null)
|
||||
remove
|
||||
{
|
||||
httpClientHandler.UseProxy = true;
|
||||
httpClientHandler.Proxy = _webProxy;
|
||||
}
|
||||
_httpClient = new HttpClient(httpClientHandler);
|
||||
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(GeneralAppInfo.UserAgent);
|
||||
}
|
||||
|
||||
public async Task GetUpdateInfoAsync()
|
||||
{
|
||||
if (IsGetUpdateInfoRunning)
|
||||
{
|
||||
_getUpdateInfoCancelToken.Cancel();
|
||||
_getUpdateInfoCancelToken.Dispose();
|
||||
_getUpdateInfoCancelToken = null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_getUpdateInfoCancelToken = new CancellationTokenSource();
|
||||
var updateInfo = await _httpClient.GetStringAsync(UpdateChannelInfo.GetUpdateChannelInfo(), _getUpdateInfoCancelToken.Token);
|
||||
CurrentUpdateInfo = UpdateInfo.FromString(updateInfo);
|
||||
Settings.Default.CheckForUpdatesLastCheck = DateTime.UtcNow;
|
||||
|
||||
if (!Settings.Default.UpdatePending)
|
||||
{
|
||||
Settings.Default.UpdatePending = IsUpdateAvailable();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_getUpdateInfoCancelToken?.Dispose();
|
||||
_getUpdateInfoCancelToken = null;
|
||||
GetUpdateInfoCompletedEventEvent =
|
||||
(AsyncCompletedEventHandler)Delegate.Remove(GetUpdateInfoCompletedEventEvent, value);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetChangeLogAsync()
|
||||
{
|
||||
if (IsGetChangeLogRunning)
|
||||
{
|
||||
_changeLogCancelToken.Cancel();
|
||||
_changeLogCancelToken.Dispose();
|
||||
_changeLogCancelToken = null;
|
||||
}
|
||||
private AsyncCompletedEventHandler GetChangeLogCompletedEventEvent;
|
||||
|
||||
try
|
||||
public event AsyncCompletedEventHandler GetChangeLogCompletedEvent
|
||||
{
|
||||
add
|
||||
{
|
||||
_changeLogCancelToken = new CancellationTokenSource();
|
||||
return await _httpClient.GetStringAsync(CurrentUpdateInfo.ChangeLogAddress, _changeLogCancelToken.Token);
|
||||
GetChangeLogCompletedEventEvent =
|
||||
(AsyncCompletedEventHandler)Delegate.Combine(GetChangeLogCompletedEventEvent, value);
|
||||
}
|
||||
finally
|
||||
remove
|
||||
{
|
||||
_changeLogCancelToken?.Dispose();
|
||||
_changeLogCancelToken = null;
|
||||
GetChangeLogCompletedEventEvent =
|
||||
(AsyncCompletedEventHandler)Delegate.Remove(GetChangeLogCompletedEventEvent, value);
|
||||
}
|
||||
}
|
||||
|
||||
private DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEventEvent;
|
||||
|
||||
public event DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEvent
|
||||
{
|
||||
add
|
||||
{
|
||||
DownloadUpdateProgressChangedEventEvent =
|
||||
(DownloadProgressChangedEventHandler)Delegate.Combine(DownloadUpdateProgressChangedEventEvent,
|
||||
value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
DownloadUpdateProgressChangedEventEvent =
|
||||
(DownloadProgressChangedEventHandler)Delegate.Remove(DownloadUpdateProgressChangedEventEvent,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
private AsyncCompletedEventHandler DownloadUpdateCompletedEventEvent;
|
||||
|
||||
public event AsyncCompletedEventHandler DownloadUpdateCompletedEvent
|
||||
{
|
||||
add
|
||||
{
|
||||
DownloadUpdateCompletedEventEvent =
|
||||
(AsyncCompletedEventHandler)Delegate.Combine(DownloadUpdateCompletedEventEvent, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
DownloadUpdateCompletedEventEvent =
|
||||
(AsyncCompletedEventHandler)Delegate.Remove(DownloadUpdateCompletedEventEvent, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@ namespace mRemoteNG.App
|
||||
public static class Windows
|
||||
{
|
||||
private static ActiveDirectoryImportWindow _adimportForm;
|
||||
private static HelpWindow _helpForm;
|
||||
private static ExternalToolsWindow _externalappsForm;
|
||||
private static PortScanWindow _portscanForm;
|
||||
private static ScreenshotManagerWindow _screenshotmanagerForm;
|
||||
private static UltraVNCWindow _ultravncscForm;
|
||||
private static ConnectionTreeWindow _treeForm;
|
||||
|
||||
@@ -21,6 +23,7 @@ namespace mRemoteNG.App
|
||||
|
||||
internal static ConfigWindow ConfigForm { get; set; } = new ConfigWindow();
|
||||
internal static ErrorAndInfoWindow ErrorsForm { get; set; } = new ErrorAndInfoWindow();
|
||||
internal static ScreenshotManagerWindow ScreenshotForm { get; set; } = new ScreenshotManagerWindow();
|
||||
private static UpdateWindow UpdateForm { get; set; } = new UpdateWindow();
|
||||
internal static SSHTransferWindow SshtransferForm { get; private set; } = new SSHTransferWindow();
|
||||
|
||||
@@ -55,6 +58,11 @@ namespace mRemoteNG.App
|
||||
UpdateForm = new UpdateWindow();
|
||||
UpdateForm.Show(dockPanel);
|
||||
break;
|
||||
case WindowType.Help:
|
||||
if (_helpForm == null || _helpForm.IsDisposed)
|
||||
_helpForm = new HelpWindow();
|
||||
_helpForm.Show(dockPanel);
|
||||
break;
|
||||
case WindowType.ExternalApps:
|
||||
if (_externalappsForm == null || _externalappsForm.IsDisposed)
|
||||
_externalappsForm = new ExternalToolsWindow();
|
||||
@@ -64,6 +72,10 @@ namespace mRemoteNG.App
|
||||
_portscanForm = new PortScanWindow();
|
||||
_portscanForm.Show(dockPanel);
|
||||
break;
|
||||
case WindowType.ScreenshotManager:
|
||||
_screenshotmanagerForm = new ScreenshotManagerWindow();
|
||||
_screenshotmanagerForm.Show(dockPanel);
|
||||
break;
|
||||
case WindowType.UltraVNCSC:
|
||||
if (_ultravncscForm == null || _ultravncscForm.IsDisposed)
|
||||
_ultravncscForm = new UltraVNCWindow();
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public enum ConnectionsBackupFrequencyEnum
|
||||
{
|
||||
Unassigned = 0,
|
||||
Never = 1,
|
||||
OnEdit = 2,
|
||||
OnExit = 3,
|
||||
Daily = 4,
|
||||
Weekly = 5,
|
||||
Custom = 6
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
|
||||
{
|
||||
public class RemoteConnectionsSyncronizer : IConnectionsUpdateChecker
|
||||
{
|
||||
private readonly System.Timers.Timer _updateTimer;
|
||||
private readonly Timer _updateTimer;
|
||||
private readonly IConnectionsUpdateChecker _updateChecker;
|
||||
|
||||
public double TimerIntervalInMilliseconds
|
||||
@@ -19,7 +19,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
|
||||
public RemoteConnectionsSyncronizer(IConnectionsUpdateChecker updateChecker)
|
||||
{
|
||||
_updateChecker = updateChecker;
|
||||
_updateTimer = new System.Timers.Timer(3000);
|
||||
_updateTimer = new Timer(3000);
|
||||
SetEventListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.Properties;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
@@ -49,14 +48,12 @@ namespace mRemoteNG.Config.Connections
|
||||
|
||||
private void SaveConnectionOnEdit(string propertyName = "")
|
||||
{
|
||||
//OBSOLETE: mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit is obsolete and should be removed in a future release
|
||||
if (mRemoteNG.Properties.Settings.Default.SaveConnectionsAfterEveryEdit || (mRemoteNG.Properties.Settings.Default.SaveConnectionsFrequency == (int)ConnectionsBackupFrequencyEnum.OnEdit))
|
||||
{
|
||||
if (FrmMain.Default.IsClosing)
|
||||
return;
|
||||
if (!Properties.Settings.Default.SaveConnectionsAfterEveryEdit)
|
||||
return;
|
||||
if (FrmMain.Default.IsClosing)
|
||||
return;
|
||||
|
||||
_connectionsService.SaveConnectionsAsync(propertyName);
|
||||
}
|
||||
_connectionsService.SaveConnectionsAsync(propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,12 @@ using mRemoteNG.Config.Serializers.Versioning;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
@@ -140,9 +140,9 @@ namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
dbQuery =
|
||||
databaseConnector.DbCommand(
|
||||
"INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES('" +
|
||||
MiscTools.PrepareValueForDB(rootTreeNode.Name) + "', 0, '" + strProtected + "','" +
|
||||
ConnectionsFileInfo.ConnectionFileVersion.ToString() + "')");
|
||||
"INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES(\'" +
|
||||
MiscTools.PrepareValueForDB(rootTreeNode.Name) + "\', 0, \'" + strProtected + "\'," +
|
||||
ConnectionsFileInfo.ConnectionFileVersion.ToString(CultureInfo.InvariantCulture) + ")");
|
||||
dbQuery.ExecuteNonQuery();
|
||||
}
|
||||
else
|
||||
@@ -172,7 +172,7 @@ namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
var dbQuery = databaseConnector.DbCommand("DELETE FROM tblUpdate");
|
||||
dbQuery.ExecuteNonQuery();
|
||||
dbQuery = databaseConnector.DbCommand("INSERT INTO tblUpdate (LastUpdate) VALUES('" + MiscTools.DBDate(DateTime.Now) + "')");
|
||||
dbQuery = databaseConnector.DbCommand("INSERT INTO tblUpdate (LastUpdate) VALUES(\'" + MiscTools.DBDate(DateTime.Now) + "\')");
|
||||
dbQuery.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
|
||||
@@ -53,26 +53,12 @@ namespace mRemoteNG.Config.DatabaseConnectors
|
||||
|
||||
private void BuildDbConnectionStringWithCustomCredentials()
|
||||
{
|
||||
string[] hostParts = _dbHost.Split(new char[] { ':' }, 2);
|
||||
var _dbPort = (hostParts.Length == 2) ? hostParts[1] : "1433";
|
||||
|
||||
_dbConnectionString = new SqlConnectionStringBuilder
|
||||
{
|
||||
DataSource = $"{hostParts[0]},{_dbPort}",
|
||||
InitialCatalog = _dbCatalog,
|
||||
UserID = _dbUsername,
|
||||
Password = _dbPassword,
|
||||
}.ToString();
|
||||
_dbConnectionString = $"Data Source={_dbHost};Initial Catalog={_dbCatalog};User Id={_dbUsername};Password={_dbPassword}";
|
||||
}
|
||||
|
||||
private void BuildDbConnectionStringWithDefaultCredentials()
|
||||
{
|
||||
_dbConnectionString = new SqlConnectionStringBuilder
|
||||
{
|
||||
DataSource = _dbHost,
|
||||
InitialCatalog = _dbCatalog,
|
||||
IntegratedSecurity = true
|
||||
}.ToString();
|
||||
_dbConnectionString = $"Data Source={_dbHost};Initial Catalog={_dbCatalog};Integrated Security=True";
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
|
||||
@@ -101,10 +101,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
? connectionCsv[headers.IndexOf("Panel")]
|
||||
: "";
|
||||
|
||||
connectionRecord.Username = headers.Contains("UserViaAPI")
|
||||
? connectionCsv[headers.IndexOf("UserViaAPI")]
|
||||
: "";
|
||||
|
||||
connectionRecord.Username = headers.Contains("Username")
|
||||
? connectionCsv[headers.IndexOf("Username")]
|
||||
: "";
|
||||
@@ -140,10 +136,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
? connectionCsv[headers.IndexOf("LoadBalanceInfo")]
|
||||
: "";
|
||||
|
||||
connectionRecord.OpeningCommand = headers.Contains("OpeningCommand")
|
||||
? connectionCsv[headers.IndexOf("OpeningCommand")]
|
||||
: "";
|
||||
|
||||
connectionRecord.PreExtApp = headers.Contains("PreExtApp")
|
||||
? connectionCsv[headers.IndexOf("PreExtApp")]
|
||||
: "";
|
||||
@@ -194,14 +186,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
? connectionCsv[headers.IndexOf("RDGatewayHostname")]
|
||||
: "";
|
||||
|
||||
connectionRecord.RDPStartProgram = headers.Contains("RDPStartProgram")
|
||||
? connectionCsv[headers.IndexOf("RDPStartProgram")]
|
||||
: "";
|
||||
|
||||
connectionRecord.RDPStartProgramWorkDir = headers.Contains("RDPStartProgramWorkDir")
|
||||
? connectionCsv[headers.IndexOf("RDPStartProgramWorkDir")]
|
||||
: "";
|
||||
|
||||
if (headers.Contains("Protocol"))
|
||||
{
|
||||
if (Enum.TryParse(connectionCsv[headers.IndexOf("Protocol")], out ProtocolType protocolType))
|
||||
@@ -552,12 +536,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
connectionRecord.Inheritance.SSHTunnelConnectionName = value;
|
||||
}
|
||||
|
||||
if (headers.Contains("InheritOpeningCommand"))
|
||||
{
|
||||
if (bool.TryParse(connectionCsv[headers.IndexOf("InheritOpeningCommand")], out bool value))
|
||||
connectionRecord.Inheritance.OpeningCommand = value;
|
||||
}
|
||||
|
||||
if (headers.Contains("InheritSSHOptions"))
|
||||
{
|
||||
if (bool.TryParse(connectionCsv[headers.IndexOf("InheritSSHOptions")], out bool value))
|
||||
@@ -654,12 +632,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
connectionRecord.Inheritance.RenderingEngine = value;
|
||||
}
|
||||
|
||||
if (headers.Contains("InheritUserViaAPI"))
|
||||
{
|
||||
if (bool.TryParse(connectionCsv[headers.IndexOf("InheritUserViaAPI")], out bool value))
|
||||
connectionRecord.Inheritance.UserViaAPI = value;
|
||||
}
|
||||
|
||||
if (headers.Contains("InheritUsername"))
|
||||
{
|
||||
if (bool.TryParse(connectionCsv[headers.IndexOf("InheritUsername")], out bool value))
|
||||
@@ -684,12 +656,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
connectionRecord.Inheritance.LoadBalanceInfo = value;
|
||||
}
|
||||
|
||||
if (headers.Contains("InheritOpeningCommand"))
|
||||
{
|
||||
if (bool.TryParse(connectionCsv[headers.IndexOf("InheritOpeningCommand")], out bool value))
|
||||
connectionRecord.Inheritance.OpeningCommand = value;
|
||||
}
|
||||
|
||||
if (headers.Contains("InheritPreExtApp"))
|
||||
{
|
||||
if (bool.TryParse(connectionCsv[headers.IndexOf("InheritPreExtApp")], out bool value))
|
||||
|
||||
@@ -1,263 +1,255 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Credential;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
{
|
||||
public class CsvConnectionsSerializerMremotengFormat : ISerializer<ConnectionInfo, string>
|
||||
{
|
||||
private readonly SaveFilter _saveFilter;
|
||||
private readonly ICredentialRepositoryList _credentialRepositoryList;
|
||||
|
||||
public Version Version { get; } = new Version(2, 7);
|
||||
|
||||
public CsvConnectionsSerializerMremotengFormat(SaveFilter saveFilter,
|
||||
ICredentialRepositoryList credentialRepositoryList)
|
||||
{
|
||||
saveFilter.ThrowIfNull(nameof(saveFilter));
|
||||
credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList));
|
||||
|
||||
_saveFilter = saveFilter;
|
||||
_credentialRepositoryList = credentialRepositoryList;
|
||||
}
|
||||
|
||||
public string Serialize(ConnectionTreeModel connectionTreeModel)
|
||||
{
|
||||
connectionTreeModel.ThrowIfNull(nameof(connectionTreeModel));
|
||||
|
||||
var rootNode = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo);
|
||||
return Serialize(rootNode);
|
||||
}
|
||||
|
||||
public string Serialize(ConnectionInfo serializationTarget)
|
||||
{
|
||||
serializationTarget.ThrowIfNull(nameof(serializationTarget));
|
||||
var sb = new StringBuilder();
|
||||
|
||||
WriteCsvHeader(sb);
|
||||
SerializeNodesRecursive(serializationTarget, sb);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private void WriteCsvHeader(StringBuilder sb)
|
||||
{
|
||||
sb.Append("Name;Id;Parent;NodeType;Description;Icon;Panel;");
|
||||
if (_saveFilter.SaveUsername)
|
||||
sb.Append("Username;");
|
||||
if (_saveFilter.SavePassword)
|
||||
sb.Append("Password;");
|
||||
if (_saveFilter.SaveDomain)
|
||||
sb.Append("Domain;");
|
||||
|
||||
sb.Append("Hostname;Port;VmId;Protocol;SSHTunnelConnectionName;OpeningCommand;SSHOptions;PuttySession;ConnectToConsole;UseCredSsp;UseVmId;UseEnhancedMode;RenderingEngine;RDPAuthenticationLevel;" +
|
||||
"LoadBalanceInfo;Colors;Resolution;AutomaticResize;DisplayWallpaper;DisplayThemes;EnableFontSmoothing;EnableDesktopComposition;DisableFullWindowDrag;DisableMenuAnimations;DisableCursorShadow;DisableCursorBlinking;" +
|
||||
"CacheBitmaps;RedirectDiskDrives;RedirectPorts;RedirectPrinters;RedirectClipboard;RedirectSmartCards;RedirectSound;RedirectKeys;" +
|
||||
"PreExtApp;PostExtApp;MacAddress;UserField;ExtApp;Favorite;VNCCompression;VNCEncoding;VNCAuthMode;VNCProxyType;VNCProxyIP;" +
|
||||
"VNCProxyPort;VNCProxyUsername;VNCProxyPassword;VNCColors;VNCSmartSizeMode;VNCViewOnly;RDGatewayUsageMethod;RDGatewayHostname;" +
|
||||
"RDGatewayUseConnectionCredentials;RDGatewayUsername;RDGatewayPassword;RDGatewayDomain;RedirectAudioCapture;RdpVersion;RDPStartProgram;RDPStartProgramWorkDir;UserViaAPI;EC2InstanceId;EC2Region;");
|
||||
|
||||
if (_saveFilter.SaveInheritance)
|
||||
sb.Append("InheritCacheBitmaps;InheritColors;InheritDescription;InheritDisplayThemes;InheritDisplayWallpaper;" +
|
||||
"InheritEnableFontSmoothing;InheritEnableDesktopComposition;InheritDisableFullWindowDrag;InheritDisableMenuAnimations;InheritDisableCursorShadow;InheritDisableCursorBlinking;InheritDomain;InheritIcon;InheritPanel;InheritPassword;InheritPort;" +
|
||||
"InheritProtocol;InheritSSHTunnelConnectionName;InheritOpeningCommand;InheritSSHOptions;InheritPuttySession;InheritRedirectDiskDrives;InheritRedirectKeys;InheritRedirectPorts;InheritRedirectPrinters;" +
|
||||
"InheritRedirectClipboard;InheritRedirectSmartCards;InheritRedirectSound;InheritResolution;InheritAutomaticResize;" +
|
||||
"InheritUseConsoleSession;InheritUseCredSsp;InheritUseVmId;InheritUseEnhancedMode;InheritVmId;InheritRenderingEngine;InheritUsername;" +
|
||||
"InheritRDPAuthenticationLevel;InheritLoadBalanceInfo;InheritPreExtApp;InheritPostExtApp;InheritMacAddress;InheritUserField;" +
|
||||
"InheritFavorite;InheritExtApp;InheritVNCCompression;InheritVNCEncoding;InheritVNCAuthMode;InheritVNCProxyType;InheritVNCProxyIP;" +
|
||||
"InheritVNCProxyPort;InheritVNCProxyUsername;InheritVNCProxyPassword;InheritVNCColors;InheritVNCSmartSizeMode;InheritVNCViewOnly;" +
|
||||
"InheritRDGatewayUsageMethod;InheritRDGatewayHostname;InheritRDGatewayUseConnectionCredentials;InheritRDGatewayUsername;" +
|
||||
"InheritRDGatewayPassword;InheritRDGatewayDomain;InheritRDPAlertIdleTimeout;InheritRDPMinutesToIdleTimeout;InheritSoundQuality;InheritUserViaAPI;" +
|
||||
"InheritRedirectAudioCapture;InheritRdpVersion");
|
||||
}
|
||||
|
||||
private void SerializeNodesRecursive(ConnectionInfo node, StringBuilder sb)
|
||||
{
|
||||
var nodeAsContainer = node as ContainerInfo;
|
||||
if (nodeAsContainer != null)
|
||||
{
|
||||
foreach (var child in nodeAsContainer.Children)
|
||||
{
|
||||
SerializeNodesRecursive(child, sb);
|
||||
}
|
||||
}
|
||||
|
||||
// dont serialize the root node
|
||||
if (node is RootNodeInfo)
|
||||
return;
|
||||
|
||||
SerializeConnectionInfo(node, sb);
|
||||
}
|
||||
|
||||
private void SerializeConnectionInfo(ConnectionInfo con, StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.Append(FormatForCsv(con.Name))
|
||||
.Append(FormatForCsv(con.ConstantID))
|
||||
.Append(FormatForCsv(con.Parent?.ConstantID ?? ""))
|
||||
.Append(FormatForCsv(con.GetTreeNodeType()))
|
||||
.Append(FormatForCsv(con.Description))
|
||||
.Append(FormatForCsv(con.Icon))
|
||||
.Append(FormatForCsv(con.Panel));
|
||||
|
||||
if (_saveFilter.SaveUsername)
|
||||
sb.Append(FormatForCsv(con.Username));
|
||||
|
||||
if (_saveFilter.SavePassword)
|
||||
sb.Append(FormatForCsv(con.Password));
|
||||
|
||||
if (_saveFilter.SaveDomain)
|
||||
sb.Append(FormatForCsv(con.Domain));
|
||||
|
||||
sb.Append(FormatForCsv(con.Hostname))
|
||||
.Append(FormatForCsv(con.Port))
|
||||
.Append(FormatForCsv(con.VmId))
|
||||
.Append(FormatForCsv(con.Protocol))
|
||||
.Append(FormatForCsv(con.SSHTunnelConnectionName))
|
||||
.Append(FormatForCsv(con.OpeningCommand))
|
||||
.Append(FormatForCsv(con.SSHOptions))
|
||||
.Append(FormatForCsv(con.PuttySession))
|
||||
.Append(FormatForCsv(con.UseConsoleSession))
|
||||
.Append(FormatForCsv(con.UseCredSsp))
|
||||
.Append(FormatForCsv(con.UseVmId))
|
||||
.Append(FormatForCsv(con.UseEnhancedMode))
|
||||
.Append(FormatForCsv(con.RenderingEngine))
|
||||
.Append(FormatForCsv(con.RDPAuthenticationLevel))
|
||||
.Append(FormatForCsv(con.LoadBalanceInfo))
|
||||
.Append(FormatForCsv(con.Colors))
|
||||
.Append(FormatForCsv(con.Resolution))
|
||||
.Append(FormatForCsv(con.AutomaticResize))
|
||||
.Append(FormatForCsv(con.DisplayWallpaper))
|
||||
.Append(FormatForCsv(con.DisplayThemes))
|
||||
.Append(FormatForCsv(con.EnableFontSmoothing))
|
||||
.Append(FormatForCsv(con.EnableDesktopComposition))
|
||||
.Append(FormatForCsv(con.DisableFullWindowDrag))
|
||||
.Append(FormatForCsv(con.DisableMenuAnimations))
|
||||
.Append(FormatForCsv(con.DisableCursorShadow))
|
||||
.Append(FormatForCsv(con.DisableCursorBlinking))
|
||||
.Append(FormatForCsv(con.CacheBitmaps))
|
||||
.Append(FormatForCsv(con.RedirectDiskDrives))
|
||||
.Append(FormatForCsv(con.RedirectPorts))
|
||||
.Append(FormatForCsv(con.RedirectPrinters))
|
||||
.Append(FormatForCsv(con.RedirectClipboard))
|
||||
.Append(FormatForCsv(con.RedirectSmartCards))
|
||||
.Append(FormatForCsv(con.RedirectSound))
|
||||
.Append(FormatForCsv(con.RedirectKeys))
|
||||
.Append(FormatForCsv(con.PreExtApp))
|
||||
.Append(FormatForCsv(con.PostExtApp))
|
||||
.Append(FormatForCsv(con.MacAddress))
|
||||
.Append(FormatForCsv(con.UserField))
|
||||
.Append(FormatForCsv(con.ExtApp))
|
||||
.Append(FormatForCsv(con.Favorite))
|
||||
.Append(FormatForCsv(con.VNCCompression))
|
||||
.Append(FormatForCsv(con.VNCEncoding))
|
||||
.Append(FormatForCsv(con.VNCAuthMode))
|
||||
.Append(FormatForCsv(con.VNCProxyType))
|
||||
.Append(FormatForCsv(con.VNCProxyIP))
|
||||
.Append(FormatForCsv(con.VNCProxyPort))
|
||||
.Append(FormatForCsv(con.VNCProxyUsername))
|
||||
.Append(FormatForCsv(con.VNCProxyPassword))
|
||||
.Append(FormatForCsv(con.VNCColors))
|
||||
.Append(FormatForCsv(con.VNCSmartSizeMode))
|
||||
.Append(FormatForCsv(con.VNCViewOnly))
|
||||
.Append(FormatForCsv(con.RDGatewayUsageMethod))
|
||||
.Append(FormatForCsv(con.RDGatewayHostname))
|
||||
.Append(FormatForCsv(con.RDGatewayUseConnectionCredentials))
|
||||
.Append(FormatForCsv(con.RDGatewayUsername))
|
||||
.Append(FormatForCsv(con.RDGatewayPassword))
|
||||
.Append(FormatForCsv(con.RDGatewayDomain))
|
||||
.Append(FormatForCsv(con.RedirectAudioCapture))
|
||||
.Append(FormatForCsv(con.RdpVersion))
|
||||
.Append(FormatForCsv(con.RDPStartProgram))
|
||||
.Append(FormatForCsv(con.RDPStartProgramWorkDir))
|
||||
.Append(FormatForCsv(con.UserViaAPI))
|
||||
.Append(FormatForCsv(con.EC2InstanceId))
|
||||
.Append(FormatForCsv(con.EC2Region));
|
||||
|
||||
|
||||
if (!_saveFilter.SaveInheritance)
|
||||
return;
|
||||
|
||||
sb.Append(FormatForCsv(con.Inheritance.CacheBitmaps))
|
||||
.Append(FormatForCsv(con.Inheritance.Colors))
|
||||
.Append(FormatForCsv(con.Inheritance.Description))
|
||||
.Append(FormatForCsv(con.Inheritance.DisplayThemes))
|
||||
.Append(FormatForCsv(con.Inheritance.DisplayWallpaper))
|
||||
.Append(FormatForCsv(con.Inheritance.EnableFontSmoothing))
|
||||
.Append(FormatForCsv(con.Inheritance.EnableDesktopComposition))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableFullWindowDrag))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableMenuAnimations))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableCursorShadow))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableCursorBlinking))
|
||||
.Append(FormatForCsv(con.Inheritance.Domain))
|
||||
.Append(FormatForCsv(con.Inheritance.Icon))
|
||||
.Append(FormatForCsv(con.Inheritance.Panel))
|
||||
.Append(FormatForCsv(con.Inheritance.Password))
|
||||
.Append(FormatForCsv(con.Inheritance.Port))
|
||||
.Append(FormatForCsv(con.Inheritance.Protocol))
|
||||
.Append(FormatForCsv(con.Inheritance.SSHTunnelConnectionName))
|
||||
.Append(FormatForCsv(con.Inheritance.OpeningCommand))
|
||||
.Append(FormatForCsv(con.Inheritance.SSHOptions))
|
||||
.Append(FormatForCsv(con.Inheritance.PuttySession))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectDiskDrives))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectKeys))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectPorts))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectPrinters))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectClipboard))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectSmartCards))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectSound))
|
||||
.Append(FormatForCsv(con.Inheritance.Resolution))
|
||||
.Append(FormatForCsv(con.Inheritance.AutomaticResize))
|
||||
.Append(FormatForCsv(con.Inheritance.UseConsoleSession))
|
||||
.Append(FormatForCsv(con.Inheritance.UseCredSsp))
|
||||
.Append(FormatForCsv(con.Inheritance.UseVmId))
|
||||
.Append(FormatForCsv(con.Inheritance.UseEnhancedMode))
|
||||
.Append(FormatForCsv(con.Inheritance.VmId))
|
||||
.Append(FormatForCsv(con.Inheritance.RenderingEngine))
|
||||
.Append(FormatForCsv(con.Inheritance.Username))
|
||||
.Append(FormatForCsv(con.Inheritance.RDPAuthenticationLevel))
|
||||
.Append(FormatForCsv(con.Inheritance.LoadBalanceInfo))
|
||||
.Append(FormatForCsv(con.Inheritance.PreExtApp))
|
||||
.Append(FormatForCsv(con.Inheritance.PostExtApp))
|
||||
.Append(FormatForCsv(con.Inheritance.MacAddress))
|
||||
.Append(FormatForCsv(con.Inheritance.UserField))
|
||||
.Append(FormatForCsv(con.Inheritance.Favorite))
|
||||
.Append(FormatForCsv(con.Inheritance.ExtApp))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCCompression))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCEncoding))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCAuthMode))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyType))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyIP))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyPort))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyUsername))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyPassword))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCColors))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCSmartSizeMode))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCViewOnly))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayUsageMethod))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayHostname))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayUseConnectionCredentials))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayUsername))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayPassword))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayDomain))
|
||||
.Append(FormatForCsv(con.Inheritance.RDPAlertIdleTimeout))
|
||||
.Append(FormatForCsv(con.Inheritance.RDPMinutesToIdleTimeout))
|
||||
.Append(FormatForCsv(con.Inheritance.SoundQuality))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectAudioCapture))
|
||||
.Append(FormatForCsv(con.Inheritance.RdpVersion))
|
||||
.Append(FormatForCsv(con.Inheritance.UserViaAPI));
|
||||
}
|
||||
|
||||
private string FormatForCsv(object value)
|
||||
{
|
||||
var cleanedString = value.ToString().Replace(";", "");
|
||||
return cleanedString + ";";
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Credential;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
|
||||
{
|
||||
public class CsvConnectionsSerializerMremotengFormat : ISerializer<ConnectionInfo, string>
|
||||
{
|
||||
private readonly SaveFilter _saveFilter;
|
||||
private readonly ICredentialRepositoryList _credentialRepositoryList;
|
||||
|
||||
public Version Version { get; } = new Version(2, 7);
|
||||
|
||||
public CsvConnectionsSerializerMremotengFormat(SaveFilter saveFilter,
|
||||
ICredentialRepositoryList credentialRepositoryList)
|
||||
{
|
||||
saveFilter.ThrowIfNull(nameof(saveFilter));
|
||||
credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList));
|
||||
|
||||
_saveFilter = saveFilter;
|
||||
_credentialRepositoryList = credentialRepositoryList;
|
||||
}
|
||||
|
||||
public string Serialize(ConnectionTreeModel connectionTreeModel)
|
||||
{
|
||||
connectionTreeModel.ThrowIfNull(nameof(connectionTreeModel));
|
||||
|
||||
var rootNode = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo);
|
||||
return Serialize(rootNode);
|
||||
}
|
||||
|
||||
public string Serialize(ConnectionInfo serializationTarget)
|
||||
{
|
||||
serializationTarget.ThrowIfNull(nameof(serializationTarget));
|
||||
var sb = new StringBuilder();
|
||||
|
||||
WriteCsvHeader(sb);
|
||||
SerializeNodesRecursive(serializationTarget, sb);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private void WriteCsvHeader(StringBuilder sb)
|
||||
{
|
||||
sb.Append("Name;Id;Parent;NodeType;Description;Icon;Panel;");
|
||||
if (_saveFilter.SaveUsername)
|
||||
sb.Append("Username;");
|
||||
if (_saveFilter.SavePassword)
|
||||
sb.Append("Password;");
|
||||
if (_saveFilter.SaveDomain)
|
||||
sb.Append("Domain;");
|
||||
|
||||
sb.Append("Hostname;Port;VmId;Protocol;SSHTunnelConnectionName;SSHOptions;PuttySession;ConnectToConsole;UseCredSsp;UseVmId;UseEnhancedMode;RenderingEngine;RDPAuthenticationLevel;" +
|
||||
"LoadBalanceInfo;Colors;Resolution;AutomaticResize;DisplayWallpaper;DisplayThemes;EnableFontSmoothing;EnableDesktopComposition;DisableFullWindowDrag;DisableMenuAnimations;DisableCursorShadow;DisableCursorBlinking;" +
|
||||
"CacheBitmaps;RedirectDiskDrives;RedirectPorts;RedirectPrinters;RedirectClipboard;RedirectSmartCards;RedirectSound;RedirectKeys;" +
|
||||
"PreExtApp;PostExtApp;MacAddress;UserField;ExtApp;Favorite;VNCCompression;VNCEncoding;VNCAuthMode;VNCProxyType;VNCProxyIP;" +
|
||||
"VNCProxyPort;VNCProxyUsername;VNCProxyPassword;VNCColors;VNCSmartSizeMode;VNCViewOnly;RDGatewayUsageMethod;RDGatewayHostname;" +
|
||||
"RDGatewayUseConnectionCredentials;RDGatewayUsername;RDGatewayPassword;RDGatewayDomain;RedirectAudioCapture;RdpVersion;");
|
||||
|
||||
if (_saveFilter.SaveInheritance)
|
||||
sb.Append("InheritCacheBitmaps;InheritColors;InheritDescription;InheritDisplayThemes;InheritDisplayWallpaper;" +
|
||||
"InheritEnableFontSmoothing;InheritEnableDesktopComposition;InheritDisableFullWindowDrag;InheritDisableMenuAnimations;InheritDisableCursorShadow;InheritDisableCursorBlinking;InheritDomain;InheritIcon;InheritPanel;InheritPassword;InheritPort;" +
|
||||
"InheritProtocol;InheritSSHTunnelConnectionName;InheritSSHOptions;InheritPuttySession;InheritRedirectDiskDrives;InheritRedirectKeys;InheritRedirectPorts;InheritRedirectPrinters;" +
|
||||
"InheritRedirectClipboard;InheritRedirectSmartCards;InheritRedirectSound;InheritResolution;InheritAutomaticResize;" +
|
||||
"InheritUseConsoleSession;InheritUseCredSsp;InheritUseVmId;InheritUseEnhancedMode;InheritVmId;InheritRenderingEngine;InheritUsername;" +
|
||||
"InheritRDPAuthenticationLevel;InheritLoadBalanceInfo;InheritPreExtApp;InheritPostExtApp;InheritMacAddress;InheritUserField;" +
|
||||
"InheritFavorite;InheritExtApp;InheritVNCCompression;InheritVNCEncoding;InheritVNCAuthMode;InheritVNCProxyType;InheritVNCProxyIP;" +
|
||||
"InheritVNCProxyPort;InheritVNCProxyUsername;InheritVNCProxyPassword;InheritVNCColors;InheritVNCSmartSizeMode;InheritVNCViewOnly;" +
|
||||
"InheritRDGatewayUsageMethod;InheritRDGatewayHostname;InheritRDGatewayUseConnectionCredentials;InheritRDGatewayUsername;" +
|
||||
"InheritRDGatewayPassword;InheritRDGatewayDomain;InheritRDPAlertIdleTimeout;InheritRDPMinutesToIdleTimeout;InheritSoundQuality;" +
|
||||
"InheritRedirectAudioCapture;InheritRdpVersion");
|
||||
}
|
||||
|
||||
private void SerializeNodesRecursive(ConnectionInfo node, StringBuilder sb)
|
||||
{
|
||||
var nodeAsContainer = node as ContainerInfo;
|
||||
if (nodeAsContainer != null)
|
||||
{
|
||||
foreach (var child in nodeAsContainer.Children)
|
||||
{
|
||||
SerializeNodesRecursive(child, sb);
|
||||
}
|
||||
}
|
||||
|
||||
// dont serialize the root node
|
||||
if (node is RootNodeInfo)
|
||||
return;
|
||||
|
||||
SerializeConnectionInfo(node, sb);
|
||||
}
|
||||
|
||||
private void SerializeConnectionInfo(ConnectionInfo con, StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.Append(FormatForCsv(con.Name))
|
||||
.Append(FormatForCsv(con.ConstantID))
|
||||
.Append(FormatForCsv(con.Parent?.ConstantID ?? ""))
|
||||
.Append(FormatForCsv(con.GetTreeNodeType()))
|
||||
.Append(FormatForCsv(con.Description))
|
||||
.Append(FormatForCsv(con.Icon))
|
||||
.Append(FormatForCsv(con.Panel));
|
||||
|
||||
if (_saveFilter.SaveUsername)
|
||||
sb.Append(FormatForCsv(con.Username));
|
||||
|
||||
if (_saveFilter.SavePassword)
|
||||
sb.Append(FormatForCsv(con.Password));
|
||||
|
||||
if (_saveFilter.SaveDomain)
|
||||
sb.Append(FormatForCsv(con.Domain));
|
||||
|
||||
sb.Append(FormatForCsv(con.Hostname))
|
||||
.Append(FormatForCsv(con.Port))
|
||||
.Append(FormatForCsv(con.VmId))
|
||||
.Append(FormatForCsv(con.Protocol))
|
||||
.Append(FormatForCsv(con.SSHTunnelConnectionName))
|
||||
.Append(FormatForCsv(con.SSHOptions))
|
||||
.Append(FormatForCsv(con.PuttySession))
|
||||
.Append(FormatForCsv(con.UseConsoleSession))
|
||||
.Append(FormatForCsv(con.UseCredSsp))
|
||||
.Append(FormatForCsv(con.UseVmId))
|
||||
.Append(FormatForCsv(con.UseEnhancedMode))
|
||||
.Append(FormatForCsv(con.RenderingEngine))
|
||||
.Append(FormatForCsv(con.RDPAuthenticationLevel))
|
||||
.Append(FormatForCsv(con.LoadBalanceInfo))
|
||||
.Append(FormatForCsv(con.Colors))
|
||||
.Append(FormatForCsv(con.Resolution))
|
||||
.Append(FormatForCsv(con.AutomaticResize))
|
||||
.Append(FormatForCsv(con.DisplayWallpaper))
|
||||
.Append(FormatForCsv(con.DisplayThemes))
|
||||
.Append(FormatForCsv(con.EnableFontSmoothing))
|
||||
.Append(FormatForCsv(con.EnableDesktopComposition))
|
||||
.Append(FormatForCsv(con.DisableFullWindowDrag))
|
||||
.Append(FormatForCsv(con.DisableMenuAnimations))
|
||||
.Append(FormatForCsv(con.DisableCursorShadow))
|
||||
.Append(FormatForCsv(con.DisableCursorBlinking))
|
||||
.Append(FormatForCsv(con.CacheBitmaps))
|
||||
.Append(FormatForCsv(con.RedirectDiskDrives))
|
||||
.Append(FormatForCsv(con.RedirectPorts))
|
||||
.Append(FormatForCsv(con.RedirectPrinters))
|
||||
.Append(FormatForCsv(con.RedirectClipboard))
|
||||
.Append(FormatForCsv(con.RedirectSmartCards))
|
||||
.Append(FormatForCsv(con.RedirectSound))
|
||||
.Append(FormatForCsv(con.RedirectKeys))
|
||||
.Append(FormatForCsv(con.PreExtApp))
|
||||
.Append(FormatForCsv(con.PostExtApp))
|
||||
.Append(FormatForCsv(con.MacAddress))
|
||||
.Append(FormatForCsv(con.UserField))
|
||||
.Append(FormatForCsv(con.ExtApp))
|
||||
.Append(FormatForCsv(con.Favorite))
|
||||
.Append(FormatForCsv(con.VNCCompression))
|
||||
.Append(FormatForCsv(con.VNCEncoding))
|
||||
.Append(FormatForCsv(con.VNCAuthMode))
|
||||
.Append(FormatForCsv(con.VNCProxyType))
|
||||
.Append(FormatForCsv(con.VNCProxyIP))
|
||||
.Append(FormatForCsv(con.VNCProxyPort))
|
||||
.Append(FormatForCsv(con.VNCProxyUsername))
|
||||
.Append(FormatForCsv(con.VNCProxyPassword))
|
||||
.Append(FormatForCsv(con.VNCColors))
|
||||
.Append(FormatForCsv(con.VNCSmartSizeMode))
|
||||
.Append(FormatForCsv(con.VNCViewOnly))
|
||||
.Append(FormatForCsv(con.RDGatewayUsageMethod))
|
||||
.Append(FormatForCsv(con.RDGatewayHostname))
|
||||
.Append(FormatForCsv(con.RDGatewayUseConnectionCredentials))
|
||||
.Append(FormatForCsv(con.RDGatewayUsername))
|
||||
.Append(FormatForCsv(con.RDGatewayPassword))
|
||||
.Append(FormatForCsv(con.RDGatewayDomain))
|
||||
.Append(FormatForCsv(con.RedirectAudioCapture))
|
||||
.Append(FormatForCsv(con.RdpVersion));
|
||||
|
||||
|
||||
if (!_saveFilter.SaveInheritance)
|
||||
return;
|
||||
|
||||
sb.Append(FormatForCsv(con.Inheritance.CacheBitmaps))
|
||||
.Append(FormatForCsv(con.Inheritance.Colors))
|
||||
.Append(FormatForCsv(con.Inheritance.Description))
|
||||
.Append(FormatForCsv(con.Inheritance.DisplayThemes))
|
||||
.Append(FormatForCsv(con.Inheritance.DisplayWallpaper))
|
||||
.Append(FormatForCsv(con.Inheritance.EnableFontSmoothing))
|
||||
.Append(FormatForCsv(con.Inheritance.EnableDesktopComposition))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableFullWindowDrag))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableMenuAnimations))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableCursorShadow))
|
||||
.Append(FormatForCsv(con.Inheritance.DisableCursorBlinking))
|
||||
.Append(FormatForCsv(con.Inheritance.Domain))
|
||||
.Append(FormatForCsv(con.Inheritance.Icon))
|
||||
.Append(FormatForCsv(con.Inheritance.Panel))
|
||||
.Append(FormatForCsv(con.Inheritance.Password))
|
||||
.Append(FormatForCsv(con.Inheritance.Port))
|
||||
.Append(FormatForCsv(con.Inheritance.Protocol))
|
||||
.Append(FormatForCsv(con.Inheritance.SSHTunnelConnectionName))
|
||||
.Append(FormatForCsv(con.Inheritance.SSHOptions))
|
||||
.Append(FormatForCsv(con.Inheritance.PuttySession))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectDiskDrives))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectKeys))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectPorts))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectPrinters))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectClipboard))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectSmartCards))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectSound))
|
||||
.Append(FormatForCsv(con.Inheritance.Resolution))
|
||||
.Append(FormatForCsv(con.Inheritance.AutomaticResize))
|
||||
.Append(FormatForCsv(con.Inheritance.UseConsoleSession))
|
||||
.Append(FormatForCsv(con.Inheritance.UseCredSsp))
|
||||
.Append(FormatForCsv(con.Inheritance.UseVmId))
|
||||
.Append(FormatForCsv(con.Inheritance.UseEnhancedMode))
|
||||
.Append(FormatForCsv(con.Inheritance.VmId))
|
||||
.Append(FormatForCsv(con.Inheritance.RenderingEngine))
|
||||
.Append(FormatForCsv(con.Inheritance.Username))
|
||||
.Append(FormatForCsv(con.Inheritance.RDPAuthenticationLevel))
|
||||
.Append(FormatForCsv(con.Inheritance.LoadBalanceInfo))
|
||||
.Append(FormatForCsv(con.Inheritance.PreExtApp))
|
||||
.Append(FormatForCsv(con.Inheritance.PostExtApp))
|
||||
.Append(FormatForCsv(con.Inheritance.MacAddress))
|
||||
.Append(FormatForCsv(con.Inheritance.UserField))
|
||||
.Append(FormatForCsv(con.Inheritance.Favorite))
|
||||
.Append(FormatForCsv(con.Inheritance.ExtApp))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCCompression))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCEncoding))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCAuthMode))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyType))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyIP))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyPort))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyUsername))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCProxyPassword))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCColors))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCSmartSizeMode))
|
||||
.Append(FormatForCsv(con.Inheritance.VNCViewOnly))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayUsageMethod))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayHostname))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayUseConnectionCredentials))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayUsername))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayPassword))
|
||||
.Append(FormatForCsv(con.Inheritance.RDGatewayDomain))
|
||||
.Append(FormatForCsv(con.Inheritance.RDPAlertIdleTimeout))
|
||||
.Append(FormatForCsv(con.Inheritance.RDPMinutesToIdleTimeout))
|
||||
.Append(FormatForCsv(con.Inheritance.SoundQuality))
|
||||
.Append(FormatForCsv(con.Inheritance.RedirectAudioCapture))
|
||||
.Append(FormatForCsv(con.Inheritance.RdpVersion));
|
||||
}
|
||||
|
||||
private string FormatForCsv(object value)
|
||||
{
|
||||
var cleanedString = value.ToString().Replace(";", "");
|
||||
return cleanedString + ";";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,263 +1,278 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.Http;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.MsSql
|
||||
{
|
||||
public class DataTableDeserializer : IDeserializer<DataTable, ConnectionTreeModel>
|
||||
{
|
||||
private readonly ICryptographyProvider _cryptographyProvider;
|
||||
private readonly SecureString _decryptionKey;
|
||||
|
||||
public DataTableDeserializer(ICryptographyProvider cryptographyProvider, SecureString decryptionKey)
|
||||
{
|
||||
_cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
|
||||
_decryptionKey = decryptionKey.ThrowIfNull(nameof(decryptionKey));
|
||||
}
|
||||
|
||||
public ConnectionTreeModel Deserialize(DataTable table)
|
||||
{
|
||||
var connectionList = CreateNodesFromTable(table);
|
||||
var connectionTreeModel = CreateNodeHierarchy(connectionList, table);
|
||||
Runtime.ConnectionsService.IsConnectionsFileLoaded = true;
|
||||
return connectionTreeModel;
|
||||
}
|
||||
|
||||
private List<ConnectionInfo> CreateNodesFromTable(DataTable table)
|
||||
{
|
||||
var nodeList = new List<ConnectionInfo>();
|
||||
foreach (DataRow row in table.Rows)
|
||||
{
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch ((string)row["Type"])
|
||||
{
|
||||
case "Connection":
|
||||
nodeList.Add(DeserializeConnectionInfo(row));
|
||||
break;
|
||||
case "Container":
|
||||
nodeList.Add(DeserializeContainerInfo(row));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
private ConnectionInfo DeserializeConnectionInfo(DataRow row)
|
||||
{
|
||||
var connectionId = row["ConstantID"] as string ?? Guid.NewGuid().ToString();
|
||||
var connectionInfo = new ConnectionInfo(connectionId);
|
||||
PopulateConnectionInfoFromDatarow(row, connectionInfo);
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
private ContainerInfo DeserializeContainerInfo(DataRow row)
|
||||
{
|
||||
var containerId = row["ConstantID"] as string ?? Guid.NewGuid().ToString();
|
||||
var containerInfo = new ContainerInfo(containerId);
|
||||
PopulateConnectionInfoFromDatarow(row, containerInfo);
|
||||
return containerInfo;
|
||||
}
|
||||
|
||||
private void PopulateConnectionInfoFromDatarow(DataRow dataRow, ConnectionInfo connectionInfo)
|
||||
{
|
||||
connectionInfo.Name = (string)dataRow["Name"];
|
||||
|
||||
// This throws a NPE - Parent is a connectionInfo object which will be null at this point.
|
||||
// The Parent object is linked properly later in CreateNodeHierarchy()
|
||||
//connectionInfo.Parent.ConstantID = (string)dataRow["ParentID"];
|
||||
|
||||
connectionInfo.Description = (string)dataRow["Description"];
|
||||
connectionInfo.Icon = (string)dataRow["Icon"];
|
||||
connectionInfo.Panel = (string)dataRow["Panel"];
|
||||
connectionInfo.Username = (string)dataRow["Username"];
|
||||
connectionInfo.Domain = (string)dataRow["Domain"];
|
||||
connectionInfo.Password = DecryptValue((string)dataRow["Password"]);
|
||||
connectionInfo.Hostname = (string)dataRow["Hostname"];
|
||||
connectionInfo.VmId = (string)dataRow["VmId"];
|
||||
connectionInfo.UseEnhancedMode = (bool)dataRow["UseEnhancedMode"];
|
||||
connectionInfo.Protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), (string)dataRow["Protocol"]);
|
||||
connectionInfo.SSHTunnelConnectionName = (string)dataRow["SSHTunnelConnectionName"];
|
||||
connectionInfo.OpeningCommand = (string)dataRow["OpeningCommand"];
|
||||
connectionInfo.SSHOptions = (string)dataRow["SSHOptions"];
|
||||
connectionInfo.PuttySession = (string)dataRow["PuttySession"];
|
||||
connectionInfo.Port = (int)dataRow["Port"];
|
||||
connectionInfo.UseConsoleSession = (bool)dataRow["ConnectToConsole"];
|
||||
connectionInfo.UseCredSsp = (bool)dataRow["UseCredSsp"];
|
||||
connectionInfo.UseVmId = (bool)dataRow["UseVmId"];
|
||||
connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), (string)dataRow["RenderingEngine"]);
|
||||
connectionInfo.RDPAuthenticationLevel = (AuthenticationLevel)Enum.Parse(typeof(AuthenticationLevel), (string)dataRow["RDPAuthenticationLevel"]);
|
||||
connectionInfo.RDPMinutesToIdleTimeout = (int)dataRow["RDPMinutesToIdleTimeout"];
|
||||
connectionInfo.RDPAlertIdleTimeout = (bool)dataRow["RDPAlertIdleTimeout"];
|
||||
connectionInfo.LoadBalanceInfo = (string)dataRow["LoadBalanceInfo"];
|
||||
connectionInfo.Colors = (RDPColors)Enum.Parse(typeof(RDPColors), (string)dataRow["Colors"]);
|
||||
connectionInfo.Resolution = (RDPResolutions)Enum.Parse(typeof(RDPResolutions), (string)dataRow["Resolution"]);
|
||||
connectionInfo.AutomaticResize = (bool)dataRow["AutomaticResize"];
|
||||
connectionInfo.DisplayWallpaper = (bool)dataRow["DisplayWallpaper"];
|
||||
connectionInfo.DisplayThemes = (bool)dataRow["DisplayThemes"];
|
||||
connectionInfo.EnableFontSmoothing = (bool)dataRow["EnableFontSmoothing"];
|
||||
connectionInfo.EnableDesktopComposition = (bool)dataRow["EnableDesktopComposition"];
|
||||
connectionInfo.DisableFullWindowDrag = (bool)dataRow["DisableFullWindowDrag"];
|
||||
connectionInfo.DisableMenuAnimations = (bool)dataRow["DisableMenuAnimations"];
|
||||
connectionInfo.DisableCursorShadow = (bool)dataRow["DisableCursorShadow"];
|
||||
connectionInfo.DisableCursorBlinking = (bool)dataRow["DisableCursorBlinking"];
|
||||
connectionInfo.CacheBitmaps = (bool)dataRow["CacheBitmaps"];
|
||||
connectionInfo.RedirectDiskDrives = (bool)dataRow["RedirectDiskDrives"];
|
||||
connectionInfo.RedirectPorts = (bool)dataRow["RedirectPorts"];
|
||||
connectionInfo.RedirectPrinters = (bool)dataRow["RedirectPrinters"];
|
||||
connectionInfo.RedirectClipboard = (bool)dataRow["RedirectClipboard"];
|
||||
connectionInfo.RedirectSmartCards = (bool)dataRow["RedirectSmartCards"];
|
||||
connectionInfo.RedirectSound = (RDPSounds)Enum.Parse(typeof(RDPSounds), (string)dataRow["RedirectSound"]);
|
||||
connectionInfo.SoundQuality = (RDPSoundQuality)Enum.Parse(typeof(RDPSoundQuality), (string)dataRow["SoundQuality"]);
|
||||
connectionInfo.RedirectAudioCapture = (bool)dataRow["RedirectAudioCapture"];
|
||||
connectionInfo.RDPStartProgram = (string)dataRow["StartProgram"];
|
||||
connectionInfo.RDPStartProgramWorkDir = (string)dataRow["StartProgramWorkDir"];
|
||||
connectionInfo.RedirectKeys = (bool)dataRow["RedirectKeys"];
|
||||
connectionInfo.OpeningCommand = (string)dataRow["OpeningCommand"];
|
||||
connectionInfo.PreExtApp = (string)dataRow["PreExtApp"];
|
||||
connectionInfo.PostExtApp = (string)dataRow["PostExtApp"];
|
||||
connectionInfo.MacAddress = (string)dataRow["MacAddress"];
|
||||
connectionInfo.UserField = (string)dataRow["UserField"];
|
||||
connectionInfo.ExtApp = (string)dataRow["ExtApp"];
|
||||
connectionInfo.VNCCompression = (ProtocolVNC.Compression)Enum.Parse(typeof(ProtocolVNC.Compression), (string)dataRow["VNCCompression"]);
|
||||
connectionInfo.VNCEncoding = (ProtocolVNC.Encoding)Enum.Parse(typeof(ProtocolVNC.Encoding), (string)dataRow["VNCEncoding"]);
|
||||
connectionInfo.VNCAuthMode = (ProtocolVNC.AuthMode)Enum.Parse(typeof(ProtocolVNC.AuthMode), (string)dataRow["VNCAuthMode"]);
|
||||
connectionInfo.VNCProxyType = (ProtocolVNC.ProxyType)Enum.Parse(typeof(ProtocolVNC.ProxyType), (string)dataRow["VNCProxyType"]);
|
||||
connectionInfo.VNCProxyIP = (string)dataRow["VNCProxyIP"];
|
||||
connectionInfo.VNCProxyPort = (int)dataRow["VNCProxyPort"];
|
||||
connectionInfo.VNCProxyUsername = (string)dataRow["VNCProxyUsername"];
|
||||
connectionInfo.VNCProxyPassword = DecryptValue((string)dataRow["VNCProxyPassword"]);
|
||||
connectionInfo.VNCColors = (ProtocolVNC.Colors)Enum.Parse(typeof(ProtocolVNC.Colors), (string)dataRow["VNCColors"]);
|
||||
connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), (string)dataRow["VNCSmartSizeMode"]);
|
||||
connectionInfo.VNCViewOnly = (bool)dataRow["VNCViewOnly"];
|
||||
connectionInfo.RDGatewayUsageMethod = (RDGatewayUsageMethod)Enum.Parse(typeof(RDGatewayUsageMethod), (string)dataRow["RDGatewayUsageMethod"]);
|
||||
connectionInfo.RDGatewayHostname = (string)dataRow["RDGatewayHostname"];
|
||||
connectionInfo.RDGatewayUseConnectionCredentials = (RDGatewayUseConnectionCredentials)Enum.Parse(typeof(RDGatewayUseConnectionCredentials), (string)dataRow["RDGatewayUseConnectionCredentials"]);
|
||||
connectionInfo.RDGatewayUsername = (string)dataRow["RDGatewayUsername"];
|
||||
connectionInfo.RDGatewayPassword = DecryptValue((string)dataRow["RDGatewayPassword"]);
|
||||
connectionInfo.RDGatewayDomain = (string)dataRow["RDGatewayDomain"];
|
||||
|
||||
if (!dataRow.IsNull("RdpVersion")) // table allows null values which must be handled
|
||||
if (Enum.TryParse((string)dataRow["RdpVersion"], true, out RdpVersion rdpVersion))
|
||||
connectionInfo.RdpVersion = rdpVersion;
|
||||
|
||||
connectionInfo.Inheritance.CacheBitmaps = (bool)dataRow["InheritCacheBitmaps"];
|
||||
connectionInfo.Inheritance.Colors = (bool)dataRow["InheritColors"];
|
||||
connectionInfo.Inheritance.Description = (bool)dataRow["InheritDescription"];
|
||||
connectionInfo.Inheritance.DisplayThemes = (bool)dataRow["InheritDisplayThemes"];
|
||||
connectionInfo.Inheritance.DisplayWallpaper = (bool)dataRow["InheritDisplayWallpaper"];
|
||||
connectionInfo.Inheritance.EnableFontSmoothing = (bool)dataRow["InheritEnableFontSmoothing"];
|
||||
connectionInfo.Inheritance.EnableDesktopComposition = (bool)dataRow["InheritEnableDesktopComposition"];
|
||||
connectionInfo.Inheritance.DisableFullWindowDrag = (bool)dataRow["InheritDisableFullWindowDrag"];
|
||||
connectionInfo.Inheritance.DisableMenuAnimations = (bool)dataRow["InheritDisableMenuAnimations"];
|
||||
connectionInfo.Inheritance.DisableCursorShadow = (bool)dataRow["InheritDisableCursorShadow"];
|
||||
connectionInfo.Inheritance.DisableCursorBlinking = (bool)dataRow["InheritDisableCursorBlinking"];
|
||||
connectionInfo.Inheritance.Domain = (bool)dataRow["InheritDomain"];
|
||||
connectionInfo.Inheritance.Icon = (bool)dataRow["InheritIcon"];
|
||||
connectionInfo.Inheritance.Panel = (bool)dataRow["InheritPanel"];
|
||||
connectionInfo.Inheritance.Password = (bool)dataRow["InheritPassword"];
|
||||
connectionInfo.Inheritance.Port = (bool)dataRow["InheritPort"];
|
||||
connectionInfo.Inheritance.Protocol = (bool)dataRow["InheritProtocol"];
|
||||
connectionInfo.Inheritance.SSHTunnelConnectionName = (bool)dataRow["InheritSSHTunnelConnectionName"];
|
||||
connectionInfo.Inheritance.OpeningCommand = (bool)dataRow["InheritOpeningCommand"];
|
||||
connectionInfo.Inheritance.SSHOptions = (bool)dataRow["InheritSSHOptions"];
|
||||
connectionInfo.Inheritance.PuttySession = (bool)dataRow["InheritPuttySession"];
|
||||
connectionInfo.Inheritance.RedirectDiskDrives = (bool)dataRow["InheritRedirectDiskDrives"];
|
||||
connectionInfo.Inheritance.RedirectKeys = (bool)dataRow["InheritRedirectKeys"];
|
||||
connectionInfo.Inheritance.RedirectPorts = (bool)dataRow["InheritRedirectPorts"];
|
||||
connectionInfo.Inheritance.RedirectPrinters = (bool)dataRow["InheritRedirectPrinters"];
|
||||
connectionInfo.Inheritance.RedirectClipboard = (bool)dataRow["InheritRedirectClipboard"];
|
||||
connectionInfo.Inheritance.RedirectSmartCards = (bool)dataRow["InheritRedirectSmartCards"];
|
||||
connectionInfo.Inheritance.RedirectSound = (bool)dataRow["InheritRedirectSound"];
|
||||
connectionInfo.Inheritance.SoundQuality = (bool)dataRow["InheritSoundQuality"];
|
||||
connectionInfo.Inheritance.RedirectAudioCapture = (bool)dataRow["InheritRedirectAudioCapture"];
|
||||
connectionInfo.Inheritance.Resolution = (bool)dataRow["InheritResolution"];
|
||||
connectionInfo.Inheritance.AutomaticResize = (bool)dataRow["InheritAutomaticResize"];
|
||||
connectionInfo.Inheritance.UseConsoleSession = (bool)dataRow["InheritUseConsoleSession"];
|
||||
connectionInfo.Inheritance.UseCredSsp = (bool)dataRow["InheritUseCredSsp"];
|
||||
connectionInfo.Inheritance.UseVmId = (bool)dataRow["InheritUseVmId"];
|
||||
connectionInfo.Inheritance.UseEnhancedMode = (bool)dataRow["InheritUseEnhancedMode"];
|
||||
connectionInfo.Inheritance.VmId = (bool)dataRow["InheritVmId"];
|
||||
connectionInfo.Inheritance.RenderingEngine = (bool)dataRow["InheritRenderingEngine"];
|
||||
connectionInfo.Inheritance.Username = (bool)dataRow["InheritUsername"];
|
||||
connectionInfo.Inheritance.RDPAuthenticationLevel = (bool)dataRow["InheritRDPAuthenticationLevel"];
|
||||
connectionInfo.Inheritance.RDPAlertIdleTimeout = (bool)dataRow["InheritRDPAlertIdleTimeout"];
|
||||
connectionInfo.Inheritance.RDPMinutesToIdleTimeout = (bool)dataRow["InheritRDPMinutesToIdleTimeout"];
|
||||
connectionInfo.Inheritance.LoadBalanceInfo = (bool)dataRow["InheritLoadBalanceInfo"];
|
||||
connectionInfo.Inheritance.OpeningCommand = (bool)dataRow["InheritOpeningCommand"];
|
||||
connectionInfo.Inheritance.PreExtApp = (bool)dataRow["InheritPreExtApp"];
|
||||
connectionInfo.Inheritance.PostExtApp = (bool)dataRow["InheritPostExtApp"];
|
||||
connectionInfo.Inheritance.MacAddress = (bool)dataRow["InheritMacAddress"];
|
||||
connectionInfo.Inheritance.UserField = (bool)dataRow["InheritUserField"];
|
||||
connectionInfo.Inheritance.ExtApp = (bool)dataRow["InheritExtApp"];
|
||||
connectionInfo.Inheritance.VNCCompression = (bool)dataRow["InheritVNCCompression"];
|
||||
connectionInfo.Inheritance.VNCEncoding = (bool)dataRow["InheritVNCEncoding"];
|
||||
connectionInfo.Inheritance.VNCAuthMode = (bool)dataRow["InheritVNCAuthMode"];
|
||||
connectionInfo.Inheritance.VNCProxyType = (bool)dataRow["InheritVNCProxyType"];
|
||||
connectionInfo.Inheritance.VNCProxyIP = (bool)dataRow["InheritVNCProxyIP"];
|
||||
connectionInfo.Inheritance.VNCProxyPort = (bool)dataRow["InheritVNCProxyPort"];
|
||||
connectionInfo.Inheritance.VNCProxyUsername = (bool)dataRow["InheritVNCProxyUsername"];
|
||||
connectionInfo.Inheritance.VNCProxyPassword = (bool)dataRow["InheritVNCProxyPassword"];
|
||||
connectionInfo.Inheritance.VNCColors = (bool)dataRow["InheritVNCColors"];
|
||||
connectionInfo.Inheritance.VNCSmartSizeMode = (bool)dataRow["InheritVNCSmartSizeMode"];
|
||||
connectionInfo.Inheritance.VNCViewOnly = (bool)dataRow["InheritVNCViewOnly"];
|
||||
connectionInfo.Inheritance.RDGatewayUsageMethod = (bool)dataRow["InheritRDGatewayUsageMethod"];
|
||||
connectionInfo.Inheritance.RDGatewayHostname = (bool)dataRow["InheritRDGatewayHostname"];
|
||||
connectionInfo.Inheritance.RDGatewayUseConnectionCredentials = (bool)dataRow["InheritRDGatewayUseConnectionCredentials"];
|
||||
connectionInfo.Inheritance.RDGatewayUsername = (bool)dataRow["InheritRDGatewayUsername"];
|
||||
connectionInfo.Inheritance.RDGatewayPassword = (bool)dataRow["InheritRDGatewayPassword"];
|
||||
connectionInfo.Inheritance.RDGatewayDomain = (bool)dataRow["InheritRDGatewayDomain"];
|
||||
connectionInfo.Inheritance.RdpVersion = (bool)dataRow["InheritRdpVersion"];
|
||||
}
|
||||
|
||||
private string DecryptValue(string cipherText)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _cryptographyProvider.Decrypt(cipherText, _decryptionKey);
|
||||
}
|
||||
catch (EncryptionException)
|
||||
{
|
||||
// value may not be encrypted
|
||||
return cipherText;
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectionTreeModel CreateNodeHierarchy(List<ConnectionInfo> connectionList, DataTable dataTable)
|
||||
{
|
||||
var connectionTreeModel = new ConnectionTreeModel();
|
||||
var rootNode = new RootNodeInfo(RootNodeType.Connection, "0")
|
||||
{
|
||||
PasswordString = _decryptionKey.ConvertToUnsecureString()
|
||||
};
|
||||
connectionTreeModel.AddRootNode(rootNode);
|
||||
|
||||
foreach (DataRow row in dataTable.Rows)
|
||||
{
|
||||
var id = (string)row["ConstantID"];
|
||||
var connectionInfo = connectionList.First(node => node.ConstantID == id);
|
||||
var parentId = (string)row["ParentID"];
|
||||
if (parentId == "0" || connectionList.All(node => node.ConstantID != parentId))
|
||||
rootNode.AddChild(connectionInfo);
|
||||
else
|
||||
(connectionList.First(node => node.ConstantID == parentId) as ContainerInfo)?.AddChild(
|
||||
connectionInfo);
|
||||
}
|
||||
|
||||
return connectionTreeModel;
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.Http;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.MsSql
|
||||
{
|
||||
public class DataTableDeserializer : IDeserializer<DataTable, ConnectionTreeModel>
|
||||
{
|
||||
private readonly ICryptographyProvider _cryptographyProvider;
|
||||
private readonly SecureString _decryptionKey;
|
||||
|
||||
public DataTableDeserializer(ICryptographyProvider cryptographyProvider, SecureString decryptionKey)
|
||||
{
|
||||
_cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
|
||||
_decryptionKey = decryptionKey.ThrowIfNull(nameof(decryptionKey));
|
||||
}
|
||||
|
||||
public ConnectionTreeModel Deserialize(DataTable table)
|
||||
{
|
||||
var connectionList = CreateNodesFromTable(table);
|
||||
var connectionTreeModel = CreateNodeHierarchy(connectionList, table);
|
||||
Runtime.ConnectionsService.IsConnectionsFileLoaded = true;
|
||||
return connectionTreeModel;
|
||||
}
|
||||
|
||||
private List<ConnectionInfo> CreateNodesFromTable(DataTable table)
|
||||
{
|
||||
var nodeList = new List<ConnectionInfo>();
|
||||
foreach (DataRow row in table.Rows)
|
||||
{
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch ((string)row["Type"])
|
||||
{
|
||||
case "Connection":
|
||||
nodeList.Add(DeserializeConnectionInfo(row));
|
||||
break;
|
||||
case "Container":
|
||||
nodeList.Add(DeserializeContainerInfo(row));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
private ConnectionInfo DeserializeConnectionInfo(DataRow row)
|
||||
{
|
||||
var connectionId = row["ConstantID"] as string ?? Guid.NewGuid().ToString();
|
||||
var connectionInfo = new ConnectionInfo(connectionId);
|
||||
PopulateConnectionInfoFromDatarow(row, connectionInfo);
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
private ContainerInfo DeserializeContainerInfo(DataRow row)
|
||||
{
|
||||
var containerId = row["ConstantID"] as string ?? Guid.NewGuid().ToString();
|
||||
var containerInfo = new ContainerInfo(containerId);
|
||||
PopulateConnectionInfoFromDatarow(row, containerInfo);
|
||||
return containerInfo;
|
||||
}
|
||||
|
||||
private void PopulateConnectionInfoFromDatarow(DataRow dataRow, ConnectionInfo connectionInfo)
|
||||
{
|
||||
connectionInfo.Name = (string)dataRow["Name"];
|
||||
|
||||
// This throws a NPE - Parent is a connectionInfo object which will be null at this point.
|
||||
// The Parent object is linked properly later in CreateNodeHierarchy()
|
||||
//connectionInfo.Parent.ConstantID = (string)dataRow["ParentID"];
|
||||
|
||||
connectionInfo.Description = (string)dataRow["Description"];
|
||||
connectionInfo.Icon = (string)dataRow["Icon"];
|
||||
connectionInfo.Panel = (string)dataRow["Panel"];
|
||||
connectionInfo.Username = (string)dataRow["Username"];
|
||||
connectionInfo.Domain = (string)dataRow["Domain"];
|
||||
connectionInfo.Password = DecryptValue((string)dataRow["Password"]);
|
||||
connectionInfo.Hostname = (string)dataRow["Hostname"];
|
||||
connectionInfo.VmId = (string)dataRow["VmId"];
|
||||
connectionInfo.UseEnhancedMode = (bool)dataRow["UseEnhancedMode"];
|
||||
connectionInfo.Protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), (string)dataRow["Protocol"]);
|
||||
connectionInfo.SSHTunnelConnectionName = (string)dataRow["SSHTunnelConnectionName"];
|
||||
connectionInfo.SSHOptions = (string)dataRow["SSHOptions"];
|
||||
connectionInfo.PuttySession = (string)dataRow["PuttySession"];
|
||||
connectionInfo.Port = (int)dataRow["Port"];
|
||||
connectionInfo.UseConsoleSession = (bool)dataRow["ConnectToConsole"];
|
||||
connectionInfo.UseCredSsp = (bool)dataRow["UseCredSsp"];
|
||||
connectionInfo.UseVmId = (bool)dataRow["UseVmId"];
|
||||
connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine),
|
||||
(string)dataRow["RenderingEngine"]);
|
||||
connectionInfo.RDPAuthenticationLevel =
|
||||
(AuthenticationLevel)Enum.Parse(typeof(AuthenticationLevel),
|
||||
(string)dataRow["RDPAuthenticationLevel"]);
|
||||
connectionInfo.RDPMinutesToIdleTimeout = (int)dataRow["RDPMinutesToIdleTimeout"];
|
||||
connectionInfo.RDPAlertIdleTimeout = (bool)dataRow["RDPAlertIdleTimeout"];
|
||||
connectionInfo.LoadBalanceInfo = (string)dataRow["LoadBalanceInfo"];
|
||||
connectionInfo.Colors =
|
||||
(RDPColors)Enum.Parse(typeof(RDPColors), (string)dataRow["Colors"]);
|
||||
connectionInfo.Resolution =
|
||||
(RDPResolutions)Enum.Parse(typeof(RDPResolutions),
|
||||
(string)dataRow["Resolution"]);
|
||||
connectionInfo.AutomaticResize = (bool)dataRow["AutomaticResize"];
|
||||
connectionInfo.DisplayWallpaper = (bool)dataRow["DisplayWallpaper"];
|
||||
connectionInfo.DisplayThemes = (bool)dataRow["DisplayThemes"];
|
||||
connectionInfo.EnableFontSmoothing = (bool)dataRow["EnableFontSmoothing"];
|
||||
connectionInfo.EnableDesktopComposition = (bool)dataRow["EnableDesktopComposition"];
|
||||
connectionInfo.DisableFullWindowDrag = (bool)dataRow["DisableFullWindowDrag"];
|
||||
connectionInfo.DisableMenuAnimations = (bool)dataRow["DisableMenuAnimations"];
|
||||
connectionInfo.DisableCursorShadow = (bool)dataRow["DisableCursorShadow"];
|
||||
connectionInfo.DisableCursorBlinking = (bool)dataRow["DisableCursorBlinking"];
|
||||
connectionInfo.CacheBitmaps = (bool)dataRow["CacheBitmaps"];
|
||||
connectionInfo.RedirectDiskDrives = (bool)dataRow["RedirectDiskDrives"];
|
||||
connectionInfo.RedirectPorts = (bool)dataRow["RedirectPorts"];
|
||||
connectionInfo.RedirectPrinters = (bool)dataRow["RedirectPrinters"];
|
||||
connectionInfo.RedirectClipboard = (bool)dataRow["RedirectClipboard"];
|
||||
connectionInfo.RedirectSmartCards = (bool)dataRow["RedirectSmartCards"];
|
||||
connectionInfo.RedirectSound =
|
||||
(RDPSounds)Enum.Parse(typeof(RDPSounds), (string)dataRow["RedirectSound"]);
|
||||
connectionInfo.SoundQuality = (RDPSoundQuality)Enum.Parse(typeof(RDPSoundQuality),
|
||||
(string)dataRow["SoundQuality"]);
|
||||
connectionInfo.RedirectAudioCapture = (bool)dataRow["RedirectAudioCapture"];
|
||||
|
||||
connectionInfo.RedirectKeys = (bool)dataRow["RedirectKeys"];
|
||||
connectionInfo.PreExtApp = (string)dataRow["PreExtApp"];
|
||||
connectionInfo.PostExtApp = (string)dataRow["PostExtApp"];
|
||||
connectionInfo.MacAddress = (string)dataRow["MacAddress"];
|
||||
connectionInfo.UserField = (string)dataRow["UserField"];
|
||||
connectionInfo.ExtApp = (string)dataRow["ExtApp"];
|
||||
connectionInfo.VNCCompression = (ProtocolVNC.Compression)Enum.Parse(typeof(ProtocolVNC.Compression),
|
||||
(string)dataRow["VNCCompression"]);
|
||||
connectionInfo.VNCEncoding =
|
||||
(ProtocolVNC.Encoding)Enum.Parse(typeof(ProtocolVNC.Encoding), (string)dataRow["VNCEncoding"]);
|
||||
connectionInfo.VNCAuthMode =
|
||||
(ProtocolVNC.AuthMode)Enum.Parse(typeof(ProtocolVNC.AuthMode), (string)dataRow["VNCAuthMode"]);
|
||||
connectionInfo.VNCProxyType =
|
||||
(ProtocolVNC.ProxyType)Enum.Parse(typeof(ProtocolVNC.ProxyType), (string)dataRow["VNCProxyType"]);
|
||||
connectionInfo.VNCProxyIP = (string)dataRow["VNCProxyIP"];
|
||||
connectionInfo.VNCProxyPort = (int)dataRow["VNCProxyPort"];
|
||||
connectionInfo.VNCProxyUsername = (string)dataRow["VNCProxyUsername"];
|
||||
connectionInfo.VNCProxyPassword = DecryptValue((string)dataRow["VNCProxyPassword"]);
|
||||
connectionInfo.VNCColors =
|
||||
(ProtocolVNC.Colors)Enum.Parse(typeof(ProtocolVNC.Colors), (string)dataRow["VNCColors"]);
|
||||
connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Enum.Parse(typeof(ProtocolVNC.SmartSizeMode),
|
||||
(string)dataRow
|
||||
["VNCSmartSizeMode"]);
|
||||
connectionInfo.VNCViewOnly = (bool)dataRow["VNCViewOnly"];
|
||||
connectionInfo.RDGatewayUsageMethod =
|
||||
(RDGatewayUsageMethod)Enum.Parse(typeof(RDGatewayUsageMethod),
|
||||
(string)dataRow["RDGatewayUsageMethod"]);
|
||||
connectionInfo.RDGatewayHostname = (string)dataRow["RDGatewayHostname"];
|
||||
connectionInfo.RDGatewayUseConnectionCredentials =
|
||||
(RDGatewayUseConnectionCredentials)Enum.Parse(typeof(RDGatewayUseConnectionCredentials),
|
||||
(string)dataRow["RDGatewayUseConnectionCredentials"]);
|
||||
connectionInfo.RDGatewayUsername = (string)dataRow["RDGatewayUsername"];
|
||||
connectionInfo.RDGatewayPassword = DecryptValue((string)dataRow["RDGatewayPassword"]);
|
||||
connectionInfo.RDGatewayDomain = (string)dataRow["RDGatewayDomain"];
|
||||
|
||||
if (!dataRow.IsNull("RdpVersion")) // table allows null values which must be handled
|
||||
if (Enum.TryParse((string)dataRow["RdpVersion"], true, out RdpVersion rdpVersion))
|
||||
connectionInfo.RdpVersion = rdpVersion;
|
||||
|
||||
connectionInfo.Inheritance.CacheBitmaps = (bool)dataRow["InheritCacheBitmaps"];
|
||||
connectionInfo.Inheritance.Colors = (bool)dataRow["InheritColors"];
|
||||
connectionInfo.Inheritance.Description = (bool)dataRow["InheritDescription"];
|
||||
connectionInfo.Inheritance.DisplayThemes = (bool)dataRow["InheritDisplayThemes"];
|
||||
connectionInfo.Inheritance.DisplayWallpaper = (bool)dataRow["InheritDisplayWallpaper"];
|
||||
connectionInfo.Inheritance.EnableFontSmoothing = (bool)dataRow["InheritEnableFontSmoothing"];
|
||||
connectionInfo.Inheritance.EnableDesktopComposition = (bool)dataRow["InheritEnableDesktopComposition"];
|
||||
connectionInfo.Inheritance.DisableFullWindowDrag = (bool)dataRow["InheritDisableFullWindowDrag"];
|
||||
connectionInfo.Inheritance.DisableMenuAnimations = (bool)dataRow["InheritDisableMenuAnimations"];
|
||||
connectionInfo.Inheritance.DisableCursorShadow = (bool)dataRow["InheritDisableCursorShadow"];
|
||||
connectionInfo.Inheritance.DisableCursorBlinking = (bool)dataRow["InheritDisableCursorBlinking"];
|
||||
connectionInfo.Inheritance.Domain = (bool)dataRow["InheritDomain"];
|
||||
connectionInfo.Inheritance.Icon = (bool)dataRow["InheritIcon"];
|
||||
connectionInfo.Inheritance.Panel = (bool)dataRow["InheritPanel"];
|
||||
connectionInfo.Inheritance.Password = (bool)dataRow["InheritPassword"];
|
||||
connectionInfo.Inheritance.Port = (bool)dataRow["InheritPort"];
|
||||
connectionInfo.Inheritance.Protocol = (bool)dataRow["InheritProtocol"];
|
||||
connectionInfo.Inheritance.SSHTunnelConnectionName = (bool)dataRow["InheritSSHTunnelConnectionName"];
|
||||
connectionInfo.Inheritance.SSHOptions = (bool)dataRow["InheritSSHOptions"];
|
||||
connectionInfo.Inheritance.PuttySession = (bool)dataRow["InheritPuttySession"];
|
||||
connectionInfo.Inheritance.RedirectDiskDrives = (bool)dataRow["InheritRedirectDiskDrives"];
|
||||
connectionInfo.Inheritance.RedirectKeys = (bool)dataRow["InheritRedirectKeys"];
|
||||
connectionInfo.Inheritance.RedirectPorts = (bool)dataRow["InheritRedirectPorts"];
|
||||
connectionInfo.Inheritance.RedirectPrinters = (bool)dataRow["InheritRedirectPrinters"];
|
||||
connectionInfo.Inheritance.RedirectClipboard = (bool)dataRow["InheritRedirectClipboard"];
|
||||
connectionInfo.Inheritance.RedirectSmartCards = (bool)dataRow["InheritRedirectSmartCards"];
|
||||
connectionInfo.Inheritance.RedirectSound = (bool)dataRow["InheritRedirectSound"];
|
||||
connectionInfo.Inheritance.SoundQuality = (bool)dataRow["InheritSoundQuality"];
|
||||
connectionInfo.Inheritance.RedirectAudioCapture = (bool)dataRow["InheritRedirectAudioCapture"];
|
||||
connectionInfo.Inheritance.Resolution = (bool)dataRow["InheritResolution"];
|
||||
connectionInfo.Inheritance.AutomaticResize = (bool)dataRow["InheritAutomaticResize"];
|
||||
connectionInfo.Inheritance.UseConsoleSession = (bool)dataRow["InheritUseConsoleSession"];
|
||||
connectionInfo.Inheritance.UseCredSsp = (bool)dataRow["InheritUseCredSsp"];
|
||||
connectionInfo.Inheritance.UseVmId = (bool)dataRow["InheritUseVmId"];
|
||||
connectionInfo.Inheritance.UseEnhancedMode = (bool)dataRow["InheritUseEnhancedMode"];
|
||||
connectionInfo.Inheritance.VmId = (bool)dataRow["InheritVmId"];
|
||||
connectionInfo.Inheritance.RenderingEngine = (bool)dataRow["InheritRenderingEngine"];
|
||||
connectionInfo.Inheritance.Username = (bool)dataRow["InheritUsername"];
|
||||
connectionInfo.Inheritance.RDPAuthenticationLevel = (bool)dataRow["InheritRDPAuthenticationLevel"];
|
||||
connectionInfo.Inheritance.RDPAlertIdleTimeout = (bool)dataRow["InheritRDPAlertIdleTimeout"];
|
||||
connectionInfo.Inheritance.RDPMinutesToIdleTimeout = (bool)dataRow["InheritRDPMinutesToIdleTimeout"];
|
||||
connectionInfo.Inheritance.LoadBalanceInfo = (bool)dataRow["InheritLoadBalanceInfo"];
|
||||
connectionInfo.Inheritance.PreExtApp = (bool)dataRow["InheritPreExtApp"];
|
||||
connectionInfo.Inheritance.PostExtApp = (bool)dataRow["InheritPostExtApp"];
|
||||
connectionInfo.Inheritance.MacAddress = (bool)dataRow["InheritMacAddress"];
|
||||
connectionInfo.Inheritance.UserField = (bool)dataRow["InheritUserField"];
|
||||
connectionInfo.Inheritance.ExtApp = (bool)dataRow["InheritExtApp"];
|
||||
connectionInfo.Inheritance.VNCCompression = (bool)dataRow["InheritVNCCompression"];
|
||||
connectionInfo.Inheritance.VNCEncoding = (bool)dataRow["InheritVNCEncoding"];
|
||||
connectionInfo.Inheritance.VNCAuthMode = (bool)dataRow["InheritVNCAuthMode"];
|
||||
connectionInfo.Inheritance.VNCProxyType = (bool)dataRow["InheritVNCProxyType"];
|
||||
connectionInfo.Inheritance.VNCProxyIP = (bool)dataRow["InheritVNCProxyIP"];
|
||||
connectionInfo.Inheritance.VNCProxyPort = (bool)dataRow["InheritVNCProxyPort"];
|
||||
connectionInfo.Inheritance.VNCProxyUsername = (bool)dataRow["InheritVNCProxyUsername"];
|
||||
connectionInfo.Inheritance.VNCProxyPassword = (bool)dataRow["InheritVNCProxyPassword"];
|
||||
connectionInfo.Inheritance.VNCColors = (bool)dataRow["InheritVNCColors"];
|
||||
connectionInfo.Inheritance.VNCSmartSizeMode = (bool)dataRow["InheritVNCSmartSizeMode"];
|
||||
connectionInfo.Inheritance.VNCViewOnly = (bool)dataRow["InheritVNCViewOnly"];
|
||||
connectionInfo.Inheritance.RDGatewayUsageMethod = (bool)dataRow["InheritRDGatewayUsageMethod"];
|
||||
connectionInfo.Inheritance.RDGatewayHostname = (bool)dataRow["InheritRDGatewayHostname"];
|
||||
connectionInfo.Inheritance.RDGatewayUseConnectionCredentials =
|
||||
(bool)dataRow["InheritRDGatewayUseConnectionCredentials"];
|
||||
connectionInfo.Inheritance.RDGatewayUsername = (bool)dataRow["InheritRDGatewayUsername"];
|
||||
connectionInfo.Inheritance.RDGatewayPassword = (bool)dataRow["InheritRDGatewayPassword"];
|
||||
connectionInfo.Inheritance.RDGatewayDomain = (bool)dataRow["InheritRDGatewayDomain"];
|
||||
connectionInfo.Inheritance.RdpVersion = (bool)dataRow["InheritRdpVersion"];
|
||||
}
|
||||
|
||||
private string DecryptValue(string cipherText)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _cryptographyProvider.Decrypt(cipherText, _decryptionKey);
|
||||
}
|
||||
catch (EncryptionException)
|
||||
{
|
||||
// value may not be encrypted
|
||||
return cipherText;
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectionTreeModel CreateNodeHierarchy(List<ConnectionInfo> connectionList, DataTable dataTable)
|
||||
{
|
||||
var connectionTreeModel = new ConnectionTreeModel();
|
||||
var rootNode = new RootNodeInfo(RootNodeType.Connection, "0")
|
||||
{
|
||||
PasswordString = _decryptionKey.ConvertToUnsecureString()
|
||||
};
|
||||
connectionTreeModel.AddRootNode(rootNode);
|
||||
|
||||
foreach (DataRow row in dataTable.Rows)
|
||||
{
|
||||
var id = (string)row["ConstantID"];
|
||||
var connectionInfo = connectionList.First(node => node.ConstantID == id);
|
||||
var parentId = (string)row["ParentID"];
|
||||
if (parentId == "0" || connectionList.All(node => node.ConstantID != parentId))
|
||||
rootNode.AddChild(connectionInfo);
|
||||
else
|
||||
(connectionList.First(node => node.ConstantID == parentId) as ContainerInfo)?.AddChild(
|
||||
connectionInfo);
|
||||
}
|
||||
|
||||
return connectionTreeModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -80,9 +80,9 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.MsSql
|
||||
if (rootTreeNode != null)
|
||||
{
|
||||
cmd = databaseConnector.DbCommand(
|
||||
"INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES('" +
|
||||
MiscTools.PrepareValueForDB(rootTreeNode.Name) + "', 0, '" + strProtected + "','" +
|
||||
ConnectionsFileInfo.ConnectionFileVersion.ToString() + "')");
|
||||
"INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES(\'" +
|
||||
MiscTools.PrepareValueForDB(rootTreeNode.Name) + "\', 0, \'" + strProtected + "\'," +
|
||||
ConnectionsFileInfo.ConnectionFileVersion.ToString(CultureInfo.InvariantCulture) + ")");
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Xml.Linq;
|
||||
using mRemoteNG.Connection;
|
||||
@@ -66,7 +66,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(new XAttribute("Hostname", connectionInfo.Hostname));
|
||||
element.Add(new XAttribute("Protocol", connectionInfo.Protocol));
|
||||
element.Add(new XAttribute("SSHTunnelConnectionName", connectionInfo.SSHTunnelConnectionName));
|
||||
element.Add(new XAttribute("OpeningCommand", connectionInfo.OpeningCommand));
|
||||
element.Add(new XAttribute("SSHOptions", connectionInfo.SSHOptions));
|
||||
element.Add(new XAttribute("PuttySession", connectionInfo.PuttySession));
|
||||
element.Add(new XAttribute("Port", connectionInfo.Port));
|
||||
@@ -99,7 +98,7 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(new XAttribute("MacAddress", connectionInfo.MacAddress));
|
||||
element.Add(new XAttribute("UserField", connectionInfo.UserField));
|
||||
element.Add(new XAttribute("ExtApp", connectionInfo.ExtApp));
|
||||
element.Add(new XAttribute("StartProgram", connectionInfo.RDPStartProgram));
|
||||
element.Add(new XAttribute("StartProgram", connectionInfo.StartProgram));
|
||||
element.Add(new XAttribute("VNCCompression", connectionInfo.VNCCompression));
|
||||
element.Add(new XAttribute("VNCEncoding", connectionInfo.VNCEncoding));
|
||||
element.Add(new XAttribute("VNCAuthMode", connectionInfo.VNCAuthMode));
|
||||
@@ -169,8 +168,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(new XAttribute("InheritProtocol", inheritance.Protocol.ToString().ToLowerInvariant()));
|
||||
if (inheritance.SSHTunnelConnectionName)
|
||||
element.Add(new XAttribute("InheritSSHTunnelConnectionName", inheritance.SSHTunnelConnectionName.ToString().ToLowerInvariant()));
|
||||
if (inheritance.OpeningCommand)
|
||||
element.Add(new XAttribute("InheritOpeningCommand", inheritance.OpeningCommand.ToString().ToLowerInvariant()));
|
||||
if (inheritance.SSHOptions)
|
||||
element.Add(new XAttribute("InheritSSHOptions", inheritance.SSHOptions.ToString().ToLowerInvariant()));
|
||||
if (inheritance.PuttySession)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Xml.Linq;
|
||||
using mRemoteNG.App;
|
||||
@@ -76,7 +76,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(new XAttribute("Protocol", connectionInfo.Protocol));
|
||||
element.Add(new XAttribute("RdpVersion", connectionInfo.RdpVersion.ToString().ToLowerInvariant()));
|
||||
element.Add(new XAttribute("SSHTunnelConnectionName", connectionInfo.SSHTunnelConnectionName));
|
||||
element.Add(new XAttribute("OpeningCommand", connectionInfo.OpeningCommand));
|
||||
element.Add(new XAttribute("SSHOptions", connectionInfo.SSHOptions));
|
||||
element.Add(new XAttribute("PuttySession", connectionInfo.PuttySession));
|
||||
element.Add(new XAttribute("Port", connectionInfo.Port));
|
||||
@@ -115,8 +114,7 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(new XAttribute("UserField", connectionInfo.UserField));
|
||||
element.Add(new XAttribute("Favorite", connectionInfo.Favorite));
|
||||
element.Add(new XAttribute("ExtApp", connectionInfo.ExtApp));
|
||||
element.Add(new XAttribute("StartProgram", connectionInfo.RDPStartProgram));
|
||||
element.Add(new XAttribute("StartProgramWorkDir", connectionInfo.RDPStartProgramWorkDir));
|
||||
element.Add(new XAttribute("StartProgram", connectionInfo.StartProgram));
|
||||
element.Add(new XAttribute("VNCCompression", connectionInfo.VNCCompression));
|
||||
element.Add(new XAttribute("VNCEncoding", connectionInfo.VNCEncoding));
|
||||
element.Add(new XAttribute("VNCAuthMode", connectionInfo.VNCAuthMode));
|
||||
@@ -150,10 +148,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(_saveFilter.SaveDomain
|
||||
? new XAttribute("RDGatewayDomain", connectionInfo.RDGatewayDomain)
|
||||
: new XAttribute("RDGatewayDomain", ""));
|
||||
|
||||
element.Add(new XAttribute("UserViaAPI", connectionInfo.UserViaAPI));
|
||||
element.Add(new XAttribute("EC2InstanceId", connectionInfo.EC2InstanceId));
|
||||
element.Add(new XAttribute("EC2Region", connectionInfo.EC2Region));
|
||||
}
|
||||
|
||||
private void SetInheritanceAttributes(XContainer element, IInheritable connectionInfo)
|
||||
@@ -200,8 +194,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(new XAttribute("InheritRdpVersion", inheritance.RdpVersion.ToString().ToLowerInvariant()));
|
||||
if (inheritance.SSHTunnelConnectionName)
|
||||
element.Add(new XAttribute("InheritSSHTunnelConnectionName", inheritance.SSHTunnelConnectionName.ToString().ToLowerInvariant()));
|
||||
if (inheritance.OpeningCommand)
|
||||
element.Add(new XAttribute("InheritOpeningCommand", inheritance.OpeningCommand.ToString().ToLowerInvariant()));
|
||||
if (inheritance.SSHOptions)
|
||||
element.Add(new XAttribute("InheritSSHOptions", inheritance.SSHOptions.ToString().ToLowerInvariant()));
|
||||
if (inheritance.PuttySession)
|
||||
@@ -296,8 +288,6 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
|
||||
element.Add(new XAttribute("InheritUseVmId", inheritance.UseVmId.ToString().ToLowerInvariant()));
|
||||
if (inheritance.UseEnhancedMode)
|
||||
element.Add(new XAttribute("InheritUseEnhancedMode", inheritance.UseEnhancedMode.ToString().ToLowerInvariant()));
|
||||
if (inheritance.UserViaAPI)
|
||||
element.Add(new XAttribute("InheritUserViaAPI", inheritance.UserViaAPI.ToString().ToLowerInvariant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,10 +6,10 @@ using mRemoteNG.Config.Import;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.MiscSerializers
|
||||
{
|
||||
|
||||
@@ -152,7 +152,7 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
|
||||
connectionInfo.RDGatewayHostname = value;
|
||||
break;
|
||||
case "alternate shell":
|
||||
connectionInfo.RDPStartProgram = value;
|
||||
connectionInfo.StartProgram = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
@@ -7,9 +7,9 @@ using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.RDP;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.MiscSerializers
|
||||
{
|
||||
@@ -183,8 +183,8 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
|
||||
{
|
||||
if (bool.TryParse(connectionSettingsNode.SelectSingleNode("./connectToConsole")?.InnerText, out var useConsole))
|
||||
connectionInfo.UseConsoleSession = useConsole;
|
||||
connectionInfo.RDPStartProgram = connectionSettingsNode.SelectSingleNode("./startProgram")?.InnerText;
|
||||
connectionInfo.RDPStartProgramWorkDir = connectionSettingsNode.SelectSingleNode("./startProgramWorkDir")?.InnerText;
|
||||
connectionInfo.StartProgram = connectionSettingsNode.SelectSingleNode("./startProgram")?.InnerText;
|
||||
// ./workingDir
|
||||
if (int.TryParse(connectionSettingsNode.SelectSingleNode("./port")?.InnerText, out var port))
|
||||
connectionInfo.Port = port;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Config.DatabaseConnectors;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using System;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.Versioning
|
||||
{
|
||||
public class SqlDatabaseVersionVerifier
|
||||
{
|
||||
protected readonly Version currentSupportedVersion = new Version(2, 9);
|
||||
|
||||
{
|
||||
private readonly IDatabaseConnector _databaseConnector;
|
||||
|
||||
public SqlDatabaseVersionVerifier(IDatabaseConnector DatabaseConnector)
|
||||
@@ -41,7 +39,6 @@ namespace mRemoteNG.Config.Serializers.Versioning
|
||||
new SqlVersion25To26Upgrader(_databaseConnector),
|
||||
new SqlVersion26To27Upgrader(_databaseConnector),
|
||||
new SqlVersion27To28Upgrader(_databaseConnector),
|
||||
new SqlVersion28To29Upgrader(_databaseConnector),
|
||||
};
|
||||
|
||||
foreach (var upgrader in dbUpgraders)
|
||||
@@ -53,7 +50,7 @@ namespace mRemoteNG.Config.Serializers.Versioning
|
||||
}
|
||||
|
||||
// DB is at the highest current supported version
|
||||
if (databaseVersion.CompareTo(currentSupportedVersion) == 0)
|
||||
if (databaseVersion.CompareTo(new Version(2, 8)) == 0)
|
||||
isVerified = true;
|
||||
|
||||
if (isVerified == false)
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Config.DatabaseConnectors;
|
||||
using mRemoteNG.Messages;
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers.Versioning
|
||||
{
|
||||
public class SqlVersion28To29Upgrader : IVersionUpgrader
|
||||
{
|
||||
private readonly Version version = new Version(2, 9);
|
||||
private readonly IDatabaseConnector _databaseConnector;
|
||||
|
||||
public SqlVersion28To29Upgrader(IDatabaseConnector databaseConnector)
|
||||
{
|
||||
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
|
||||
}
|
||||
|
||||
public bool CanUpgrade(Version currentVersion)
|
||||
{
|
||||
return currentVersion == new Version(2, 8) ||
|
||||
// Support upgrading during dev revisions, 2.9.1, 2.9.2, etc...
|
||||
(currentVersion <= new Version(2, 9) &&
|
||||
currentVersion < version);
|
||||
}
|
||||
|
||||
public Version Upgrade()
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg,
|
||||
string.Format("Upgrading database to version {0}.", version));
|
||||
|
||||
const string mySqlAlter = @"
|
||||
ALTER TABLE tblCons ADD COLUMN StartProgram varchar(512) DEFAULT NULL;
|
||||
ALTER TABLE tblCons ADD COLUMN StartProgramWorkDir varchar(512) DEFAULT NULL;
|
||||
ALTER TABLE tblRoot CHANGE COLUMN ConfVersion ConfVersion VARCHAR(15) NOT NULL;";
|
||||
const string mySqlUpdate = @"UPDATE tblRoot SET ConfVersion=?;";
|
||||
const string msSqlAlter = @"
|
||||
IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[tblCons]') AND name = 'StartProgram')
|
||||
BEGIN
|
||||
ALTER TABLE tblCons ADD StartProgram varchar(512), StartProgramWorkDir varchar(512);
|
||||
END;GO;
|
||||
ALTER TABLE tblRoot MODIFY COLUMN ConfVersion varchar(15);GO;";
|
||||
const string msSqlUpdate = @"UPDATE tblRoot SET ConfVersion=@confVersion;";
|
||||
using (var sqlTran = _databaseConnector.DbConnection().BeginTransaction(System.Data.IsolationLevel.Serializable))
|
||||
{
|
||||
DbCommand dbCommand;
|
||||
if (_databaseConnector.GetType() == typeof(MSSqlDatabaseConnector))
|
||||
{
|
||||
dbCommand = _databaseConnector.DbCommand(msSqlAlter);
|
||||
dbCommand.Transaction = sqlTran;
|
||||
dbCommand.ExecuteNonQuery();
|
||||
dbCommand = _databaseConnector.DbCommand(msSqlUpdate);
|
||||
dbCommand.Transaction = sqlTran;
|
||||
}
|
||||
else if (_databaseConnector.GetType() == typeof(MySqlDatabaseConnector))
|
||||
{
|
||||
dbCommand = _databaseConnector.DbCommand(mySqlAlter);
|
||||
dbCommand.Transaction = sqlTran;
|
||||
dbCommand.ExecuteNonQuery();
|
||||
dbCommand = _databaseConnector.DbCommand(mySqlUpdate);
|
||||
dbCommand.Transaction = sqlTran;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unknown database back-end");
|
||||
}
|
||||
var pConfVersion = dbCommand.CreateParameter();
|
||||
pConfVersion.ParameterName = "confVersion";
|
||||
pConfVersion.Value = version.ToString();
|
||||
pConfVersion.DbType = System.Data.DbType.String;
|
||||
pConfVersion.Direction = System.Data.ParameterDirection.Input;
|
||||
dbCommand.Parameters.Add(pConfVersion);
|
||||
|
||||
dbCommand.ExecuteNonQuery();
|
||||
sqlTran.Commit();
|
||||
}
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,9 @@ namespace mRemoteNG.Config.Settings
|
||||
|
||||
if (persistString == typeof(ErrorAndInfoWindow).ToString())
|
||||
return Windows.ErrorsForm;
|
||||
|
||||
if (persistString == typeof(ScreenshotManagerWindow).ToString())
|
||||
return Windows.ScreenshotForm;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,9 +15,8 @@ using mRemoteNG.Connection.Protocol.Telnet;
|
||||
using mRemoteNG.Connection.Protocol.VNC;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Properties;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.Tree;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
@@ -47,10 +46,10 @@ namespace mRemoteNG.Connection
|
||||
[Browsable(false)] public ContainerInfo Parent { get; internal set; }
|
||||
|
||||
[Browsable(false)]
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Global
|
||||
public bool IsQuickConnect { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool PleaseConnect { get; set; }
|
||||
[Browsable(false)] public bool PleaseConnect { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -67,7 +66,6 @@ namespace mRemoteNG.Connection
|
||||
SetTreeDisplayDefaults();
|
||||
SetConnectionDefaults();
|
||||
SetProtocolDefaults();
|
||||
SetRemoteDesktopServicesDefaults();
|
||||
SetRdGatewayDefaults();
|
||||
SetAppearanceDefaults();
|
||||
SetRedirectDefaults();
|
||||
@@ -201,10 +199,7 @@ namespace mRemoteNG.Connection
|
||||
|
||||
private bool ShouldThisPropertyBeInherited(string propertyName)
|
||||
{
|
||||
return
|
||||
Inheritance.InheritanceActive &&
|
||||
ParentIsValidInheritanceTarget() &&
|
||||
IsInheritanceTurnedOnForThisProperty(propertyName);
|
||||
return ParentIsValidInheritanceTarget() && IsInheritanceTurnedOnForThisProperty(propertyName);
|
||||
}
|
||||
|
||||
private bool ParentIsValidInheritanceTarget()
|
||||
@@ -296,7 +291,6 @@ namespace mRemoteNG.Connection
|
||||
private void SetConnectionDefaults()
|
||||
{
|
||||
Hostname = string.Empty;
|
||||
EC2Region = Settings.Default.ConDefaultEC2Region;
|
||||
}
|
||||
|
||||
private void SetProtocolDefaults()
|
||||
@@ -316,12 +310,6 @@ namespace mRemoteNG.Connection
|
||||
UseEnhancedMode = Settings.Default.ConDefaultUseEnhancedMode;
|
||||
}
|
||||
|
||||
private void SetRemoteDesktopServicesDefaults()
|
||||
{
|
||||
RDPStartProgram = string.Empty;
|
||||
RDPStartProgramWorkDir = string.Empty;
|
||||
}
|
||||
|
||||
private void SetRdGatewayDefaults()
|
||||
{
|
||||
RDGatewayUsageMethod = (RDGatewayUsageMethod)Enum.Parse(typeof(RDGatewayUsageMethod), Settings.Default.ConDefaultRDGatewayUsageMethod);
|
||||
@@ -368,9 +356,7 @@ namespace mRemoteNG.Connection
|
||||
MacAddress = Settings.Default.ConDefaultMacAddress;
|
||||
UserField = Settings.Default.ConDefaultUserField;
|
||||
Favorite = Settings.Default.ConDefaultFavorite;
|
||||
RDPStartProgram = Settings.Default.ConDefaultRDPStartProgram;
|
||||
RDPStartProgramWorkDir = Settings.Default.ConDefaultRDPStartProgram;
|
||||
OpeningCommand = Settings.Default.OpeningCommand;
|
||||
StartProgram = Settings.Default.ConDefaultStartProgram;
|
||||
}
|
||||
|
||||
private void SetVncDefaults()
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
{
|
||||
@@ -51,12 +50,6 @@ namespace mRemoteNG.Connection
|
||||
#endregion
|
||||
|
||||
#region Connection
|
||||
[LocalizedAttributes.LocalizedCategory(nameof(Language.Connection), 3),
|
||||
LocalizedAttributes.LocalizedDisplayNameInherit(nameof(Language.UserViaAPI)),
|
||||
LocalizedAttributes.LocalizedDescriptionInherit(nameof(Language.PropertyDescriptionUserViaAPI)),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
[Browsable(true)]
|
||||
public bool UserViaAPI { get; set; }
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory(nameof(Language.Connection), 3),
|
||||
LocalizedAttributes.LocalizedDisplayNameInherit(nameof(Language.Username)),
|
||||
@@ -99,15 +92,6 @@ namespace mRemoteNG.Connection
|
||||
[Browsable(true)]
|
||||
public bool SSHTunnelConnectionName { get; set; }
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory(nameof(Language.Connection), 3),
|
||||
LocalizedAttributes.LocalizedDisplayNameInheritAttribute(nameof(Language.OpeningCommand)),
|
||||
LocalizedAttributes.LocalizedDescriptionInheritAttribute(nameof(Language.PropertyDescriptionOpeningCommand)),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
|
||||
[Browsable(true)]
|
||||
public bool OpeningCommand { get; set; }
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protocol
|
||||
@@ -462,16 +446,7 @@ namespace mRemoteNG.Connection
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool VNCViewOnly {get; set;}
|
||||
#endregion
|
||||
|
||||
[Browsable(false)]
|
||||
public ConnectionInfo Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this inheritance object is enabled.
|
||||
/// When false, users of this object should not respect inheritance
|
||||
/// settings for individual properties.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public bool InheritanceActive => !(Parent is RootNodeInfo || Parent?.Parent is RootNodeInfo);
|
||||
[Browsable(false)] public ConnectionInfo Parent { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -488,6 +463,7 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
var newInheritance = (ConnectionInfoInheritance)MemberwiseClone();
|
||||
newInheritance.Parent = parent;
|
||||
newInheritance._tempInheritanceStorage = null;
|
||||
return newInheritance;
|
||||
}
|
||||
|
||||
@@ -545,22 +521,15 @@ namespace mRemoteNG.Connection
|
||||
/// <returns></returns>
|
||||
public IEnumerable<string> GetEnabledInheritanceProperties()
|
||||
{
|
||||
return InheritanceActive
|
||||
? GetProperties()
|
||||
.Where(property => (bool)property.GetValue(this))
|
||||
.Select(property => property.Name)
|
||||
.ToList()
|
||||
: Enumerable.Empty<string>();
|
||||
return GetProperties()
|
||||
.Where(property => (bool)property.GetValue(this))
|
||||
.Select(property => property.Name)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private bool FilterProperty(PropertyInfo propertyInfo)
|
||||
{
|
||||
var exclusions = new[]
|
||||
{
|
||||
nameof(EverythingInherited),
|
||||
nameof(Parent),
|
||||
nameof(InheritanceActive)
|
||||
};
|
||||
var exclusions = new[] {"EverythingInherited", "Parent"};
|
||||
var valueShouldNotBeFiltered = !exclusions.Contains(propertyInfo.Name);
|
||||
return valueShouldNotBeFiltered;
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@ using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Properties;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.UI.Panels;
|
||||
using mRemoteNG.UI.Tabs;
|
||||
using mRemoteNG.UI.Window;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
@@ -62,19 +62,6 @@ namespace mRemoteNG.Connection
|
||||
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(connectionInfo.EC2InstanceId))
|
||||
{
|
||||
try
|
||||
{
|
||||
string host = await ExternalConnectors.AWS.EC2FetchDataService.GetEC2InstanceDataAsync("AWSAPI:" + connectionInfo.EC2InstanceId, connectionInfo.EC2Region);
|
||||
if (!string.IsNullOrEmpty(host))
|
||||
connectionInfo.Hostname = host;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (connectionInfo.Hostname == "" && connectionInfo.Protocol != ProtocolType.IntApp)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg,
|
||||
|
||||
@@ -13,12 +13,12 @@ using mRemoteNG.Config.Serializers.ConnectionSerializers.MsSql;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Properties;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
{
|
||||
@@ -37,7 +37,6 @@ namespace mRemoteNG.Connection
|
||||
public string ConnectionFileName { get; private set; }
|
||||
public RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; }
|
||||
public DateTime LastSqlUpdate { get; set; }
|
||||
public DateTime LastFileUpdate { get; set; }
|
||||
|
||||
public ConnectionTreeModel ConnectionTreeModel { get; private set; }
|
||||
|
||||
@@ -78,16 +77,10 @@ namespace mRemoteNG.Connection
|
||||
|
||||
if (connectionString.Contains("@"))
|
||||
{
|
||||
var x = connectionString.Split('@');
|
||||
string[] x = connectionString.Split('@');
|
||||
uriBuilder.UserName = x[0];
|
||||
uriBuilder.Host = x[1];
|
||||
}
|
||||
if (uriBuilder.Host.Contains(":"))
|
||||
{
|
||||
var x = uriBuilder.Host.Split(':');
|
||||
uriBuilder.Host = x[0];
|
||||
uriBuilder.Port = Convert.ToInt32(x[1]);
|
||||
}
|
||||
else
|
||||
uriBuilder.Host = connectionString;
|
||||
|
||||
@@ -99,12 +92,16 @@ namespace mRemoteNG.Connection
|
||||
: uriBuilder.Host;
|
||||
|
||||
newConnectionInfo.Protocol = protocol;
|
||||
newConnectionInfo.Hostname = uriBuilder.Host;
|
||||
newConnectionInfo.Username = uriBuilder.UserName;
|
||||
|
||||
if (uriBuilder.Port == -1)
|
||||
{
|
||||
newConnectionInfo.SetDefaultPort();
|
||||
}
|
||||
else
|
||||
{
|
||||
newConnectionInfo.Port = uriBuilder.Port;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newConnectionInfo.Panel))
|
||||
newConnectionInfo.Panel = Language.General;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright © 2013 The CefSharp Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
using CefSharp;
|
||||
using System;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.Http
|
||||
{
|
||||
public class DownloadHandler : IDownloadHandler
|
||||
{
|
||||
public event EventHandler<DownloadItem> OnBeforeDownloadFired;
|
||||
|
||||
public event EventHandler<DownloadItem> OnDownloadUpdatedFired;
|
||||
|
||||
public void OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IBeforeDownloadCallback callback)
|
||||
{
|
||||
OnBeforeDownloadFired?.Invoke(this, downloadItem);
|
||||
|
||||
if (!callback.IsDisposed)
|
||||
{
|
||||
using (callback)
|
||||
{
|
||||
callback.Continue(downloadItem.SuggestedFileName, showDialog: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IDownloadItemCallback callback)
|
||||
{
|
||||
OnDownloadUpdatedFired?.Invoke(this, downloadItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using CefSharp;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.Http
|
||||
{
|
||||
partial class RequestHandler : IRequestHandler
|
||||
{
|
||||
public bool GetAuthCredentials(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
|
||||
{
|
||||
if (request.Url.StartsWith(Cef.CefCommitHash))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Process.Start(request.Url);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDocumentAvailableInMainFrame(IWebBrowser chromiumWebBrowser, IBrowser browser)
|
||||
{
|
||||
}
|
||||
|
||||
public bool OnCertificateError(IWebBrowser chromiumWebBrowser, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool OnOpenUrlFromTab(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnPluginCrashed(IWebBrowser chromiumWebBrowser, IBrowser browser, string pluginPath)
|
||||
{
|
||||
}
|
||||
|
||||
public bool OnQuotaRequest(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, long newSize, IRequestCallback callback)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnRenderProcessTerminated(IWebBrowser chromiumWebBrowser, IBrowser browser, CefTerminationStatus status)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRenderViewReady(IWebBrowser chromiumWebBrowser, IBrowser browser)
|
||||
{
|
||||
}
|
||||
|
||||
public bool OnSelectClientCertificate(IWebBrowser chromiumWebBrowser, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Web.WebView2.WinForms;
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.UI.Tabs;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.UI.Tabs;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.Http
|
||||
@@ -13,22 +14,24 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
{
|
||||
#region Private Properties
|
||||
|
||||
private Control _wBrowser;
|
||||
private string _tabTitle;
|
||||
private Control wBrowser;
|
||||
protected string httpOrS;
|
||||
protected int defaultPort;
|
||||
private string tabTitle;
|
||||
private bool browserInitialised = false;
|
||||
private bool connectCalled = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
protected HTTPBase(RenderingEngine renderingEngine)
|
||||
protected HTTPBase(RenderingEngine RenderingEngine)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (renderingEngine == RenderingEngine.EdgeChromium)
|
||||
if (RenderingEngine == RenderingEngine.CEF)
|
||||
{
|
||||
Control = new WebView2()
|
||||
Control = new ChromiumWebBrowser("about:blank")
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
};
|
||||
@@ -50,26 +53,33 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
|
||||
try
|
||||
{
|
||||
if (InterfaceControl.Parent is ConnectionTab objConnectionTab) _tabTitle = objConnectionTab.TabText;
|
||||
if (InterfaceControl.Parent is ConnectionTab objConnectionTab) tabTitle = objConnectionTab.TabText;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_tabTitle = "";
|
||||
tabTitle = "";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_wBrowser = Control;
|
||||
wBrowser = Control;
|
||||
|
||||
if (InterfaceControl.Info.RenderingEngine == RenderingEngine.EdgeChromium)
|
||||
if (InterfaceControl.Info.RenderingEngine == RenderingEngine.CEF)
|
||||
{
|
||||
var edge = (WebView2)_wBrowser;
|
||||
|
||||
edge.CoreWebView2InitializationCompleted += Edge_CoreWebView2InitializationCompleted;
|
||||
var CEFBrowser = (ChromiumWebBrowser)wBrowser;
|
||||
if (CEFBrowser != null)
|
||||
{
|
||||
CEFBrowser.LoadingStateChanged += CefBrowser_LoadingStateChanged;
|
||||
CEFBrowser.TitleChanged += WBrowser_DocumentTitleChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Failed to initialize CEF Rendering Engine.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var objWebBrowser = (WebBrowser)_wBrowser;
|
||||
var objWebBrowser = (WebBrowser)wBrowser;
|
||||
objWebBrowser.ScrollBarsEnabled = true;
|
||||
|
||||
// http://stackoverflow.com/questions/4655662/how-to-ignore-script-errors-in-webbrowser
|
||||
@@ -77,6 +87,7 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
|
||||
objWebBrowser.Navigated += WBrowser_Navigated;
|
||||
objWebBrowser.DocumentTitleChanged += WBrowser_DocumentTitleChanged;
|
||||
browserInitialised = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -92,16 +103,20 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
{
|
||||
try
|
||||
{
|
||||
if (InterfaceControl.Info.RenderingEngine == RenderingEngine.EdgeChromium)
|
||||
if (InterfaceControl.Info.RenderingEngine == RenderingEngine.CEF)
|
||||
{
|
||||
((WebView2)_wBrowser).Source = new Uri(GetUrl());
|
||||
if (browserInitialised)
|
||||
{
|
||||
((ChromiumWebBrowser)wBrowser).Load(GetURL());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((WebBrowser)_wBrowser).Navigate(GetUrl());
|
||||
((WebBrowser)wBrowser).Navigate(GetURL());
|
||||
}
|
||||
|
||||
base.Connect();
|
||||
connectCalled = true;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -115,12 +130,22 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private string GetUrl()
|
||||
private string GetURL()
|
||||
{
|
||||
try
|
||||
{
|
||||
var strHost = InterfaceControl.Info.Hostname;
|
||||
/*
|
||||
* Commenting out since this codes doesn't actually do anything at this time...
|
||||
* Possibly related to MR-221 and/or MR-533 ????
|
||||
*
|
||||
string strAuth = "";
|
||||
|
||||
if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) != (int)ConnectionInfo.Force.NoCredentials && !string.IsNullOrEmpty(InterfaceControl.Info.Username) && !string.IsNullOrEmpty(InterfaceControl.Info.Password))
|
||||
{
|
||||
strAuth = "Authorization: Basic " + Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(InterfaceControl.Info.Username + ":" + InterfaceControl.Info.Password)) + Environment.NewLine;
|
||||
}
|
||||
*/
|
||||
if (InterfaceControl.Info.Port != defaultPort)
|
||||
{
|
||||
if (strHost.EndsWith("/"))
|
||||
@@ -136,7 +161,6 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
if (strHost.Contains(httpOrS + "://") == false)
|
||||
strHost = httpOrS + "://" + strHost;
|
||||
}
|
||||
|
||||
return strHost;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -150,17 +174,26 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
|
||||
#region Events
|
||||
|
||||
private void Edge_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
|
||||
private void CefBrowser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
|
||||
{
|
||||
if (!e.IsSuccess)
|
||||
browserInitialised = !e.IsLoading;
|
||||
if (browserInitialised)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.HttpFailedUrlBuild, e.InitializationException);
|
||||
// Unhook the loading state changes now, as navigation is done by the user on links in the control
|
||||
((ChromiumWebBrowser)wBrowser).LoadingStateChanged -= CefBrowser_LoadingStateChanged;
|
||||
|
||||
// If this Connection has already been asked to connect but the browser hadn't finished initalising
|
||||
// then the connect wouldn't have been allowed to take place, so now we can call it!
|
||||
if (connectCalled)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
|
||||
{
|
||||
if (!(_wBrowser is WebBrowser objWebBrowser)) return;
|
||||
if (!(wBrowser is WebBrowser objWebBrowser)) return;
|
||||
|
||||
// This can only be set once the WebBrowser control is shown, it will throw a COM exception otherwise.
|
||||
objWebBrowser.AllowWebBrowserDrop = false;
|
||||
@@ -174,18 +207,33 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
{
|
||||
if (!(InterfaceControl.Parent is ConnectionTab tabP)) return;
|
||||
string shortTitle;
|
||||
if (((WebBrowser)_wBrowser).DocumentTitle.Length >= 15)
|
||||
|
||||
if (InterfaceControl.Info.RenderingEngine == RenderingEngine.CEF)
|
||||
{
|
||||
shortTitle = ((WebBrowser)_wBrowser).DocumentTitle.Substring(0, 10) + "...";
|
||||
if (((TitleChangedEventArgs)e).Title.Length >= 15)
|
||||
{
|
||||
shortTitle = ((TitleChangedEventArgs)e).Title.Substring(0, 10) + "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
shortTitle = ((CefSharp.TitleChangedEventArgs)e).Title;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shortTitle = ((WebBrowser)_wBrowser).DocumentTitle;
|
||||
if (((WebBrowser)wBrowser).DocumentTitle.Length >= 15)
|
||||
{
|
||||
shortTitle = ((WebBrowser)wBrowser).DocumentTitle.Substring(0, 10) + "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
shortTitle = ((WebBrowser)wBrowser).DocumentTitle;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(_tabTitle))
|
||||
if (!string.IsNullOrEmpty(tabTitle))
|
||||
{
|
||||
tabP.TabText = _tabTitle + @" - " + shortTitle;
|
||||
tabP.TabText = tabTitle + @" - " + shortTitle;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -198,6 +246,38 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void geckoBrowser_DocumentTitleChanged(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!(InterfaceControl.Parent is ConnectionTab tabP)) return;
|
||||
string shortTitle;
|
||||
|
||||
if (((WebBrowser)wBrowser).DocumentTitle.Length >= 15)
|
||||
{
|
||||
shortTitle = ((WebBrowser)wBrowser).DocumentTitle.Substring(0, 10) + "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
shortTitle = ((WebBrowser)wBrowser).DocumentTitle;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(tabTitle))
|
||||
{
|
||||
tabP.TabText = tabTitle + @" - " + shortTitle;
|
||||
}
|
||||
else
|
||||
{
|
||||
tabP.TabText = shortTitle;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.HttpDocumentTileChangeFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Enums
|
||||
@@ -208,7 +288,7 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
IE = 1,
|
||||
|
||||
[LocalizedAttributes.LocalizedDescription(nameof(Language.HttpCEF))]
|
||||
EdgeChromium = 2
|
||||
CEF = 2
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -6,8 +6,8 @@ using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Properties;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
|
||||
@@ -82,19 +82,6 @@ namespace mRemoteNG.Connection.Protocol
|
||||
var username = "";
|
||||
var password = "";
|
||||
|
||||
// access secret server api if necessary
|
||||
if (!string.IsNullOrEmpty(InterfaceControl.Info?.UserViaAPI))
|
||||
{
|
||||
var domain = ""; // dummy
|
||||
try
|
||||
{
|
||||
ExternalConnectors.TSS.SecretServerInterface.FetchSecretFromServer("SSAPI:" + InterfaceControl.Info?.UserViaAPI, out username, out password, out domain);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(InterfaceControl.Info?.Username))
|
||||
{
|
||||
username = InterfaceControl.Info.Username;
|
||||
@@ -201,13 +188,6 @@ namespace mRemoteNG.Connection.Protocol
|
||||
string.Format(Language.PanelHandle,
|
||||
InterfaceControl.Parent.Handle), true);
|
||||
|
||||
if (!string.IsNullOrEmpty(InterfaceControl.Info?.OpeningCommand))
|
||||
{
|
||||
NativeMethods.SetForegroundWindow(PuttyHandle);
|
||||
var finalCommand = InterfaceControl.Info.OpeningCommand.TrimEnd() + "\n";
|
||||
SendKeys.SendWait(finalCommand);
|
||||
}
|
||||
|
||||
Resize(this, new EventArgs());
|
||||
base.Connect();
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,8 @@ using System.Windows.Forms;
|
||||
using AxMSTSCLib;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Messages;
|
||||
using MSTSCLib;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using MSTSCLib;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
|
||||
@@ -3,20 +3,36 @@ using System.Threading;
|
||||
using System.ComponentModel;
|
||||
using System.Net.Sockets;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
// ReSharper disable ArrangeAccessorOwnerBody
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.VNC
|
||||
{
|
||||
public class ProtocolVNC : ProtocolBase
|
||||
public class ProtocolVNC : ProtocolBase, ISupportsViewOnly
|
||||
{
|
||||
#region Properties
|
||||
|
||||
public bool SmartSize
|
||||
{
|
||||
get => _vnc.Scaled;
|
||||
set => _vnc.Scaled = value;
|
||||
}
|
||||
|
||||
public bool ViewOnly
|
||||
{
|
||||
get => _vnc.ViewOnly;
|
||||
set => _vnc.ViewOnly = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Declarations
|
||||
|
||||
private VncSharpCore.RemoteDesktop _vnc;
|
||||
private VncSharp.RemoteDesktop _vnc;
|
||||
private ConnectionInfo _info;
|
||||
private static bool _isConnectionSuccessful;
|
||||
private static Exception _socketexception;
|
||||
@@ -28,7 +44,7 @@ namespace mRemoteNG.Connection.Protocol.VNC
|
||||
|
||||
public ProtocolVNC()
|
||||
{
|
||||
Control = new VncSharpCore.RemoteDesktop();
|
||||
Control = new VncSharp.RemoteDesktop();
|
||||
}
|
||||
|
||||
public override bool Initialize()
|
||||
@@ -37,7 +53,7 @@ namespace mRemoteNG.Connection.Protocol.VNC
|
||||
|
||||
try
|
||||
{
|
||||
_vnc = (VncSharpCore.RemoteDesktop)Control;
|
||||
_vnc = (VncSharp.RemoteDesktop)Control;
|
||||
_info = InterfaceControl.Info;
|
||||
_vnc.VncPort = _info.Port;
|
||||
|
||||
@@ -93,10 +109,10 @@ namespace mRemoteNG.Connection.Protocol.VNC
|
||||
switch (Keys)
|
||||
{
|
||||
case SpecialKeys.CtrlAltDel:
|
||||
_vnc.SendSpecialKeys(VncSharpCore.SpecialKeys.CtrlAltDel);
|
||||
_vnc.SendSpecialKeys(VncSharp.SpecialKeys.CtrlAltDel);
|
||||
break;
|
||||
case SpecialKeys.CtrlEsc:
|
||||
_vnc.SendSpecialKeys(VncSharpCore.SpecialKeys.CtrlEsc);
|
||||
_vnc.SendSpecialKeys(VncSharp.SpecialKeys.CtrlEsc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -108,6 +124,36 @@ namespace mRemoteNG.Connection.Protocol.VNC
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleSmartSize()
|
||||
{
|
||||
try
|
||||
{
|
||||
SmartSize = !SmartSize;
|
||||
RefreshScreen();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
|
||||
Language.VncToggleSmartSizeFailed + Environment.NewLine +
|
||||
ex.Message, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleViewOnly()
|
||||
{
|
||||
try
|
||||
{
|
||||
ViewOnly = !ViewOnly;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
|
||||
Language.VncToggleViewOnlyFailed + Environment.NewLine +
|
||||
ex.Message, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void StartChat()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol.VNC
|
||||
{
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Tools;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.Resources.Language;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
|
||||
@@ -263,34 +263,6 @@ namespace mRemoteNG.Container
|
||||
return childList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the connection properties of this container to all
|
||||
/// children recursively.
|
||||
/// </summary>
|
||||
public void ApplyConnectionPropertiesToChildren()
|
||||
{
|
||||
var children = GetRecursiveChildList();
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
child.CopyFrom(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the inheritance settings of this container to all
|
||||
/// children recursively.
|
||||
/// </summary>
|
||||
public void ApplyInheritancePropertiesToChildren()
|
||||
{
|
||||
var children = GetRecursiveChildList();
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
child.Inheritance = Inheritance.Clone(child);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<ConnectionInfo> GetRecursiveFavoritChildList(ContainerInfo container)
|
||||
{
|
||||
var childList = new List<ConnectionInfo>();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user