mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Merge branch 'develop' into sql_test_connection
# Conflicts: # mRemoteV1/Resources/Language/Language.Designer.cs # mRemoteV1/Resources/Language/Language.resx # mRemoteV1/mRemoteV1.csproj
This commit is contained in:
@@ -77,6 +77,10 @@ IP TextBox
|
||||
Copyright <20> 2005 mawnkay
|
||||
http://www.codeproject.com/Articles/11576/IP-TextBox
|
||||
|
||||
PortableSettingsProvider
|
||||
Copyright <20> 2014 crdx
|
||||
https://github.com/crdx/PortableSettingsProvider
|
||||
|
||||
|
||||
Included Components
|
||||
===================
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using mRemoteNG.Config.Connections;
|
||||
using mRemoteNGTests.TestHelpers;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace mRemoteNGTests.Config.Connections
|
||||
{
|
||||
class XmlConnectionsLoaderTests
|
||||
{
|
||||
[Test]
|
||||
public void ThrowsFileNotFound()
|
||||
{
|
||||
Assert.Throws<FileNotFoundException>(() => (new XmlConnectionsLoader(FileTestHelpers.NewTempFilePath())).Load());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tools.CustomCollections;
|
||||
using mRemoteNG.UI.Window;
|
||||
using NUnit.Framework;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
@@ -44,7 +45,7 @@ namespace mRemoteNGTests.Connection.Protocol
|
||||
|
||||
private void SetExternalToolList(ExternalTool externalTool)
|
||||
{
|
||||
Runtime.ExternalToolsService.ExternalTools = new ObservableCollection<ExternalTool> {externalTool};
|
||||
Runtime.ExternalToolsService.ExternalTools = new FullyObservableCollection<ExternalTool> {externalTool};
|
||||
}
|
||||
|
||||
private InterfaceControl BuildInterfaceControl(string extAppName, ProtocolBase sut)
|
||||
|
||||
@@ -138,7 +138,49 @@ namespace mRemoteNG.App
|
||||
if (ex is FileNotFoundException && !withDialog)
|
||||
{
|
||||
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionsLoader.ConnectionFileName), ex, MessageClass.InformationMsg);
|
||||
ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName);
|
||||
|
||||
string[] commandButtons =
|
||||
{
|
||||
Language.ConfigurationCreateNew,
|
||||
Language.ConfigurationCustomPath,
|
||||
Language.ConfigurationImportFile,
|
||||
Language.strMenuExit
|
||||
};
|
||||
|
||||
bool answered = false;
|
||||
while (!answered)
|
||||
{
|
||||
try
|
||||
{
|
||||
CTaskDialog.ShowTaskDialogBox(GeneralAppInfo.ProductName, Language.ConfigurationFileNotFound, "", "", "", "", "", string.Join(" | ", commandButtons), ETaskDialogButtons.None, ESysIcons.Question, ESysIcons.Question);
|
||||
|
||||
switch (CTaskDialog.CommandButtonResult)
|
||||
{
|
||||
case 0:
|
||||
ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName);
|
||||
answered = true;
|
||||
break;
|
||||
case 1:
|
||||
LoadConnections(true);
|
||||
answered = true;
|
||||
break;
|
||||
case 2:
|
||||
ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName);
|
||||
Import.ImportFromFile(ConnectionsService.ConnectionTreeModel.RootNodes[0]);
|
||||
answered = true;
|
||||
break;
|
||||
case 3:
|
||||
Application.Exit();
|
||||
answered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionsLoader.ConnectionFileName), exc, MessageClass.InformationMsg);
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using mRemoteNG.Config.DataProviders;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using System.IO;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
@@ -16,6 +17,9 @@ namespace mRemoteNG.Config.Connections
|
||||
if (string.IsNullOrEmpty(connectionFilePath))
|
||||
throw new ArgumentException($"{nameof(connectionFilePath)} cannot be null or empty");
|
||||
|
||||
if (!File.Exists(connectionFilePath))
|
||||
throw new FileNotFoundException($"{connectionFilePath} does not exist");
|
||||
|
||||
_connectionFilePath = connectionFilePath;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,12 @@ namespace mRemoteNG.Config.Settings
|
||||
Arguments = xEl.Attributes["Arguments"].Value
|
||||
};
|
||||
|
||||
// check before, since old save files won't have this set
|
||||
if (xEl.HasAttribute("WorkingDir"))
|
||||
extA.WorkingDir = xEl.Attributes["WorkingDir"].Value;
|
||||
if (xEl.HasAttribute("RunElevated"))
|
||||
extA.RunElevated = bool.Parse(xEl.Attributes["RunElevated"].Value);
|
||||
|
||||
if (xEl.HasAttribute("WaitForExit"))
|
||||
{
|
||||
extA.WaitForExit = bool.Parse(xEl.Attributes["WaitForExit"].Value);
|
||||
@@ -82,6 +88,11 @@ namespace mRemoteNG.Config.Settings
|
||||
extA.TryIntegrate = bool.Parse(xEl.Attributes["TryToIntegrate"].Value);
|
||||
}
|
||||
|
||||
if (xEl.HasAttribute("ShowOnToolbar"))
|
||||
{
|
||||
extA.ShowOnToolbar = bool.Parse(xEl.Attributes["ShowOnToolbar"].Value);
|
||||
}
|
||||
|
||||
_messageCollector.AddMessage(MessageClass.InformationMsg, $"Adding External App: {extA.DisplayName} {extA.FileName} {extA.Arguments}", true);
|
||||
Runtime.ExternalToolsService.ExternalTools.Add(extA);
|
||||
}
|
||||
|
||||
@@ -37,8 +37,11 @@ namespace mRemoteNG.Config.Settings
|
||||
xmlTextWriter.WriteAttributeString("DisplayName", "", extA.DisplayName);
|
||||
xmlTextWriter.WriteAttributeString("FileName", "", extA.FileName);
|
||||
xmlTextWriter.WriteAttributeString("Arguments", "", extA.Arguments);
|
||||
xmlTextWriter.WriteAttributeString("WorkingDir", "", extA.WorkingDir);
|
||||
xmlTextWriter.WriteAttributeString("WaitForExit", "", Convert.ToString(extA.WaitForExit));
|
||||
xmlTextWriter.WriteAttributeString("TryToIntegrate", "", Convert.ToString(extA.TryIntegrate));
|
||||
xmlTextWriter.WriteAttributeString("RunElevated", "", Convert.ToString(extA.RunElevated));
|
||||
xmlTextWriter.WriteAttributeString("ShowOnToolbar", "", Convert.ToString(extA.ShowOnToolbar));
|
||||
xmlTextWriter.WriteEndElement();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
#if false
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml;
|
||||
|
||||
|
||||
namespace mRemoteNG.Config.Settings.Providers
|
||||
{
|
||||
public class AppSettingsProvider : SettingsProvider
|
||||
{
|
||||
const string SETTINGSROOT = "Settings"; //XML Root Node
|
||||
|
||||
public override void Initialize(string name, NameValueCollection col)
|
||||
{
|
||||
if (Application.ProductName.Trim().Length > 0)
|
||||
{
|
||||
_applicationName = Application.ProductName;
|
||||
}
|
||||
else
|
||||
{
|
||||
_applicationName = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
|
||||
}
|
||||
|
||||
base.Initialize(ApplicationName, col);
|
||||
|
||||
/*
|
||||
if (!File.Exists(GetDotSettingsFile()))
|
||||
{
|
||||
// do something smart.
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private string _applicationName;
|
||||
public override string ApplicationName
|
||||
{
|
||||
get { return _applicationName; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public virtual string GetDotSettingsFile()
|
||||
{
|
||||
return Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename());
|
||||
}
|
||||
|
||||
|
||||
public virtual string GetAppSettingsPath()
|
||||
{
|
||||
//Used to determine where to store the settings
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Application.ProductName);
|
||||
}
|
||||
|
||||
public virtual string GetAppSettingsFilename()
|
||||
{
|
||||
//Used to determine the filename to store the settings
|
||||
return Application.ProductName + ".settings";
|
||||
}
|
||||
|
||||
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
|
||||
{
|
||||
//Iterate through the settings to be stored
|
||||
//Only dirty settings are included in propvals, and only ones relevant to this provider
|
||||
foreach (SettingsPropertyValue propval in propvals)
|
||||
{
|
||||
SetValue(propval);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SettingsXml.Save(GetDotSettingsFile());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Ignore if cant save, device been ejected
|
||||
}
|
||||
}
|
||||
|
||||
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props)
|
||||
{
|
||||
//Create new collection of values
|
||||
var values = new SettingsPropertyValueCollection();
|
||||
|
||||
//Iterate through the settings to be retrieved
|
||||
foreach (SettingsProperty setting in props)
|
||||
{
|
||||
|
||||
var value = new SettingsPropertyValue(setting)
|
||||
{
|
||||
IsDirty = false,
|
||||
SerializedValue = GetValue(setting)
|
||||
};
|
||||
values.Add(value);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private XmlDocument _SettingsXml;
|
||||
|
||||
private XmlDocument SettingsXml
|
||||
{
|
||||
get
|
||||
{
|
||||
//If we dont hold an xml document, try opening one.
|
||||
//If it doesnt exist then create a new one ready.
|
||||
if (_SettingsXml == null)
|
||||
{
|
||||
_SettingsXml = new XmlDocument();
|
||||
|
||||
try
|
||||
{
|
||||
_SettingsXml.Load(GetDotSettingsFile());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Create new document
|
||||
var dec = _SettingsXml.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
|
||||
_SettingsXml.AppendChild(dec);
|
||||
|
||||
var nodeRoot = _SettingsXml.CreateNode(XmlNodeType.Element, SETTINGSROOT, "");
|
||||
_SettingsXml.AppendChild(nodeRoot);
|
||||
}
|
||||
}
|
||||
return _SettingsXml;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetValue(SettingsProperty setting)
|
||||
{
|
||||
var ret = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
if (IsRoaming(setting))
|
||||
{
|
||||
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + setting.Name).InnerText;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + Environment.MachineName + "/" + setting.Name).InnerText;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
ret = setting.DefaultValue?.ToString() ?? "";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void SetValue(SettingsPropertyValue propVal)
|
||||
{
|
||||
System.Xml.XmlElement MachineNode = default(System.Xml.XmlElement);
|
||||
System.Xml.XmlElement SettingNode = default(System.Xml.XmlElement);
|
||||
|
||||
//Determine if the setting is roaming.
|
||||
//If roaming then the value is stored as an element under the root
|
||||
//Otherwise it is stored under a machine name node
|
||||
try
|
||||
{
|
||||
if (IsRoaming(propVal.Property))
|
||||
{
|
||||
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + propVal.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name + "/" + propVal.Name));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
SettingNode = null;
|
||||
}
|
||||
|
||||
//Check to see if the node exists, if so then set its new value
|
||||
if (SettingNode != null)
|
||||
{
|
||||
if (propVal.SerializedValue != null)
|
||||
{
|
||||
SettingNode.InnerText = propVal.SerializedValue.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsRoaming(propVal.Property))
|
||||
{
|
||||
//Store the value as an element of the Settings Root Node
|
||||
SettingNode = SettingsXml.CreateElement(propVal.Name);
|
||||
if (propVal.SerializedValue != null)
|
||||
{
|
||||
SettingNode.InnerText = propVal.SerializedValue.ToString();
|
||||
}
|
||||
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(SettingNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Its machine specific, store as an element of the machine name node,
|
||||
//creating a new machine name node if one doesnt exist.
|
||||
try
|
||||
{
|
||||
MachineNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
|
||||
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
|
||||
}
|
||||
|
||||
if (MachineNode == null)
|
||||
{
|
||||
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
|
||||
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
|
||||
}
|
||||
|
||||
SettingNode = SettingsXml.CreateElement(propVal.Name);
|
||||
if (propVal.SerializedValue != null)
|
||||
{
|
||||
SettingNode.InnerText = propVal.SerializedValue.ToString();
|
||||
}
|
||||
MachineNode.AppendChild(SettingNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsRoaming(SettingsProperty prop)
|
||||
{
|
||||
//Determine if the setting is marked as Roaming
|
||||
//For Each d As DictionaryEntry In prop.Attributes
|
||||
// Dim a As Attribute = DirectCast(d.Value, Attribute)
|
||||
// If TypeOf a Is System.Configuration.SettingsManageabilityAttribute Then
|
||||
// Return True
|
||||
// End If
|
||||
//Next
|
||||
//Return False
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,12 +1,11 @@
|
||||
namespace mRemoteNG.Config.Settings.Providers
|
||||
using System.Configuration;
|
||||
|
||||
namespace mRemoteNG.Config.Settings.Providers
|
||||
{
|
||||
#if false
|
||||
#if PORTABLE
|
||||
public class ChooseProvider : PortableSettingsProvider
|
||||
#else
|
||||
public class ChooseProvider : AppSettingsProvider
|
||||
#endif
|
||||
{
|
||||
}
|
||||
public class ChooseProvider : LocalFileSettingsProvider
|
||||
#endif
|
||||
{ }
|
||||
}
|
||||
@@ -1,234 +1,245 @@
|
||||
#if false
|
||||
/// The MIT License (MIT)
|
||||
///
|
||||
/// Copyright(c) crdx
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining
|
||||
/// a copy of this software and associated documentation files (the
|
||||
/// "Software"), to deal in the Software without restriction, including
|
||||
/// without limitation the rights to use, copy, modify, merge, publish,
|
||||
/// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
/// permit persons to whom the Software is furnished to do so, subject to
|
||||
/// the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be
|
||||
/// included in all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
/// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
/// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
/// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
/// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///
|
||||
/// https://raw.githubusercontent.com/crdx/PortableSettingsProvider
|
||||
///
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Collections.Specialized;
|
||||
using System.Xml;
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace mRemoteNG.Config.Settings.Providers
|
||||
{
|
||||
public class PortableSettingsProvider : SettingsProvider
|
||||
{
|
||||
const string SETTINGSROOT = "Settings"; //XML Root Node
|
||||
public class PortableSettingsProvider : SettingsProvider, IApplicationSettingsProvider
|
||||
{
|
||||
private const string _rootNodeName = "settings";
|
||||
private const string _localSettingsNodeName = "localSettings";
|
||||
private const string _globalSettingsNodeName = "globalSettings";
|
||||
private const string _className = "PortableSettingsProvider";
|
||||
private XmlDocument _xmlDocument;
|
||||
|
||||
public override void Initialize(string name, NameValueCollection col)
|
||||
{
|
||||
if (Application.ProductName.Trim().Length > 0)
|
||||
private string _filePath
|
||||
{
|
||||
get
|
||||
{
|
||||
_applicationName = Application.ProductName;
|
||||
return Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),
|
||||
string.Format("{0}.settings", ApplicationName));
|
||||
}
|
||||
}
|
||||
|
||||
private XmlNode _localSettingsNode
|
||||
{
|
||||
get
|
||||
{
|
||||
XmlNode settingsNode = GetSettingsNode(_localSettingsNodeName);
|
||||
XmlNode machineNode = settingsNode.SelectSingleNode(Environment.MachineName.ToLowerInvariant());
|
||||
|
||||
if (machineNode == null)
|
||||
{
|
||||
machineNode = _rootDocument.CreateElement(Environment.MachineName.ToLowerInvariant());
|
||||
settingsNode.AppendChild(machineNode);
|
||||
}
|
||||
|
||||
return machineNode;
|
||||
}
|
||||
}
|
||||
|
||||
private XmlNode _globalSettingsNode
|
||||
{
|
||||
get { return GetSettingsNode(_globalSettingsNodeName); }
|
||||
}
|
||||
|
||||
private XmlNode _rootNode
|
||||
{
|
||||
get { return _rootDocument.SelectSingleNode(_rootNodeName); }
|
||||
}
|
||||
|
||||
private XmlDocument _rootDocument
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_xmlDocument == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_xmlDocument = new XmlDocument();
|
||||
_xmlDocument.Load(_filePath);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (_xmlDocument.SelectSingleNode(_rootNodeName) != null)
|
||||
return _xmlDocument;
|
||||
|
||||
_xmlDocument = GetBlankXmlDocument();
|
||||
}
|
||||
|
||||
return _xmlDocument;
|
||||
}
|
||||
else
|
||||
{
|
||||
_applicationName = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
|
||||
}
|
||||
|
||||
base.Initialize(ApplicationName, col);
|
||||
}
|
||||
|
||||
private string _applicationName;
|
||||
public override string ApplicationName
|
||||
{
|
||||
get { return _applicationName; }
|
||||
get { return Path.GetFileNameWithoutExtension(Application.ExecutablePath); }
|
||||
set { }
|
||||
}
|
||||
|
||||
public virtual string GetDotSettingsFile()
|
||||
public override string Name
|
||||
{
|
||||
return Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename());
|
||||
get { return _className; }
|
||||
}
|
||||
|
||||
public virtual string GetAppSettingsPath()
|
||||
{
|
||||
//Used to determine where to store the settings
|
||||
System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath);
|
||||
return fi.DirectoryName;
|
||||
}
|
||||
|
||||
public virtual string GetAppSettingsFilename()
|
||||
{
|
||||
//Used to determine the filename to store the settings
|
||||
return "portable.settings.";
|
||||
}
|
||||
|
||||
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
|
||||
{
|
||||
//Iterate through the settings to be stored
|
||||
//Only dirty settings are included in propvals, and only ones relevant to this provider
|
||||
foreach (SettingsPropertyValue propval in propvals)
|
||||
{
|
||||
SetValue(propval);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SettingsXml.Save(GetDotSettingsFile());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Ignore if cant save, device been ejected
|
||||
}
|
||||
}
|
||||
|
||||
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props)
|
||||
{
|
||||
//Create new collection of values
|
||||
var values = new SettingsPropertyValueCollection();
|
||||
|
||||
//Iterate through the settings to be retrieved
|
||||
foreach (SettingsProperty setting in props)
|
||||
{
|
||||
public override void Initialize(string name, NameValueCollection config)
|
||||
{
|
||||
base.Initialize(Name, config);
|
||||
}
|
||||
|
||||
var value = new SettingsPropertyValue(setting)
|
||||
{
|
||||
IsDirty = false,
|
||||
SerializedValue = GetValue(setting)
|
||||
};
|
||||
values.Add(value);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private XmlDocument _SettingsXml;
|
||||
|
||||
private XmlDocument SettingsXml
|
||||
{
|
||||
get
|
||||
{
|
||||
//If we dont hold an xml document, try opening one.
|
||||
//If it doesnt exist then create a new one ready.
|
||||
if (_SettingsXml == null)
|
||||
{
|
||||
_SettingsXml = new XmlDocument();
|
||||
|
||||
try
|
||||
{
|
||||
_SettingsXml.Load(GetDotSettingsFile());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Create new document
|
||||
var dec = _SettingsXml.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
|
||||
_SettingsXml.AppendChild(dec);
|
||||
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
|
||||
{
|
||||
foreach (SettingsPropertyValue propertyValue in collection)
|
||||
SetValue(propertyValue);
|
||||
|
||||
var nodeRoot = _SettingsXml.CreateNode(XmlNodeType.Element, SETTINGSROOT, "");
|
||||
_SettingsXml.AppendChild(nodeRoot);
|
||||
}
|
||||
}
|
||||
return _SettingsXml;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetValue(SettingsProperty setting)
|
||||
{
|
||||
var ret = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
if (IsRoaming(setting))
|
||||
{
|
||||
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + setting.Name).InnerText;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + Environment.MachineName + "/" + setting.Name).InnerText;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
ret = setting.DefaultValue?.ToString() ?? "";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void SetValue(SettingsPropertyValue propVal)
|
||||
{
|
||||
System.Xml.XmlElement MachineNode = default(System.Xml.XmlElement);
|
||||
System.Xml.XmlElement SettingNode = default(System.Xml.XmlElement);
|
||||
|
||||
//Determine if the setting is roaming.
|
||||
//If roaming then the value is stored as an element under the root
|
||||
//Otherwise it is stored under a machine name node
|
||||
try
|
||||
{
|
||||
if (IsRoaming(propVal.Property))
|
||||
{
|
||||
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + propVal.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name + "/" + propVal.Name));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
SettingNode = null;
|
||||
}
|
||||
|
||||
//Check to see if the node exists, if so then set its new value
|
||||
if (SettingNode != null)
|
||||
{
|
||||
if (propVal.SerializedValue != null)
|
||||
{
|
||||
SettingNode.InnerText = propVal.SerializedValue.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsRoaming(propVal.Property))
|
||||
{
|
||||
//Store the value as an element of the Settings Root Node
|
||||
SettingNode = SettingsXml.CreateElement(propVal.Name);
|
||||
if (propVal.SerializedValue != null)
|
||||
{
|
||||
SettingNode.InnerText = propVal.SerializedValue.ToString();
|
||||
}
|
||||
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(SettingNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Its machine specific, store as an element of the machine name node,
|
||||
//creating a new machine name node if one doesnt exist.
|
||||
try
|
||||
{
|
||||
MachineNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
|
||||
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
|
||||
}
|
||||
|
||||
if (MachineNode == null)
|
||||
{
|
||||
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
|
||||
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
|
||||
}
|
||||
|
||||
SettingNode = SettingsXml.CreateElement(propVal.Name);
|
||||
if (propVal.SerializedValue != null)
|
||||
{
|
||||
SettingNode.InnerText = propVal.SerializedValue.ToString();
|
||||
}
|
||||
MachineNode.AppendChild(SettingNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsRoaming(SettingsProperty prop)
|
||||
{
|
||||
//Determine if the setting is marked as Roaming
|
||||
//For Each d As DictionaryEntry In prop.Attributes
|
||||
// Dim a As Attribute = DirectCast(d.Value, Attribute)
|
||||
// If TypeOf a Is System.Configuration.SettingsManageabilityAttribute Then
|
||||
// Return True
|
||||
// End If
|
||||
//Next
|
||||
//Return False
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
try
|
||||
{
|
||||
_rootDocument.Save(_filePath);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
/*
|
||||
* If this is a portable application and the device has been
|
||||
* removed then this will fail, so don't do anything. It's
|
||||
* probably better for the application to stop saving settings
|
||||
* rather than just crashing outright. Probably.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
|
||||
{
|
||||
SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
|
||||
|
||||
foreach (SettingsProperty property in collection)
|
||||
{
|
||||
values.Add(new SettingsPropertyValue(property)
|
||||
{
|
||||
SerializedValue = GetValue(property)
|
||||
});
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
private void SetValue(SettingsPropertyValue propertyValue)
|
||||
{
|
||||
XmlNode targetNode = IsGlobal(propertyValue.Property)
|
||||
? _globalSettingsNode
|
||||
: _localSettingsNode;
|
||||
|
||||
XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", propertyValue.Name));
|
||||
|
||||
if (settingNode != null)
|
||||
settingNode.InnerText = propertyValue.SerializedValue.ToString();
|
||||
else
|
||||
{
|
||||
settingNode = _rootDocument.CreateElement("setting");
|
||||
|
||||
XmlAttribute nameAttribute = _rootDocument.CreateAttribute("name");
|
||||
nameAttribute.Value = propertyValue.Name;
|
||||
|
||||
settingNode.Attributes.Append(nameAttribute);
|
||||
settingNode.InnerText = propertyValue.SerializedValue.ToString();
|
||||
|
||||
targetNode.AppendChild(settingNode);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetValue(SettingsProperty property)
|
||||
{
|
||||
XmlNode targetNode = IsGlobal(property) ? _globalSettingsNode : _localSettingsNode;
|
||||
XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", property.Name));
|
||||
|
||||
if (settingNode == null)
|
||||
return property.DefaultValue != null ? property.DefaultValue.ToString() : string.Empty;
|
||||
|
||||
return settingNode.InnerText;
|
||||
}
|
||||
|
||||
private bool IsGlobal(SettingsProperty property)
|
||||
{
|
||||
foreach (DictionaryEntry attribute in property.Attributes)
|
||||
{
|
||||
if ((Attribute)attribute.Value is SettingsManageabilityAttribute)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private XmlNode GetSettingsNode(string name)
|
||||
{
|
||||
XmlNode settingsNode = _rootNode.SelectSingleNode(name);
|
||||
|
||||
if (settingsNode == null)
|
||||
{
|
||||
settingsNode = _rootDocument.CreateElement(name);
|
||||
_rootNode.AppendChild(settingsNode);
|
||||
}
|
||||
|
||||
return settingsNode;
|
||||
}
|
||||
|
||||
public XmlDocument GetBlankXmlDocument()
|
||||
{
|
||||
XmlDocument blankXmlDocument = new XmlDocument();
|
||||
blankXmlDocument.AppendChild(blankXmlDocument.CreateXmlDeclaration("1.0", "utf-8", string.Empty));
|
||||
blankXmlDocument.AppendChild(blankXmlDocument.CreateElement(_rootNodeName));
|
||||
|
||||
return blankXmlDocument;
|
||||
}
|
||||
|
||||
public void Reset(SettingsContext context)
|
||||
{
|
||||
_localSettingsNode.RemoveAll();
|
||||
_globalSettingsNode.RemoveAll();
|
||||
|
||||
_xmlDocument.Save(_filePath);
|
||||
}
|
||||
|
||||
public SettingsPropertyValue GetPreviousVersion(SettingsContext context, SettingsProperty property)
|
||||
{
|
||||
// do nothing
|
||||
return new SettingsPropertyValue(property);
|
||||
}
|
||||
|
||||
public void Upgrade(SettingsContext context, SettingsPropertyCollection properties)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ namespace mRemoteNG.Connection
|
||||
ConnectionTreeModel = newConnectionsModel,
|
||||
ConnectionFileName = filename
|
||||
};
|
||||
connectionSaver.SaveFilter = new Security.SaveFilter();
|
||||
connectionSaver.SaveConnections();
|
||||
|
||||
// Load config
|
||||
|
||||
5116
mRemoteV1/Properties/Settings.Designer.cs
generated
5116
mRemoteV1/Properties/Settings.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
47
mRemoteV1/Resources/Language/Language.Designer.cs
generated
47
mRemoteV1/Resources/Language/Language.Designer.cs
generated
@@ -60,6 +60,42 @@ namespace mRemoteNG {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Create a New Configuration File.
|
||||
/// </summary>
|
||||
internal static string ConfigurationCreateNew {
|
||||
get {
|
||||
return ResourceManager.GetString("ConfigurationCreateNew", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Use a Custom File Path.
|
||||
/// </summary>
|
||||
internal static string ConfigurationCustomPath {
|
||||
get {
|
||||
return ResourceManager.GetString("ConfigurationCustomPath", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The Configuration File is Missing..
|
||||
/// </summary>
|
||||
internal static string ConfigurationFileNotFound {
|
||||
get {
|
||||
return ResourceManager.GetString("ConfigurationFileNotFound", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Import an Existing File.
|
||||
/// </summary>
|
||||
internal static string ConfigurationImportFile {
|
||||
get {
|
||||
return ResourceManager.GetString("ConfigurationImportFile", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connection successful.
|
||||
/// </summary>
|
||||
@@ -7037,7 +7073,16 @@ namespace mRemoteNG {
|
||||
return ResourceManager.GetString("strTryIntegrate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Try to integrate.
|
||||
/// </summary>
|
||||
internal static string strShowOnToolbar {
|
||||
get {
|
||||
return ResourceManager.GetString("strShowOnToolbar", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Type.
|
||||
/// </summary>
|
||||
|
||||
@@ -2240,6 +2240,9 @@ Message:
|
||||
<data name="strTryIntegrate" xml:space="preserve">
|
||||
<value>Try to integrate</value>
|
||||
</data>
|
||||
<data name="strShowOnToolbar" xml:space="preserve">
|
||||
<value>Show On Toolbar</value>
|
||||
</data>
|
||||
<data name="strType" xml:space="preserve">
|
||||
<value>Type</value>
|
||||
</data>
|
||||
@@ -2595,6 +2598,18 @@ This page will walk you through the process of upgrading your connections file o
|
||||
<data name="CouldNotFindExternalTool" xml:space="preserve">
|
||||
<value>Could not find external tool with name "{0}"</value>
|
||||
</data>
|
||||
<data name="ConfigurationCreateNew" xml:space="preserve">
|
||||
<value>Create a New Configuration File</value>
|
||||
</data>
|
||||
<data name="ConfigurationFileNotFound" xml:space="preserve">
|
||||
<value>The Configuration File is Missing.</value>
|
||||
</data>
|
||||
<data name="ConfigurationImportFile" xml:space="preserve">
|
||||
<value>Import an Existing File</value>
|
||||
</data>
|
||||
<data name="ConfigurationCustomPath" xml:space="preserve">
|
||||
<value>Use a Custom File Path</value>
|
||||
</data>
|
||||
<data name="TestingConnection" xml:space="preserve">
|
||||
<value>Testing connection</value>
|
||||
</data>
|
||||
@@ -2610,4 +2625,4 @@ This page will walk you through the process of upgrading your connections file o
|
||||
<data name="DatabaseNotAvailable" xml:space="preserve">
|
||||
<value>Database '{0}' not available.</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
32
mRemoteV1/Settings.cs
Normal file
32
mRemoteV1/Settings.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Configuration;
|
||||
|
||||
namespace mRemoteNG
|
||||
{
|
||||
|
||||
|
||||
// This class allows you to handle specific events on the settings class:
|
||||
// The SettingChanging event is raised before a setting's value is changed.
|
||||
// The PropertyChanged event is raised after a setting's value is changed.
|
||||
// The SettingsLoaded event is raised after the setting values are loaded.
|
||||
// The SettingsSaving event is raised before the setting values are saved.
|
||||
[global::System.Configuration.SettingsProviderAttribute(typeof(mRemoteNG.Config.Settings.Providers.ChooseProvider))]
|
||||
internal sealed partial class Settings {
|
||||
|
||||
public Settings() {
|
||||
// // To add event handlers for saving and changing settings, uncomment the lines below:
|
||||
//
|
||||
// this.SettingChanging += this.SettingChangingEventHandler;
|
||||
//
|
||||
// this.SettingsSaving += this.SettingsSavingEventHandler;
|
||||
//
|
||||
}
|
||||
|
||||
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
|
||||
// Add code to handle the SettingChangingEvent event here.
|
||||
}
|
||||
|
||||
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
// Add code to handle the SettingsSaving event here.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ namespace mRemoteNG.Tools.CustomCollections
|
||||
where T : INotifyPropertyChanged
|
||||
{
|
||||
private readonly IList<T> _list = new List<T>();
|
||||
private bool _eventsAllowed;
|
||||
|
||||
public int Count => _list.Count;
|
||||
public bool IsReadOnly => _list.IsReadOnly;
|
||||
@@ -26,30 +27,48 @@ namespace mRemoteNG.Tools.CustomCollections
|
||||
|
||||
public FullyObservableCollection(IEnumerable<T> items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
Add(item);
|
||||
AddRange(items);
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
_list.Add(item);
|
||||
SubscribeToChildEvents(item);
|
||||
RaiseCredentialChangedEvent(ActionType.Added, new[] {item});
|
||||
if (_eventsAllowed)
|
||||
RaiseCollectionChangedEvent(ActionType.Added, new[] {item});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a range of items to the collection.
|
||||
/// Only raises a single <see cref="CollectionUpdated"/> event
|
||||
/// after all new items are added.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
public void AddRange(IEnumerable<T> items)
|
||||
{
|
||||
var itemsAsList = items.ToList();
|
||||
_eventsAllowed = false;
|
||||
|
||||
foreach (var item in itemsAsList)
|
||||
Add(item);
|
||||
|
||||
_eventsAllowed = true;
|
||||
RaiseCollectionChangedEvent(ActionType.Added, itemsAsList);
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
_list.Insert(index, item);
|
||||
SubscribeToChildEvents(item);
|
||||
RaiseCredentialChangedEvent(ActionType.Added, new[] { item });
|
||||
RaiseCollectionChangedEvent(ActionType.Added, new[] { item });
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
var worked = _list.Remove(item);
|
||||
if (!worked) return worked;
|
||||
RaiseCredentialChangedEvent(ActionType.Removed, new[] {item});
|
||||
UnsubscribeFromChildEvents(item);
|
||||
RaiseCollectionChangedEvent(ActionType.Removed, new[] {item});
|
||||
return worked;
|
||||
}
|
||||
|
||||
@@ -58,7 +77,7 @@ namespace mRemoteNG.Tools.CustomCollections
|
||||
var item = _list[index];
|
||||
_list.RemoveAt(index);
|
||||
UnsubscribeFromChildEvents(item);
|
||||
RaiseCredentialChangedEvent(ActionType.Removed, new[] { item });
|
||||
RaiseCollectionChangedEvent(ActionType.Removed, new[] { item });
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
@@ -67,7 +86,7 @@ namespace mRemoteNG.Tools.CustomCollections
|
||||
_list.Clear();
|
||||
foreach (var item in oldItems)
|
||||
UnsubscribeFromChildEvents(item);
|
||||
RaiseCredentialChangedEvent(ActionType.Removed, oldItems);
|
||||
RaiseCollectionChangedEvent(ActionType.Removed, oldItems);
|
||||
}
|
||||
|
||||
private void SubscribeToChildEvents(INotifyPropertyChanged item)
|
||||
@@ -83,12 +102,12 @@ namespace mRemoteNG.Tools.CustomCollections
|
||||
private void ItemOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
|
||||
{
|
||||
if (sender is T)
|
||||
RaiseCredentialChangedEvent(ActionType.Updated, new []{ (T)sender });
|
||||
RaiseCollectionChangedEvent(ActionType.Updated, new []{ (T)sender });
|
||||
}
|
||||
|
||||
public event EventHandler<CollectionUpdatedEventArgs<T>> CollectionUpdated;
|
||||
|
||||
private void RaiseCredentialChangedEvent(ActionType action, IEnumerable<T> changedItems)
|
||||
private void RaiseCollectionChangedEvent(ActionType action, IEnumerable<T> changedItems)
|
||||
{
|
||||
CollectionUpdated?.Invoke(this, new CollectionUpdatedEventArgs<T>(action, changedItems));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
@@ -10,16 +12,81 @@ using mRemoteNG.Messages;
|
||||
|
||||
namespace mRemoteNG.Tools
|
||||
{
|
||||
public class ExternalTool
|
||||
public class ExternalTool : INotifyPropertyChanged
|
||||
{
|
||||
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
|
||||
#region Public Properties
|
||||
public string DisplayName { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public bool WaitForExit { get; set; }
|
||||
public string Arguments { get; set; }
|
||||
public bool TryIntegrate { get; set; }
|
||||
public ConnectionInfo ConnectionInfo { get; set; }
|
||||
private string _displayName;
|
||||
private string _fileName;
|
||||
private bool _waitForExit;
|
||||
private string _arguments;
|
||||
private string _workingDir;
|
||||
private bool _tryIntegrate;
|
||||
private bool _showOnToolbar = true;
|
||||
private bool _runElevated;
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get { return _displayName; }
|
||||
set { SetField(ref _displayName, value, nameof(DisplayName)); }
|
||||
}
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get { return _fileName; }
|
||||
set { SetField(ref _fileName, value, nameof(FileName)); }
|
||||
}
|
||||
|
||||
public bool WaitForExit
|
||||
{
|
||||
get { return _waitForExit; }
|
||||
set
|
||||
{
|
||||
// WaitForExit cannot be turned on when TryIntegrate is true
|
||||
if (TryIntegrate)
|
||||
return;
|
||||
SetField(ref _waitForExit, value, nameof(WaitForExit));
|
||||
}
|
||||
}
|
||||
|
||||
public string Arguments
|
||||
{
|
||||
get { return _arguments; }
|
||||
set { SetField(ref _arguments, value, nameof(Arguments)); }
|
||||
}
|
||||
|
||||
public string WorkingDir
|
||||
{
|
||||
get { return _workingDir; }
|
||||
set { SetField(ref _workingDir, value, nameof(WorkingDir)); }
|
||||
}
|
||||
|
||||
public bool TryIntegrate
|
||||
{
|
||||
get { return _tryIntegrate; }
|
||||
set
|
||||
{
|
||||
// WaitForExit cannot be turned on when TryIntegrate is true
|
||||
if (value)
|
||||
WaitForExit = false;
|
||||
SetField(ref _tryIntegrate, value, nameof(TryIntegrate));
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowOnToolbar
|
||||
{
|
||||
get { return _showOnToolbar; }
|
||||
set { SetField(ref _showOnToolbar, value, nameof(ShowOnToolbar)); }
|
||||
}
|
||||
|
||||
public bool RunElevated
|
||||
{
|
||||
get { return _runElevated; }
|
||||
set { SetField(ref _runElevated, value, nameof(RunElevated)); }
|
||||
}
|
||||
|
||||
public ConnectionInfo ConnectionInfo { get; set; }
|
||||
|
||||
public Icon Icon
|
||||
{
|
||||
@@ -33,11 +100,13 @@ namespace mRemoteNG.Tools
|
||||
|
||||
#endregion
|
||||
|
||||
public ExternalTool(string displayName = "", string fileName = "", string arguments = "")
|
||||
public ExternalTool(string displayName = "", string fileName = "", string arguments = "", string workingDir = "", bool runElevated = false)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
FileName = fileName;
|
||||
Arguments = arguments;
|
||||
WorkingDir = workingDir;
|
||||
RunElevated = runElevated;
|
||||
}
|
||||
|
||||
public void Start(ConnectionInfo startConnectionInfo = null)
|
||||
@@ -81,6 +150,8 @@ namespace mRemoteNG.Tools
|
||||
process.StartInfo.UseShellExecute = true;
|
||||
process.StartInfo.FileName = argParser.ParseArguments(FileName);
|
||||
process.StartInfo.Arguments = argParser.ParseArguments(Arguments);
|
||||
if (WorkingDir != "") process.StartInfo.WorkingDirectory = argParser.ParseArguments(WorkingDir);
|
||||
if (RunElevated) process.StartInfo.Verb = "runas";
|
||||
}
|
||||
|
||||
private void StartIntegrated()
|
||||
@@ -116,5 +187,20 @@ namespace mRemoteNG.Tools
|
||||
newConnectionInfo.Name = DisplayName;
|
||||
newConnectionInfo.Panel = Language.strMenuExternalTools;
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void RaisePropertyChangedEvent(object sender, string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
protected bool SetField<T>(ref T field, T value, string propertyName)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
|
||||
field = value;
|
||||
RaisePropertyChangedEvent(this, propertyName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using mRemoteNG.Tools.CustomCollections;
|
||||
|
||||
namespace mRemoteNG.Tools
|
||||
{
|
||||
public class ExternalToolsService
|
||||
{
|
||||
public ObservableCollection<ExternalTool> ExternalTools { get; set; } = new ObservableCollection<ExternalTool>();
|
||||
public FullyObservableCollection<ExternalTool> ExternalTools { get; set; } = new FullyObservableCollection<ExternalTool>();
|
||||
|
||||
public ExternalTool GetExtAppByName(string name)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace mRemoteNG.UI.Controls
|
||||
public ExternalToolsToolStrip()
|
||||
{
|
||||
Initialize();
|
||||
Runtime.ExternalToolsService.ExternalTools.CollectionChanged += (sender, args) => AddExternalToolsToToolBar();
|
||||
Runtime.ExternalToolsService.ExternalTools.CollectionUpdated += (sender, args) => AddExternalToolsToToolBar();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
@@ -53,9 +53,6 @@ namespace mRemoteNG.UI.Controls
|
||||
CMenToolbarShowText.Click += cMenToolbarShowText_Click;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region Ext Apps Toolbar
|
||||
private void cMenToolbarShowText_Click(object sender, EventArgs e)
|
||||
{
|
||||
@@ -66,25 +63,34 @@ namespace mRemoteNG.UI.Controls
|
||||
{
|
||||
try
|
||||
{
|
||||
SuspendLayout();
|
||||
|
||||
for (var index = Items.Count - 1; index >= 0; index--)
|
||||
Items[index].Dispose();
|
||||
Items.Clear();
|
||||
|
||||
foreach (var tool in Runtime.ExternalToolsService.ExternalTools)
|
||||
{
|
||||
var button = (ToolStripButton)Items.Add(tool.DisplayName, tool.Image, tsExtAppEntry_Click);
|
||||
if (CMenToolbarShowText.Checked)
|
||||
button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
|
||||
else
|
||||
button.DisplayStyle = button.Image != null ? ToolStripItemDisplayStyle.Image : ToolStripItemDisplayStyle.ImageAndText;
|
||||
if (tool.ShowOnToolbar)
|
||||
{
|
||||
var button = (ToolStripButton)Items.Add(tool.DisplayName, tool.Image, tsExtAppEntry_Click);
|
||||
if (CMenToolbarShowText.Checked)
|
||||
button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
|
||||
else
|
||||
button.DisplayStyle = button.Image != null ? ToolStripItemDisplayStyle.Image : ToolStripItemDisplayStyle.ImageAndText;
|
||||
|
||||
button.Tag = tool;
|
||||
button.Tag = tool;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddExternalToolsToToolBarFailed, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ResumeLayout(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void tsExtAppEntry_Click(object sender, EventArgs e)
|
||||
|
||||
212
mRemoteV1/UI/Window/ExternalToolsWindow.Designer.cs
generated
212
mRemoteV1/UI/Window/ExternalToolsWindow.Designer.cs
generated
@@ -11,8 +11,10 @@ namespace mRemoteNG.UI.Window
|
||||
internal BrightIdeasSoftware.OLVColumn ArgumentsColumnHeader;
|
||||
internal BrightIdeasSoftware.OLVColumn WaitForExitColumnHeader;
|
||||
internal BrightIdeasSoftware.OLVColumn TryToIntegrateColumnHeader;
|
||||
internal System.Windows.Forms.GroupBox PropertiesGroupBox;
|
||||
internal BrightIdeasSoftware.OLVColumn WorkingDirColumnHeader;
|
||||
internal BrightIdeasSoftware.OLVColumn RunElevateHeader;
|
||||
internal Controls.Base.NGTextBox DisplayNameTextBox;
|
||||
internal BrightIdeasSoftware.OLVColumn ShowOnToolbarColumnHeader;
|
||||
internal Controls.Base.NGLabel DisplayNameLabel;
|
||||
internal Controls.Base.NGTextBox ArgumentsCheckBox;
|
||||
internal Controls.Base.NGTextBox FilenameTextBox;
|
||||
@@ -27,29 +29,41 @@ namespace mRemoteNG.UI.Window
|
||||
internal Controls.Base.NGCheckBox WaitForExitCheckBox;
|
||||
internal Controls.Base.NGLabel OptionsLabel;
|
||||
internal Controls.Base.NGCheckBox TryToIntegrateCheckBox;
|
||||
|
||||
internal Controls.Base.NGListView ToolsListObjView;
|
||||
|
||||
private void InitializeComponent()
|
||||
internal Controls.Base.NGCheckBox ShowOnToolbarCheckBox;
|
||||
internal Controls.Base.NGListView ToolsListObjView;
|
||||
internal Controls.Base.NGLabel WorkingDirLabel;
|
||||
internal Controls.Base.NGTextBox WorkingDirTextBox;
|
||||
internal Controls.Base.NGButton BrowseWorkingDir;
|
||||
internal Controls.Base.NGCheckBox RunElevatedCheckBox;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExternalToolsWindow));
|
||||
this.ToolsListObjView = new Controls.Base.NGListView();
|
||||
this.ToolsListObjView = new mRemoteNG.UI.Controls.Base.NGListView();
|
||||
this.DisplayNameColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.FilenameColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.ArgumentsColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.WorkingDirColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.WaitForExitColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.TryToIntegrateColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.RunElevateHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.ShowOnToolbarColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.ToolsContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.NewToolMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.DeleteToolMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.LaunchToolMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.PropertiesGroupBox = new mRemoteNG.UI.Controls.Base.NGGroupBox();
|
||||
this.ShowOnToolbarCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
|
||||
this.RunElevatedCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
|
||||
this.BrowseWorkingDir = new mRemoteNG.UI.Controls.Base.NGButton();
|
||||
this.WorkingDirLabel = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.WorkingDirTextBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
|
||||
this.TryToIntegrateCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
|
||||
this.OptionsLabel = new mRemoteNG.UI.Controls.Base.NGLabel();
|
||||
this.WaitForExitCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
|
||||
this.BrowseButton = new Controls.Base.NGButton();
|
||||
this.BrowseButton = new mRemoteNG.UI.Controls.Base.NGButton();
|
||||
this.ArgumentsCheckBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
|
||||
this.FilenameTextBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
|
||||
this.DisplayNameTextBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
|
||||
@@ -74,64 +88,118 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// ToolsListObjView
|
||||
//
|
||||
this.ToolsListObjView.AllColumns.Add(this.DisplayNameColumnHeader);
|
||||
this.ToolsListObjView.AllColumns.Add(this.FilenameColumnHeader);
|
||||
this.ToolsListObjView.AllColumns.Add(this.ArgumentsColumnHeader);
|
||||
this.ToolsListObjView.AllColumns.Add(this.WorkingDirColumnHeader);
|
||||
this.ToolsListObjView.AllColumns.Add(this.WaitForExitColumnHeader);
|
||||
this.ToolsListObjView.AllColumns.Add(this.TryToIntegrateColumnHeader);
|
||||
this.ToolsListObjView.AllColumns.Add(this.RunElevateHeader);
|
||||
this.ToolsListObjView.AllColumns.Add(this.ShowOnToolbarColumnHeader);
|
||||
this.ToolsListObjView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.ToolsListObjView.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.ToolsListObjView.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.F2Only;
|
||||
this.ToolsListObjView.CellEditUseWholeCell = false;
|
||||
this.ToolsListObjView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.DisplayNameColumnHeader,
|
||||
this.FilenameColumnHeader,
|
||||
this.ArgumentsColumnHeader,
|
||||
this.WorkingDirColumnHeader,
|
||||
this.WaitForExitColumnHeader,
|
||||
this.TryToIntegrateColumnHeader});
|
||||
this.TryToIntegrateColumnHeader,
|
||||
this.RunElevateHeader,
|
||||
this.ShowOnToolbarColumnHeader});
|
||||
this.ToolsListObjView.ContextMenuStrip = this.ToolsContextMenuStrip;
|
||||
this.ToolsListObjView.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
this.ToolsListObjView.DecorateLines = true;
|
||||
this.ToolsListObjView.FullRowSelect = true;
|
||||
this.ToolsListObjView.GridLines = true;
|
||||
this.ToolsListObjView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||
this.ToolsListObjView.HideSelection = false;
|
||||
this.ToolsListObjView.Location = new System.Drawing.Point(0, 0);
|
||||
this.ToolsListObjView.Name = "ToolsListObjView";
|
||||
this.ToolsListObjView.Size = new System.Drawing.Size(684, 157);
|
||||
this.ToolsListObjView.RenderNonEditableCheckboxesAsDisabled = true;
|
||||
this.ToolsListObjView.ShowCommandMenuOnRightClick = true;
|
||||
this.ToolsListObjView.ShowGroups = false;
|
||||
this.ToolsListObjView.Size = new System.Drawing.Size(827, 186);
|
||||
this.ToolsListObjView.Sorting = System.Windows.Forms.SortOrder.Ascending;
|
||||
this.ToolsListObjView.TabIndex = 0;
|
||||
this.ToolsListObjView.UseCompatibleStateImageBehavior = false;
|
||||
this.ToolsListObjView.UseNotifyPropertyChanged = true;
|
||||
this.ToolsListObjView.View = System.Windows.Forms.View.Details;
|
||||
this.ToolsListObjView.CellToolTipShowing += new System.EventHandler<BrightIdeasSoftware.ToolTipShowingEventArgs>(this.ToolsListObjView_CellToolTipShowing);
|
||||
this.ToolsListObjView.SelectedIndexChanged += new System.EventHandler(this.ToolsListObjView_SelectedIndexChanged);
|
||||
this.ToolsListObjView.DoubleClick += new System.EventHandler(this.ToolsListObjView_DoubleClick);
|
||||
//
|
||||
// DisplayNameColumnHeader
|
||||
//
|
||||
this.DisplayNameColumnHeader.AspectName = "DisplayName";
|
||||
this.DisplayNameColumnHeader.AutoCompleteEditor = false;
|
||||
this.DisplayNameColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
|
||||
this.DisplayNameColumnHeader.Text = "Display Name";
|
||||
this.DisplayNameColumnHeader.Width = 130;
|
||||
this.DisplayNameColumnHeader.UseInitialLetterForGroup = true;
|
||||
this.DisplayNameColumnHeader.Width = 100;
|
||||
//
|
||||
// FilenameColumnHeader
|
||||
//
|
||||
this.FilenameColumnHeader.AspectName = "FileName";
|
||||
this.FilenameColumnHeader.AutoCompleteEditor = false;
|
||||
this.FilenameColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
|
||||
this.FilenameColumnHeader.Groupable = false;
|
||||
this.FilenameColumnHeader.Text = "Filename";
|
||||
this.FilenameColumnHeader.Width = 200;
|
||||
this.FilenameColumnHeader.Width = 100;
|
||||
//
|
||||
// ArgumentsColumnHeader
|
||||
//
|
||||
this.ArgumentsColumnHeader.AspectName = "Arguments";
|
||||
this.ArgumentsColumnHeader.FillsFreeSpace = true;
|
||||
this.ArgumentsColumnHeader.AutoCompleteEditor = false;
|
||||
this.ArgumentsColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
|
||||
this.ArgumentsColumnHeader.Groupable = false;
|
||||
this.ArgumentsColumnHeader.Text = "Arguments";
|
||||
this.ArgumentsColumnHeader.Width = 160;
|
||||
this.ArgumentsColumnHeader.Width = 100;
|
||||
//
|
||||
// WorkingDirColumnHeader
|
||||
//
|
||||
this.WorkingDirColumnHeader.AspectName = "WorkingDir";
|
||||
this.WorkingDirColumnHeader.AutoCompleteEditor = false;
|
||||
this.WorkingDirColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
|
||||
this.WorkingDirColumnHeader.Groupable = false;
|
||||
this.WorkingDirColumnHeader.Text = "Working Directory";
|
||||
this.WorkingDirColumnHeader.Width = 120;
|
||||
//
|
||||
// WaitForExitColumnHeader
|
||||
//
|
||||
this.WaitForExitColumnHeader.AspectName = "WaitForExit";
|
||||
this.WaitForExitColumnHeader.CheckBoxes = true;
|
||||
this.WaitForExitColumnHeader.Groupable = false;
|
||||
this.WaitForExitColumnHeader.Text = "Wait for exit";
|
||||
this.WaitForExitColumnHeader.Width = 95;
|
||||
this.WaitForExitColumnHeader.Width = 75;
|
||||
//
|
||||
// TryToIntegrateColumnHeader
|
||||
//
|
||||
this.TryToIntegrateColumnHeader.AspectName = "TryIntegrate";
|
||||
this.TryToIntegrateColumnHeader.CheckBoxes = true;
|
||||
this.TryToIntegrateColumnHeader.Groupable = false;
|
||||
this.TryToIntegrateColumnHeader.Text = "Try To Integrate";
|
||||
this.TryToIntegrateColumnHeader.Width = 95;
|
||||
//
|
||||
// RunElevateHeader
|
||||
//
|
||||
this.RunElevateHeader.AspectName = "RunElevated";
|
||||
this.RunElevateHeader.CheckBoxes = true;
|
||||
this.RunElevateHeader.Groupable = false;
|
||||
this.RunElevateHeader.Text = "Run Elevated";
|
||||
this.RunElevateHeader.Width = 95;
|
||||
//
|
||||
// ShowOnToolbarColumnHeader
|
||||
//
|
||||
this.ShowOnToolbarColumnHeader.AspectName = "ShowOnToolbar";
|
||||
this.ShowOnToolbarColumnHeader.CheckBoxes = true;
|
||||
this.ShowOnToolbarColumnHeader.Groupable = false;
|
||||
this.ShowOnToolbarColumnHeader.Text = "Show On Toolbar";
|
||||
this.ShowOnToolbarColumnHeader.Width = 120;
|
||||
//
|
||||
// ToolsContextMenuStrip
|
||||
//
|
||||
this.ToolsContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
@@ -153,6 +221,7 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// DeleteToolMenuItem
|
||||
//
|
||||
this.DeleteToolMenuItem.Enabled = false;
|
||||
this.DeleteToolMenuItem.Image = global::mRemoteNG.Resources.ExtApp_Delete;
|
||||
this.DeleteToolMenuItem.Name = "DeleteToolMenuItem";
|
||||
this.DeleteToolMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;
|
||||
@@ -167,6 +236,7 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// LaunchToolMenuItem
|
||||
//
|
||||
this.LaunchToolMenuItem.Enabled = false;
|
||||
this.LaunchToolMenuItem.Image = global::mRemoteNG.Resources.ExtApp_Start;
|
||||
this.LaunchToolMenuItem.Name = "LaunchToolMenuItem";
|
||||
this.LaunchToolMenuItem.Size = new System.Drawing.Size(219, 22);
|
||||
@@ -177,6 +247,11 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
this.PropertiesGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.PropertiesGroupBox.Controls.Add(this.ShowOnToolbarCheckBox);
|
||||
this.PropertiesGroupBox.Controls.Add(this.RunElevatedCheckBox);
|
||||
this.PropertiesGroupBox.Controls.Add(this.BrowseWorkingDir);
|
||||
this.PropertiesGroupBox.Controls.Add(this.WorkingDirLabel);
|
||||
this.PropertiesGroupBox.Controls.Add(this.WorkingDirTextBox);
|
||||
this.PropertiesGroupBox.Controls.Add(this.TryToIntegrateCheckBox);
|
||||
this.PropertiesGroupBox.Controls.Add(this.OptionsLabel);
|
||||
this.PropertiesGroupBox.Controls.Add(this.WaitForExitCheckBox);
|
||||
@@ -188,30 +263,85 @@ namespace mRemoteNG.UI.Window
|
||||
this.PropertiesGroupBox.Controls.Add(this.FilenameLabel);
|
||||
this.PropertiesGroupBox.Controls.Add(this.DisplayNameLabel);
|
||||
this.PropertiesGroupBox.Enabled = false;
|
||||
this.PropertiesGroupBox.Location = new System.Drawing.Point(0, 153);
|
||||
this.PropertiesGroupBox.Location = new System.Drawing.Point(0, 192);
|
||||
this.PropertiesGroupBox.Name = "PropertiesGroupBox";
|
||||
this.PropertiesGroupBox.Size = new System.Drawing.Size(684, 145);
|
||||
this.PropertiesGroupBox.Size = new System.Drawing.Size(827, 184);
|
||||
this.PropertiesGroupBox.TabIndex = 1;
|
||||
this.PropertiesGroupBox.TabStop = false;
|
||||
this.PropertiesGroupBox.Text = "External Tool Properties";
|
||||
//
|
||||
// ShowOnToolbarCheckBox
|
||||
//
|
||||
this.ShowOnToolbarCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
|
||||
this.ShowOnToolbarCheckBox.AutoSize = true;
|
||||
this.ShowOnToolbarCheckBox.Location = new System.Drawing.Point(306, 158);
|
||||
this.ShowOnToolbarCheckBox.Name = "ShowOnToolbarCheckBox";
|
||||
this.ShowOnToolbarCheckBox.Size = new System.Drawing.Size(113, 17);
|
||||
this.ShowOnToolbarCheckBox.TabIndex = 10;
|
||||
this.ShowOnToolbarCheckBox.Text = "Show on toolbar";
|
||||
this.ShowOnToolbarCheckBox.UseVisualStyleBackColor = true;
|
||||
this.ShowOnToolbarCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
//
|
||||
// RunElevatedCheckBox
|
||||
//
|
||||
this.RunElevatedCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
|
||||
this.RunElevatedCheckBox.AutoSize = true;
|
||||
this.RunElevatedCheckBox.Location = new System.Drawing.Point(126, 158);
|
||||
this.RunElevatedCheckBox.Name = "RunElevatedCheckBox";
|
||||
this.RunElevatedCheckBox.Size = new System.Drawing.Size(93, 17);
|
||||
this.RunElevatedCheckBox.TabIndex = 9;
|
||||
this.RunElevatedCheckBox.Text = "Run Elevated";
|
||||
this.RunElevatedCheckBox.UseVisualStyleBackColor = true;
|
||||
this.RunElevatedCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
//
|
||||
// BrowseWorkingDir
|
||||
//
|
||||
this.BrowseWorkingDir._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
|
||||
this.BrowseWorkingDir.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.BrowseWorkingDir.Location = new System.Drawing.Point(723, 103);
|
||||
this.BrowseWorkingDir.Name = "BrowseWorkingDir";
|
||||
this.BrowseWorkingDir.Size = new System.Drawing.Size(95, 23);
|
||||
this.BrowseWorkingDir.TabIndex = 6;
|
||||
this.BrowseWorkingDir.Text = "Browse...";
|
||||
this.BrowseWorkingDir.UseVisualStyleBackColor = true;
|
||||
this.BrowseWorkingDir.Click += new System.EventHandler(this.BrowseWorkingDir_Click);
|
||||
//
|
||||
// WorkingDirLabel
|
||||
//
|
||||
this.WorkingDirLabel.AutoSize = true;
|
||||
this.WorkingDirLabel.Location = new System.Drawing.Point(6, 108);
|
||||
this.WorkingDirLabel.Name = "WorkingDirLabel";
|
||||
this.WorkingDirLabel.Size = new System.Drawing.Size(104, 13);
|
||||
this.WorkingDirLabel.TabIndex = 11;
|
||||
this.WorkingDirLabel.Text = "Working Directory:";
|
||||
this.WorkingDirLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// WorkingDirTextBox
|
||||
//
|
||||
this.WorkingDirTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.WorkingDirTextBox.Location = new System.Drawing.Point(126, 104);
|
||||
this.WorkingDirTextBox.Name = "WorkingDirTextBox";
|
||||
this.WorkingDirTextBox.Size = new System.Drawing.Size(591, 22);
|
||||
this.WorkingDirTextBox.TabIndex = 5;
|
||||
this.WorkingDirTextBox.Leave += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
//
|
||||
// TryToIntegrateCheckBox
|
||||
//
|
||||
this.TryToIntegrateCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
|
||||
this.TryToIntegrateCheckBox.AutoSize = true;
|
||||
this.TryToIntegrateCheckBox.Location = new System.Drawing.Point(280, 106);
|
||||
this.TryToIntegrateCheckBox.Location = new System.Drawing.Point(306, 135);
|
||||
this.TryToIntegrateCheckBox.Name = "TryToIntegrateCheckBox";
|
||||
this.TryToIntegrateCheckBox.Size = new System.Drawing.Size(103, 17);
|
||||
this.TryToIntegrateCheckBox.TabIndex = 9;
|
||||
this.TryToIntegrateCheckBox.TabIndex = 8;
|
||||
this.TryToIntegrateCheckBox.Text = "Try to integrate";
|
||||
this.TryToIntegrateCheckBox.UseVisualStyleBackColor = true;
|
||||
this.TryToIntegrateCheckBox.CheckedChanged += new System.EventHandler(this.TryToIntegrateCheckBox_CheckedChanged);
|
||||
this.TryToIntegrateCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
//
|
||||
// OptionsLabel
|
||||
//
|
||||
this.OptionsLabel.AutoSize = true;
|
||||
this.OptionsLabel.Location = new System.Drawing.Point(51, 107);
|
||||
this.OptionsLabel.Location = new System.Drawing.Point(6, 135);
|
||||
this.OptionsLabel.Name = "OptionsLabel";
|
||||
this.OptionsLabel.Size = new System.Drawing.Size(52, 13);
|
||||
this.OptionsLabel.TabIndex = 7;
|
||||
@@ -222,10 +352,10 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
this.WaitForExitCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
|
||||
this.WaitForExitCheckBox.AutoSize = true;
|
||||
this.WaitForExitCheckBox.Location = new System.Drawing.Point(110, 106);
|
||||
this.WaitForExitCheckBox.Location = new System.Drawing.Point(126, 135);
|
||||
this.WaitForExitCheckBox.Name = "WaitForExitCheckBox";
|
||||
this.WaitForExitCheckBox.Size = new System.Drawing.Size(89, 17);
|
||||
this.WaitForExitCheckBox.TabIndex = 8;
|
||||
this.WaitForExitCheckBox.TabIndex = 7;
|
||||
this.WaitForExitCheckBox.Text = "Wait for exit";
|
||||
this.WaitForExitCheckBox.UseVisualStyleBackColor = true;
|
||||
this.WaitForExitCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
@@ -233,11 +363,12 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// BrowseButton
|
||||
//
|
||||
this.BrowseButton._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
|
||||
this.BrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.BrowseButton.Location = new System.Drawing.Point(580, 45);
|
||||
this.BrowseButton.Location = new System.Drawing.Point(723, 46);
|
||||
this.BrowseButton.Name = "BrowseButton";
|
||||
this.BrowseButton.Size = new System.Drawing.Size(95, 23);
|
||||
this.BrowseButton.TabIndex = 4;
|
||||
this.BrowseButton.TabIndex = 3;
|
||||
this.BrowseButton.Text = "Browse...";
|
||||
this.BrowseButton.UseVisualStyleBackColor = true;
|
||||
this.BrowseButton.Click += new System.EventHandler(this.BrowseButton_Click);
|
||||
@@ -248,10 +379,10 @@ namespace mRemoteNG.UI.Window
|
||||
this.ArgumentsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.ArgumentsCheckBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.ArgumentsCheckBox.Location = new System.Drawing.Point(110, 76);
|
||||
this.ArgumentsCheckBox.Location = new System.Drawing.Point(126, 76);
|
||||
this.ArgumentsCheckBox.Name = "ArgumentsCheckBox";
|
||||
this.ArgumentsCheckBox.Size = new System.Drawing.Size(565, 22);
|
||||
this.ArgumentsCheckBox.TabIndex = 6;
|
||||
this.ArgumentsCheckBox.Size = new System.Drawing.Size(591, 22);
|
||||
this.ArgumentsCheckBox.TabIndex = 4;
|
||||
this.ArgumentsCheckBox.LostFocus += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
//
|
||||
// FilenameTextBox
|
||||
@@ -259,10 +390,10 @@ namespace mRemoteNG.UI.Window
|
||||
this.FilenameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.FilenameTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.FilenameTextBox.Location = new System.Drawing.Point(110, 47);
|
||||
this.FilenameTextBox.Location = new System.Drawing.Point(126, 47);
|
||||
this.FilenameTextBox.Name = "FilenameTextBox";
|
||||
this.FilenameTextBox.Size = new System.Drawing.Size(464, 22);
|
||||
this.FilenameTextBox.TabIndex = 3;
|
||||
this.FilenameTextBox.Size = new System.Drawing.Size(591, 22);
|
||||
this.FilenameTextBox.TabIndex = 2;
|
||||
this.FilenameTextBox.LostFocus += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
//
|
||||
// DisplayNameTextBox
|
||||
@@ -270,16 +401,16 @@ namespace mRemoteNG.UI.Window
|
||||
this.DisplayNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.DisplayNameTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.DisplayNameTextBox.Location = new System.Drawing.Point(110, 19);
|
||||
this.DisplayNameTextBox.Location = new System.Drawing.Point(126, 19);
|
||||
this.DisplayNameTextBox.Name = "DisplayNameTextBox";
|
||||
this.DisplayNameTextBox.Size = new System.Drawing.Size(565, 22);
|
||||
this.DisplayNameTextBox.Size = new System.Drawing.Size(591, 22);
|
||||
this.DisplayNameTextBox.TabIndex = 1;
|
||||
this.DisplayNameTextBox.LostFocus += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
|
||||
//
|
||||
// ArgumentsLabel
|
||||
//
|
||||
this.ArgumentsLabel.AutoSize = true;
|
||||
this.ArgumentsLabel.Location = new System.Drawing.Point(33, 79);
|
||||
this.ArgumentsLabel.Location = new System.Drawing.Point(6, 78);
|
||||
this.ArgumentsLabel.Name = "ArgumentsLabel";
|
||||
this.ArgumentsLabel.Size = new System.Drawing.Size(66, 13);
|
||||
this.ArgumentsLabel.TabIndex = 5;
|
||||
@@ -289,7 +420,7 @@ namespace mRemoteNG.UI.Window
|
||||
// FilenameLabel
|
||||
//
|
||||
this.FilenameLabel.AutoSize = true;
|
||||
this.FilenameLabel.Location = new System.Drawing.Point(44, 50);
|
||||
this.FilenameLabel.Location = new System.Drawing.Point(6, 50);
|
||||
this.FilenameLabel.Name = "FilenameLabel";
|
||||
this.FilenameLabel.Size = new System.Drawing.Size(56, 13);
|
||||
this.FilenameLabel.TabIndex = 2;
|
||||
@@ -299,7 +430,7 @@ namespace mRemoteNG.UI.Window
|
||||
// DisplayNameLabel
|
||||
//
|
||||
this.DisplayNameLabel.AutoSize = true;
|
||||
this.DisplayNameLabel.Location = new System.Drawing.Point(21, 22);
|
||||
this.DisplayNameLabel.Location = new System.Drawing.Point(6, 21);
|
||||
this.DisplayNameLabel.Name = "DisplayNameLabel";
|
||||
this.DisplayNameLabel.Size = new System.Drawing.Size(79, 13);
|
||||
this.DisplayNameLabel.TabIndex = 0;
|
||||
@@ -313,11 +444,11 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
this.ToolStripContainer.ContentPanel.Controls.Add(this.PropertiesGroupBox);
|
||||
this.ToolStripContainer.ContentPanel.Controls.Add(this.ToolsListObjView);
|
||||
this.ToolStripContainer.ContentPanel.Size = new System.Drawing.Size(684, 298);
|
||||
this.ToolStripContainer.ContentPanel.Size = new System.Drawing.Size(827, 376);
|
||||
this.ToolStripContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ToolStripContainer.Location = new System.Drawing.Point(0, 0);
|
||||
this.ToolStripContainer.Name = "ToolStripContainer";
|
||||
this.ToolStripContainer.Size = new System.Drawing.Size(684, 323);
|
||||
this.ToolStripContainer.Size = new System.Drawing.Size(827, 401);
|
||||
this.ToolStripContainer.TabIndex = 0;
|
||||
this.ToolStripContainer.Text = "ToolStripContainer";
|
||||
//
|
||||
@@ -351,6 +482,7 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// DeleteToolToolstripButton
|
||||
//
|
||||
this.DeleteToolToolstripButton.Enabled = false;
|
||||
this.DeleteToolToolstripButton.Image = global::mRemoteNG.Resources.ExtApp_Delete;
|
||||
this.DeleteToolToolstripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.DeleteToolToolstripButton.Name = "DeleteToolToolstripButton";
|
||||
@@ -365,6 +497,7 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// LaunchToolToolstripButton
|
||||
//
|
||||
this.LaunchToolToolstripButton.Enabled = false;
|
||||
this.LaunchToolToolstripButton.Image = global::mRemoteNG.Resources.ExtApp_Start;
|
||||
this.LaunchToolToolstripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.LaunchToolToolstripButton.Name = "LaunchToolToolstripButton";
|
||||
@@ -378,7 +511,7 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// ExternalToolsWindow
|
||||
//
|
||||
this.ClientSize = new System.Drawing.Size(684, 323);
|
||||
this.ClientSize = new System.Drawing.Size(827, 401);
|
||||
this.Controls.Add(this.ToolStripContainer);
|
||||
this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
@@ -411,5 +544,6 @@ namespace mRemoteNG.UI.Window
|
||||
#endregion
|
||||
|
||||
private System.ComponentModel.IContainer components;
|
||||
internal Controls.Base.NGGroupBox PropertiesGroupBox;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using BrightIdeasSoftware;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Config.Settings;
|
||||
using mRemoteNG.Tools;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.Themes;
|
||||
using mRemoteNG.Tools.CustomCollections;
|
||||
|
||||
namespace mRemoteNG.UI.Window
|
||||
{
|
||||
public partial class ExternalToolsWindow
|
||||
{
|
||||
private readonly ExternalAppsSaver _externalAppsSaver;
|
||||
private ExternalTool _selectedTool;
|
||||
private ThemeManager _themeManager;
|
||||
private readonly ThemeManager _themeManager;
|
||||
private readonly FullyObservableCollection<ExternalTool> _currentlySelectedExternalTools;
|
||||
|
||||
public ExternalToolsWindow()
|
||||
{
|
||||
@@ -24,23 +26,120 @@ namespace mRemoteNG.UI.Window
|
||||
_themeManager = ThemeManager.getInstance();
|
||||
_themeManager.ThemeChanged += ApplyTheme;
|
||||
_externalAppsSaver = new ExternalAppsSaver();
|
||||
_currentlySelectedExternalTools = new FullyObservableCollection<ExternalTool>();
|
||||
_currentlySelectedExternalTools.CollectionUpdated += CurrentlySelectedExternalToolsOnCollectionUpdated;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Private Methods
|
||||
#region Private Methods
|
||||
private void ExternalTools_Load(object sender, EventArgs e)
|
||||
{
|
||||
ApplyLanguage();
|
||||
ApplyTheme();
|
||||
UpdateToolsListObjView();
|
||||
}
|
||||
|
||||
private void ApplyLanguage()
|
||||
{
|
||||
Text = Language.strMenuExternalTools;
|
||||
TabText = Language.strMenuExternalTools;
|
||||
|
||||
NewToolToolstripButton.Text = Language.strButtonNew;
|
||||
DeleteToolToolstripButton.Text = Language.strOptionsKeyboardButtonDelete;
|
||||
LaunchToolToolstripButton.Text = Language.strButtonLaunch;
|
||||
|
||||
DisplayNameColumnHeader.Text = Language.strColumnDisplayName;
|
||||
FilenameColumnHeader.Text = Language.strColumnFilename;
|
||||
ArgumentsColumnHeader.Text = Language.strColumnArguments;
|
||||
WaitForExitColumnHeader.Text = Language.strColumnWaitForExit;
|
||||
TryToIntegrateCheckBox.Text = Language.strTryIntegrate;
|
||||
ShowOnToolbarCheckBox.Text = Language.strShowOnToolbar;
|
||||
|
||||
PropertiesGroupBox.Text = Language.strGroupboxExternalToolProperties;
|
||||
|
||||
DisplayNameLabel.Text = Language.strLabelDisplayName;
|
||||
FilenameLabel.Text = Language.strLabelFilename;
|
||||
ArgumentsLabel.Text = Language.strLabelArguments;
|
||||
OptionsLabel.Text = Language.strLabelOptions;
|
||||
WaitForExitCheckBox.Text = Language.strCheckboxWaitForExit;
|
||||
BrowseButton.Text = Language.strButtonBrowse;
|
||||
|
||||
NewToolMenuItem.Text = Language.strMenuNewExternalTool;
|
||||
DeleteToolMenuItem.Text = Language.strMenuDeleteExternalTool;
|
||||
LaunchToolMenuItem.Text = Language.strMenuLaunchExternalTool;
|
||||
}
|
||||
|
||||
private new void ApplyTheme()
|
||||
{
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
vsToolStripExtender.SetStyle(ToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(ToolsContextMenuStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
//Apply the extended palette
|
||||
|
||||
ToolStripContainer.TopToolStripPanel.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
|
||||
ToolStripContainer.TopToolStripPanel.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
|
||||
PropertiesGroupBox.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
|
||||
PropertiesGroupBox.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
|
||||
}
|
||||
|
||||
private void UpdateToolsListObjView()
|
||||
{
|
||||
try
|
||||
{
|
||||
ToolsListObjView.BeginUpdate();
|
||||
ToolsListObjView.SetObjects(Runtime.ExternalToolsService.ExternalTools, true);
|
||||
ToolsListObjView.AutoResizeColumns();
|
||||
ToolsListObjView.EndUpdate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.PopulateToolsListObjView()", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchTool()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var externalTool in _currentlySelectedExternalTools)
|
||||
{
|
||||
externalTool.Start();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.LaunchTool() failed.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateEditorControls()
|
||||
{
|
||||
var selectedTool = _currentlySelectedExternalTools.FirstOrDefault();
|
||||
|
||||
DisplayNameTextBox.Text = selectedTool?.DisplayName;
|
||||
FilenameTextBox.Text = selectedTool?.FileName;
|
||||
ArgumentsCheckBox.Text = selectedTool?.Arguments;
|
||||
WorkingDirTextBox.Text = selectedTool?.WorkingDir;
|
||||
WaitForExitCheckBox.Checked = selectedTool?.WaitForExit ?? false;
|
||||
TryToIntegrateCheckBox.Checked = selectedTool?.TryIntegrate ?? false;
|
||||
ShowOnToolbarCheckBox.Checked = selectedTool?.ShowOnToolbar ?? false;
|
||||
RunElevatedCheckBox.Checked = selectedTool?.RunElevated ?? false;
|
||||
WaitForExitCheckBox.Enabled = !TryToIntegrateCheckBox.Checked;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
private void ExternalTools_Load(object sender, EventArgs e)
|
||||
{
|
||||
ApplyLanguage();
|
||||
ApplyTheme();
|
||||
UpdateToolsListObjView();
|
||||
}
|
||||
private void CurrentlySelectedExternalToolsOnCollectionUpdated(object sender, CollectionUpdatedEventArgs<ExternalTool> collectionUpdatedEventArgs)
|
||||
{
|
||||
UpdateEditorControls();
|
||||
}
|
||||
|
||||
private void ExternalTools_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
_externalAppsSaver.Save(Runtime.ExternalToolsService.ExternalTools);
|
||||
}
|
||||
_themeManager.ThemeChanged -= ApplyTheme;
|
||||
_currentlySelectedExternalTools.CollectionUpdated -= CurrentlySelectedExternalToolsOnCollectionUpdated;
|
||||
}
|
||||
|
||||
private void NewTool_Click(object sender, EventArgs e)
|
||||
{
|
||||
@@ -48,7 +147,8 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
var externalTool = new ExternalTool(Language.strExternalToolDefaultName);
|
||||
Runtime.ExternalToolsService.ExternalTools.Add(externalTool);
|
||||
UpdateToolsListObjView(externalTool);
|
||||
UpdateToolsListObjView();
|
||||
ToolsListObjView.SelectedObject = externalTool;
|
||||
DisplayNameTextBox.Focus();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -62,31 +162,29 @@ namespace mRemoteNG.UI.Window
|
||||
try
|
||||
{
|
||||
string message;
|
||||
if (ToolsListObjView.SelectedItems.Count == 1)
|
||||
{
|
||||
message = string.Format(Language.strConfirmDeleteExternalTool, ToolsListObjView.SelectedItems[0].Text);
|
||||
}
|
||||
else if (ToolsListObjView.SelectedItems.Count > 1)
|
||||
{
|
||||
message = string.Format(Language.strConfirmDeleteExternalToolMultiple, ToolsListObjView.SelectedItems.Count);
|
||||
}
|
||||
if (_currentlySelectedExternalTools.Count == 1)
|
||||
message = string.Format(Language.strConfirmDeleteExternalTool, _currentlySelectedExternalTools[0].DisplayName);
|
||||
else if (_currentlySelectedExternalTools.Count > 1)
|
||||
message = string.Format(Language.strConfirmDeleteExternalToolMultiple, _currentlySelectedExternalTools.Count);
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (MessageBox.Show(FrmMain.Default, message, "Question?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Object toDeleteObj in ToolsListObjView.SelectedObjects)
|
||||
foreach (var externalTool in _currentlySelectedExternalTools)
|
||||
{
|
||||
var externalTool = toDeleteObj as ExternalTool;
|
||||
if (externalTool == null) continue;
|
||||
Runtime.ExternalToolsService.ExternalTools.Remove(externalTool);
|
||||
}
|
||||
var firstDeletedNode = _currentlySelectedExternalTools.FirstOrDefault();
|
||||
var oldSelectedIndex = ToolsListObjView.IndexOf(firstDeletedNode);
|
||||
_currentlySelectedExternalTools.Clear();
|
||||
UpdateToolsListObjView();
|
||||
|
||||
var maxIndex = ToolsListObjView.GetItemCount() - 1;
|
||||
ToolsListObjView.SelectedIndex = oldSelectedIndex <= maxIndex
|
||||
? oldSelectedIndex
|
||||
: maxIndex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -103,25 +201,15 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ToolsListObjView.SelectedItems.Count == 1)
|
||||
{
|
||||
PropertiesGroupBox.Enabled = true;
|
||||
_selectedTool = ToolsListObjView.SelectedObjects[0] as ExternalTool;
|
||||
if (_selectedTool == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayNameTextBox.Text = _selectedTool.DisplayName;
|
||||
FilenameTextBox.Text = _selectedTool.FileName;
|
||||
ArgumentsCheckBox.Text = _selectedTool.Arguments;
|
||||
WaitForExitCheckBox.Checked = _selectedTool.WaitForExit;
|
||||
TryToIntegrateCheckBox.Checked = _selectedTool.TryIntegrate;
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertiesGroupBox.Enabled = false;
|
||||
}
|
||||
_currentlySelectedExternalTools.Clear();
|
||||
_currentlySelectedExternalTools.AddRange(ToolsListObjView.SelectedObjects.OfType<ExternalTool>());
|
||||
PropertiesGroupBox.Enabled = _currentlySelectedExternalTools.Count == 1;
|
||||
|
||||
var atleastOneToolSelected = _currentlySelectedExternalTools.Count > 0;
|
||||
DeleteToolMenuItem.Enabled = atleastOneToolSelected;
|
||||
DeleteToolToolstripButton.Enabled = atleastOneToolSelected;
|
||||
LaunchToolMenuItem.Enabled = atleastOneToolSelected;
|
||||
LaunchToolToolstripButton.Enabled = atleastOneToolSelected;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -139,20 +227,22 @@ namespace mRemoteNG.UI.Window
|
||||
|
||||
private void PropertyControl_ChangedOrLostFocus(object sender, EventArgs e)
|
||||
{
|
||||
if (_selectedTool == null)
|
||||
{
|
||||
var selectedTool = _currentlySelectedExternalTools.FirstOrDefault();
|
||||
if (selectedTool == null)
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_selectedTool.DisplayName = DisplayNameTextBox.Text;
|
||||
_selectedTool.FileName = FilenameTextBox.Text;
|
||||
_selectedTool.Arguments = ArgumentsCheckBox.Text;
|
||||
_selectedTool.WaitForExit = WaitForExitCheckBox.Checked;
|
||||
_selectedTool.TryIntegrate = TryToIntegrateCheckBox.Checked;
|
||||
|
||||
UpdateToolsListObjView();
|
||||
selectedTool.DisplayName = DisplayNameTextBox.Text;
|
||||
selectedTool.FileName = FilenameTextBox.Text;
|
||||
selectedTool.Arguments = ArgumentsCheckBox.Text;
|
||||
selectedTool.WorkingDir = WorkingDirTextBox.Text;
|
||||
selectedTool.WaitForExit = WaitForExitCheckBox.Checked;
|
||||
selectedTool.TryIntegrate = TryToIntegrateCheckBox.Checked;
|
||||
selectedTool.ShowOnToolbar = ShowOnToolbarCheckBox.Checked;
|
||||
selectedTool.RunElevated = RunElevatedCheckBox.Checked;
|
||||
|
||||
UpdateToolsListObjView();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -166,128 +256,53 @@ namespace mRemoteNG.UI.Window
|
||||
{
|
||||
using (var browseDialog = new OpenFileDialog())
|
||||
{
|
||||
browseDialog.Filter = string.Join("|", new string[] {Language.strFilterApplication, "*.exe", Language.strFilterAll, "*.*"});
|
||||
if (browseDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
FilenameTextBox.Text = browseDialog.FileName;
|
||||
}
|
||||
browseDialog.Filter = string.Join("|", Language.strFilterApplication, "*.exe", Language.strFilterAll, "*.*");
|
||||
if (browseDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
var selectedItem = _currentlySelectedExternalTools.FirstOrDefault();
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
selectedItem.FileName = browseDialog.FileName;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.BrowseButton_Click() failed.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void TryToIntegrateCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (TryToIntegrateCheckBox.Checked)
|
||||
{
|
||||
WaitForExitCheckBox.Enabled = false;
|
||||
WaitForExitCheckBox.Checked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForExitCheckBox.Enabled = true;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void ApplyLanguage()
|
||||
{
|
||||
Text = Language.strMenuExternalTools;
|
||||
TabText = Language.strMenuExternalTools;
|
||||
|
||||
NewToolToolstripButton.Text = Language.strButtonNew;
|
||||
DeleteToolToolstripButton.Text = Language.strOptionsKeyboardButtonDelete;
|
||||
LaunchToolToolstripButton.Text = Language.strButtonLaunch;
|
||||
|
||||
DisplayNameColumnHeader.Text = Language.strColumnDisplayName;
|
||||
FilenameColumnHeader.Text = Language.strColumnFilename;
|
||||
ArgumentsColumnHeader.Text = Language.strColumnArguments;
|
||||
WaitForExitColumnHeader.Text = Language.strColumnWaitForExit;
|
||||
TryToIntegrateCheckBox.Text = Language.strTryIntegrate;
|
||||
|
||||
PropertiesGroupBox.Text = Language.strGroupboxExternalToolProperties;
|
||||
|
||||
DisplayNameLabel.Text = Language.strLabelDisplayName;
|
||||
FilenameLabel.Text = Language.strLabelFilename;
|
||||
ArgumentsLabel.Text = Language.strLabelArguments;
|
||||
OptionsLabel.Text = Language.strLabelOptions;
|
||||
WaitForExitCheckBox.Text = Language.strCheckboxWaitForExit;
|
||||
BrowseButton.Text = Language.strButtonBrowse;
|
||||
|
||||
NewToolMenuItem.Text = Language.strMenuNewExternalTool;
|
||||
DeleteToolMenuItem.Text = Language.strMenuDeleteExternalTool;
|
||||
LaunchToolMenuItem.Text = Language.strMenuLaunchExternalTool;
|
||||
}
|
||||
|
||||
private new void ApplyTheme()
|
||||
{
|
||||
if (!_themeManager.ThemingActive) return;
|
||||
vsToolStripExtender.SetStyle(ToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
vsToolStripExtender.SetStyle(ToolsContextMenuStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
|
||||
//Apply the extended palette
|
||||
|
||||
ToolStripContainer.TopToolStripPanel.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
|
||||
ToolStripContainer.TopToolStripPanel.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
|
||||
PropertiesGroupBox.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
|
||||
PropertiesGroupBox.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
|
||||
//Toollist grouping
|
||||
ToolsListObjView.AlwaysGroupByColumn = this.FilenameColumnHeader;
|
||||
}
|
||||
|
||||
private void UpdateToolsListObjView(ExternalTool selectTool = null)
|
||||
private void BrowseWorkingDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
var selectedTools = new List<ExternalTool>();
|
||||
try
|
||||
{
|
||||
if (selectTool == null)
|
||||
{
|
||||
foreach (var listViewItem in ToolsListObjView.SelectedObjects)
|
||||
{
|
||||
var externalTool = listViewItem as ExternalTool;
|
||||
if (externalTool != null)
|
||||
{
|
||||
selectedTools.Add(externalTool);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedTools.Add(selectTool);
|
||||
}
|
||||
|
||||
ToolsListObjView.BeginUpdate();
|
||||
ToolsListObjView.Items.Clear();
|
||||
ToolsListObjView.SetObjects(Runtime.ExternalToolsService.ExternalTools);
|
||||
ToolsListObjView.EndUpdate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.PopulateToolsListObjView()", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchTool()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Object listViewObject in ToolsListObjView.SelectedObjects)
|
||||
{
|
||||
|
||||
((ExternalTool)listViewObject).Start();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.LaunchTool() failed.", ex);
|
||||
}
|
||||
}
|
||||
using (var browseDialog = new FolderBrowserDialog())
|
||||
{
|
||||
if (browseDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
var selectedItem = _currentlySelectedExternalTools.FirstOrDefault();
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
selectedItem.WorkingDir = browseDialog.SelectedPath;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.BrowseButton_Click() failed.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void ToolsListObjView_CellToolTipShowing(object sender, ToolTipShowingEventArgs e)
|
||||
{
|
||||
if (e.Column != WaitForExitColumnHeader)
|
||||
return;
|
||||
|
||||
var rowItemAsExternalTool = e.Model as ExternalTool;
|
||||
if (rowItemAsExternalTool == null || !rowItemAsExternalTool.TryIntegrate)
|
||||
return;
|
||||
|
||||
e.Text = string.Format("'{0}' cannot be enabled if '{1}' is enabled", Language.strCheckboxWaitForExit, Language.strTryIntegrate);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
1605
mRemoteV1/app.config
1605
mRemoteV1/app.config
File diff suppressed because it is too large
Load Diff
@@ -75,6 +75,7 @@
|
||||
<HintPath>..\packages\SSH.NET.2016.0.0\lib\net40\Renci.SshNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Drawing" />
|
||||
@@ -107,7 +108,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Credential\Records\" />
|
||||
<Folder Include="Properties\DataSources\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App\CompatibilityChecker.cs" />
|
||||
@@ -198,7 +198,6 @@
|
||||
<Compile Include="Config\Settings\ExternalAppsSaver.cs" />
|
||||
<Compile Include="Config\Settings\DockPanelLayoutLoader.cs" />
|
||||
<Compile Include="Config\Settings\DockPanelLayoutSaver.cs" />
|
||||
<Compile Include="Config\Settings\Providers\AppSettingsProvider.cs" />
|
||||
<Compile Include="Config\Settings\Providers\ChooseProvider.cs" />
|
||||
<Compile Include="Config\Settings\SettingsLoader.cs" />
|
||||
<Compile Include="Config\Settings\Providers\PortableSettingsProvider.cs" />
|
||||
@@ -307,6 +306,7 @@
|
||||
<Compile Include="Tools\Cmdline\StartupArgumentsInterpreter.cs" />
|
||||
<Compile Include="Tools\CustomCollections\CollectionUpdatedEventArgs.cs" />
|
||||
<Compile Include="Tools\DesignModeTest.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Tools\Extensions.cs" />
|
||||
<Compile Include="Tools\ExternalToolArgumentParser.cs" />
|
||||
<Compile Include="Tools\Cmdline\CmdArgumentsInterpreter.cs" />
|
||||
@@ -1598,4 +1598,4 @@ powershell.exe -ExecutionPolicy Bypass -File "%25psScriptsDir%25\postbuild_mremo
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Geckofx45.45.0.32\build\Geckofx45.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Geckofx45.45.0.32\build\Geckofx45.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user