Improve handling of variables in external tool arguments.
Code cleanup.
@@ -9,6 +9,7 @@
|
||||
Removed invalid "Site" configuration option from PuTTY Saved Sessions.
|
||||
Fixed PuTTY Saved Sessions still showing if all saved sessions are removed.
|
||||
Fixed config panel showing settings from previously loaded connection file after loading a new one.
|
||||
Improved handling of variables in external tool arguments.
|
||||
|
||||
1.72 (2013-11-13):
|
||||
Fixed issue MR-592 - Unable to run VBS script as an external tool
|
||||
|
||||
10
Local.testsettings
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TestSettings name="Local" id="2a25bb82-f5ff-4a67-b5e9-c6aaa54d1e80" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<Description>These are default test settings for a local test run.</Description>
|
||||
<Deployment enabled="false" />
|
||||
<Execution>
|
||||
<TestTypeSpecific />
|
||||
<AgentRule name="Execution Agents">
|
||||
</AgentRule>
|
||||
</Execution>
|
||||
</TestSettings>
|
||||
145
TestProject/ExternalToolTest.vb
Normal file
@@ -0,0 +1,145 @@
|
||||
Imports Microsoft.VisualStudio.TestTools.UnitTesting
|
||||
|
||||
Imports mRemoteNG.Tools
|
||||
Imports mRemoteNG.Connection.PuttySession
|
||||
|
||||
|
||||
'''<summary>
|
||||
'''This is a test class for ExternalToolTest and is intended
|
||||
'''to contain all ExternalToolTest Unit Tests
|
||||
'''</summary>
|
||||
<TestClass()> _
|
||||
Public Class ExternalToolTest
|
||||
'''<summary>
|
||||
'''Gets or sets the test context which provides
|
||||
'''information about and functionality for the current test run.
|
||||
'''</summary>
|
||||
Public Property TestContext() As TestContext
|
||||
|
||||
#Region "Additional test attributes"
|
||||
'
|
||||
'You can use the following additional attributes as you write your tests:
|
||||
'
|
||||
'Use ClassInitialize to run code before running the first test in the class
|
||||
'<ClassInitialize()> _
|
||||
'Public Shared Sub MyClassInitialize(ByVal testContext As TestContext)
|
||||
'End Sub
|
||||
'
|
||||
'Use ClassCleanup to run code after all tests in a class have run
|
||||
'<ClassCleanup()> _
|
||||
'Public Shared Sub MyClassCleanup()
|
||||
'End Sub
|
||||
'
|
||||
'Use TestInitialize to run code before running each test
|
||||
'<TestInitialize()> _
|
||||
'Public Sub MyTestInitialize()
|
||||
'End Sub
|
||||
'
|
||||
'Use TestCleanup to run code after each test has run
|
||||
'<TestCleanup()> _
|
||||
'Public Sub MyTestCleanup()
|
||||
'End Sub
|
||||
'
|
||||
#End Region
|
||||
|
||||
|
||||
'''<summary>
|
||||
'''A test for ParseArguments
|
||||
'''</summary>
|
||||
<TestMethod(), _
|
||||
DeploymentItem("mRemoteNG.exe")> _
|
||||
Public Sub ParseArgumentsTest()
|
||||
Dim externalTool As New ExternalTool
|
||||
|
||||
' ReSharper disable StringLiteralTypo
|
||||
externalTool.ConnectionInfo = New Info()
|
||||
With externalTool.ConnectionInfo
|
||||
.Name = "EMAN"
|
||||
.Hostname = "EMANTSOH"
|
||||
.Port = 9876
|
||||
.Username = "EMANRESU"
|
||||
.Password = "DROWSSAP"
|
||||
.Domain = "NIAMOD"
|
||||
.Description = "NOITPIRCSED"
|
||||
.MacAddress = "SSERDDACAM"
|
||||
.UserField = "DLEIFRESU"
|
||||
End With
|
||||
|
||||
Assert.AreEqual("EMAN, EMANTSOH, 9876, EMANRESU, DROWSSAP, NIAMOD, NOITPIRCSED, SSERDDACAM, DLEIFRESU", externalTool.ParseArguments("%NAME%, %HOSTNAME%, %PORT%, %USERNAME%, %PASSWORD%, %DOMAIN%, %DESCRIPTION%, %MACADDRESS%, %USERFIELD%"))
|
||||
' ReSharper restore StringLiteralTypo
|
||||
|
||||
Assert.AreEqual(Environment.ExpandEnvironmentVariables("%PATH%"), externalTool.ParseArguments("%!PATH%"))
|
||||
|
||||
externalTool.ConnectionInfo.Name = "()%!^""<>&|\""\\"
|
||||
|
||||
Assert.AreEqual("%%", externalTool.ParseArguments("%%"))
|
||||
Assert.AreEqual("% %", externalTool.ParseArguments("% %"))
|
||||
Assert.AreEqual("%-%", externalTool.ParseArguments("%-%"))
|
||||
Assert.AreEqual("%!%", externalTool.ParseArguments("%!%"))
|
||||
Assert.AreEqual("%^%", externalTool.ParseArguments("%^%"))
|
||||
Assert.AreEqual("%%%", externalTool.ParseArguments("%%%"))
|
||||
Assert.AreEqual("%foobar%", externalTool.ParseArguments("%foobar%"))
|
||||
Assert.AreEqual("%-foobar%", externalTool.ParseArguments("%-foobar%"))
|
||||
Assert.AreEqual("%!foobar%", externalTool.ParseArguments("%!foobar%"))
|
||||
Assert.AreEqual("%-!^\", externalTool.ParseArguments("%-!^\"))
|
||||
|
||||
Assert.AreEqual("^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("%NAME%"))
|
||||
Assert.AreEqual("^(^)^%^!^^^""^<^>^&^|\^""\\", externalTool.ParseArguments("%-NAME%"))
|
||||
Assert.AreEqual("()%!^""<>&|\""\\", externalTool.ParseArguments("%!NAME%"))
|
||||
|
||||
Assert.AreEqual("^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("%name%"))
|
||||
Assert.AreEqual("%^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("%%name%"))
|
||||
Assert.AreEqual("^(^)^%^!^^\^""^<^>^&^|\\\^""\\%", externalTool.ParseArguments("%name%%"))
|
||||
Assert.AreEqual("^(^)^%^!^^\^""^<^>^&^|\\\^""\\ ^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("%name% %name%"))
|
||||
|
||||
Assert.AreEqual("%-^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("%-%name%"))
|
||||
Assert.AreEqual("^(^)^%^!^^\^""^<^>^&^|\\\^""\\-%", externalTool.ParseArguments("%name%-%"))
|
||||
Assert.AreEqual("%!^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("%!%name%"))
|
||||
Assert.AreEqual("^(^)^%^!^^\^""^<^>^&^|\\\^""\\!%", externalTool.ParseArguments("%name%!%"))
|
||||
|
||||
Assert.AreEqual("\^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("\%NAME%"))
|
||||
Assert.AreEqual("\^(^)^%^!^^\^""^<^>^&^|\\\^""\\NAME%", externalTool.ParseArguments("\%NAME%NAME%"))
|
||||
Assert.AreEqual("%NAME\%", externalTool.ParseArguments("%NAME\%"))
|
||||
|
||||
Assert.AreEqual("""^(^)^%^!^^\^""^<^>^&^|\\\^""\\\\""", externalTool.ParseArguments("""%NAME%"""))
|
||||
Assert.AreEqual("""^(^)^%^!^^^""^<^>^&^|\^""\\""", externalTool.ParseArguments("""%-NAME%"""))
|
||||
Assert.AreEqual("""()%!^""<>&|\""\\""", externalTool.ParseArguments("""%!NAME%"""))
|
||||
|
||||
Assert.AreEqual("""^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("""%NAME%"))
|
||||
Assert.AreEqual("""^(^)^%^!^^^""^<^>^&^|\^""\\", externalTool.ParseArguments("""%-NAME%"))
|
||||
Assert.AreEqual("""()%!^""<>&|\""\\", externalTool.ParseArguments("""%!NAME%"))
|
||||
|
||||
Assert.AreEqual("^(^)^%^!^^\^""^<^>^&^|\\\^""\\\\""", externalTool.ParseArguments("%NAME%"""))
|
||||
Assert.AreEqual("^(^)^%^!^^^""^<^>^&^|\^""\\""", externalTool.ParseArguments("%-NAME%"""))
|
||||
Assert.AreEqual("()%!^""<>&|\""\\""", externalTool.ParseArguments("%!NAME%"""))
|
||||
|
||||
Assert.AreEqual(Environment.ExpandEnvironmentVariables("%USERNAME%"), externalTool.ParseArguments("\%USERNAME\%"))
|
||||
Assert.AreEqual(Environment.ExpandEnvironmentVariables("%USERNAME%"), externalTool.ParseArguments("\%-USERNAME\%"))
|
||||
Assert.AreEqual(Environment.ExpandEnvironmentVariables("%USERNAME%"), externalTool.ParseArguments("\%!USERNAME\%"))
|
||||
|
||||
Assert.AreEqual("\^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("\%NAME%"))
|
||||
Assert.AreEqual("%NAME\%", externalTool.ParseArguments("%NAME\%"))
|
||||
Assert.AreEqual("\\%NAME\\%", externalTool.ParseArguments("\\%NAME\\%"))
|
||||
Assert.AreEqual("\\\%NAME\\\%", externalTool.ParseArguments("\\\%NAME\\\%"))
|
||||
Assert.AreEqual("\\\\%NAME\\\\%", externalTool.ParseArguments("\\\\%NAME\\\\%"))
|
||||
Assert.AreEqual("\\\\\%NAME\\\\\%", externalTool.ParseArguments("\\\\\%NAME\\\\\%"))
|
||||
|
||||
Assert.AreEqual("%NAME%", externalTool.ParseArguments("^%NAME^%"))
|
||||
Assert.AreEqual("%-NAME%", externalTool.ParseArguments("^%-NAME^%"))
|
||||
Assert.AreEqual("\%NAME\%", externalTool.ParseArguments("\^%NAME\^%"))
|
||||
Assert.AreEqual("\%-NAME\%", externalTool.ParseArguments("\^%-NAME\^%"))
|
||||
|
||||
Assert.AreEqual("^%NAME^%", externalTool.ParseArguments("^^%NAME^^%"))
|
||||
Assert.AreEqual("^%-NAME^%", externalTool.ParseArguments("^^%-NAME^^%"))
|
||||
Assert.AreEqual("^^^^%NAME^^^^%", externalTool.ParseArguments("^^^^^%NAME^^^^^%"))
|
||||
Assert.AreEqual("^^^^%-NAME^^^^%", externalTool.ParseArguments("^^^^^%-NAME^^^^^%"))
|
||||
Assert.AreEqual("^^^^%!NAME^^^^%", externalTool.ParseArguments("^^^^^%!NAME^^^^^%"))
|
||||
|
||||
Assert.AreEqual("blah%blah", externalTool.ParseArguments("blah%blah"))
|
||||
Assert.AreEqual("blah^%blah", externalTool.ParseArguments("blah^%blah"))
|
||||
Assert.AreEqual("blah^^%blah", externalTool.ParseArguments("blah^^%blah"))
|
||||
Assert.AreEqual("blah^^^%blah", externalTool.ParseArguments("blah^^^%blah"))
|
||||
|
||||
Assert.AreEqual("^^^^%-NAME^^^^% ^(^)^%^!^^\^""^<^>^&^|\\\^""\\", externalTool.ParseArguments("^^^^^%-NAME^^^^^% %NAME%"))
|
||||
End Sub
|
||||
End Class
|
||||
37
TestProject/My Project/AssemblyInfo.vb
Normal file
@@ -0,0 +1,37 @@
|
||||
Imports System
|
||||
Imports System.Reflection
|
||||
Imports 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.
|
||||
|
||||
' Review the values of the assembly attributes
|
||||
|
||||
<Assembly: AssemblyTitle("TestProject")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyProduct("TestProject")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2013")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: CLSCompliant(True)>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
<Assembly: Guid("8918ad54-4841-44e9-abda-e1b787b02c7c")>
|
||||
|
||||
' 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")>
|
||||
2
TestProject/Test References/mRemoteNG.accessor
Normal file
@@ -0,0 +1,2 @@
|
||||
mRemoteNG.exe
|
||||
Desktop
|
||||
181
TestProject/TestProject.vbproj
Normal file
@@ -0,0 +1,181 @@
|
||||
<?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>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>
|
||||
</SchemaVersion>
|
||||
<ProjectGuid>{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>TestProject</RootNamespace>
|
||||
<AssemblyName>TestProject</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids>
|
||||
<ReferencePath>$(DevEnvDir)PublicAssemblies\</ReferencePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DocumentationFile>TestProject.xml</DocumentationFile>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DefineDebug>false</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DocumentationFile>TestProject.xml</DocumentationFile>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionExplicit>On</OptionExplicit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionCompare>Binary</OptionCompare>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionStrict>Off</OptionStrict>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ADTree">
|
||||
<HintPath>..\mRemoteV1\References\ADTree.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="AxInterop.MSTSCLib">
|
||||
<HintPath>..\mRemoteV1\obj\Debug\AxInterop.MSTSCLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="AxInterop.WFICALib">
|
||||
<HintPath>..\mRemoteV1\obj\Debug\AxInterop.WFICALib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DiffieHellman">
|
||||
<HintPath>..\mRemoteV1\References\DiffieHellman.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FilteredPropertyGrid">
|
||||
<HintPath>..\mRemoteV1\References\FilteredPropertyGrid.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Interop.EOLWTSCOM">
|
||||
<HintPath>..\mRemoteV1\obj\Debug\Interop.EOLWTSCOM.dll</HintPath>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Interop.MSTSCLib">
|
||||
<HintPath>..\mRemoteV1\obj\Debug\Interop.MSTSCLib.dll</HintPath>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Interop.SHDocVw">
|
||||
<HintPath>..\mRemoteV1\obj\Debug\Interop.SHDocVw.dll</HintPath>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Interop.WFICALib">
|
||||
<HintPath>..\mRemoteV1\obj\Debug\Interop.WFICALib.dll</HintPath>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="IPTextBox">
|
||||
<HintPath>..\mRemoteV1\References\IPTextBox.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net">
|
||||
<HintPath>..\mRemoteV1\References\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MagicLibrary, Version=1.7.4.0, Culture=neutral, PublicKeyToken=3a6eb82f876a49bc">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualBasic.PowerPacks.Vs, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="MiniGeckoBrowser">
|
||||
<HintPath>..\mRemoteV1\References\MiniGeckoBrowser.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MiniTabControl">
|
||||
<HintPath>..\mRemoteV1\References\MiniTabControl.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Org.Mentalis.Security">
|
||||
<HintPath>..\mRemoteV1\References\Org.Mentalis.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PSTaskDialog">
|
||||
<HintPath>..\mRemoteV1\References\PSTaskDialog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Skybound.Gecko">
|
||||
<HintPath>..\mRemoteV1\References\Skybound.Gecko.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="Tamir.SharpSSH">
|
||||
<HintPath>..\mRemoteV1\References\Tamir.SharpSSH.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="VncSharpNG">
|
||||
<HintPath>..\mRemoteV1\References\VncSharpNG.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WeifenLuo.WinFormsUI.Docking">
|
||||
<HintPath>..\mRemoteV1\References\WeifenLuo.WinFormsUI.Docking.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="System" />
|
||||
<Import Include="System.Collections" />
|
||||
<Import Include="System.Collections.Generic" />
|
||||
<Import Include="System.Data" />
|
||||
<Import Include="System.Diagnostics" />
|
||||
<Import Include="System.Linq" />
|
||||
<Import Include="System.Xml.Linq" />
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
|
||||
<Visible>False</Visible>
|
||||
</CodeAnalysisDependentAssemblyPaths>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ExternalToolTest.vb" />
|
||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Shadow Include="Test References\mRemoteNG.accessor" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\SharedLibraryNG\SharedLibraryNG\SharedLibraryNG.csproj">
|
||||
<Project>{0F615504-5F30-4CF2-8341-1DE7FEC95A23}</Project>
|
||||
<Name>SharedLibraryNG</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\mRemoteV1\mRemoteV1.vbproj">
|
||||
<Project>{4934A491-40BC-4E5B-9166-EA1169A220F6}</Project>
|
||||
<Name>mRemoteV1</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.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>
|
||||
19
TraceAndTestImpact.testsettings
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TestSettings name="Trace and Test Impact" id="e062ce86-3357-43c9-b5c3-6b38a0dc3776" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<Description>These are test settings for Trace and Test Impact.</Description>
|
||||
<Execution>
|
||||
<TestTypeSpecific />
|
||||
<AgentRule name="Execution Agents">
|
||||
<DataCollectors>
|
||||
<DataCollector uri="datacollector://microsoft/SystemInfo/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo.SystemInfoDataCollector, Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="System Information">
|
||||
</DataCollector>
|
||||
<DataCollector uri="datacollector://microsoft/HttpProxy/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.HttpProxyCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="ASP.NET Client Proxy for IntelliTrace and Test Impact">
|
||||
</DataCollector>
|
||||
<DataCollector uri="datacollector://microsoft/TestImpact/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.TestImpactDataCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Test Impact">
|
||||
</DataCollector>
|
||||
<DataCollector uri="datacollector://microsoft/TraceDebugger/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.TraceDebuggerDataCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="IntelliTrace">
|
||||
</DataCollector>
|
||||
</DataCollectors>
|
||||
</AgentRule>
|
||||
</Execution>
|
||||
</TestSettings>
|
||||
@@ -5,7 +5,19 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "mRemoteV1", "mRemoteV1\mRem
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedLibraryNG", "..\SharedLibraryNG\SharedLibraryNG\SharedLibraryNG.csproj", "{0F615504-5F30-4CF2-8341-1DE7FEC95A23}"
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "TestProject", "TestProject\TestProject.vbproj", "{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{38EB1EFD-C8C8-49A2-BCA7-63F7A02B3153}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Local.testsettings = Local.testsettings
|
||||
mRemoteV1.vsmdi = mRemoteV1.vsmdi
|
||||
TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(TestCaseManagementSettings) = postSolution
|
||||
CategoryFile = mRemoteV1.vsmdi
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug Portable|Any CPU = Debug Portable|Any CPU
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -29,6 +41,14 @@ Global
|
||||
{0F615504-5F30-4CF2-8341-1DE7FEC95A23}.Release Portable|Any CPU.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
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Debug Portable|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Debug Portable|Any CPU.Build.0 = Debug|Any CPU
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Release Portable|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Release Portable|Any CPU.Build.0 = Release|Any CPU
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{24E0689D-95C0-4AAB-A93F-B8D6B7F0CB97}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
6
mRemoteV1.vsmdi
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
|
||||
<RunConfiguration id="2a25bb82-f5ff-4a67-b5e9-c6aaa54d1e80" name="Local" storage="local.testsettings" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
</TestList>
|
||||
</TestLists>
|
||||
@@ -1731,7 +1731,7 @@ Namespace App
|
||||
Case Protocol.Protocols.ICA
|
||||
newProtocol = New Protocol.ICA
|
||||
Case Protocol.Protocols.IntApp
|
||||
newProtocol = New Protocol.IntApp
|
||||
newProtocol = New Protocol.IntegratedProgram
|
||||
|
||||
If newConnectionInfo.ExtApp = "" Then
|
||||
Throw New Exception(My.Language.strNoExtAppDefined)
|
||||
@@ -1908,18 +1908,18 @@ Namespace App
|
||||
|
||||
#Region "External Apps"
|
||||
Public Shared Sub GetExtApps()
|
||||
Array.Clear(Tools.ExternalAppsTypeConverter.ExternalApps, 0, Tools.ExternalAppsTypeConverter.ExternalApps.Length)
|
||||
Array.Resize(Tools.ExternalAppsTypeConverter.ExternalApps, ExternalTools.Count + 1)
|
||||
Array.Clear(Tools.ExternalToolsTypeConverter.ExternalTools, 0, Tools.ExternalToolsTypeConverter.ExternalTools.Length)
|
||||
Array.Resize(Tools.ExternalToolsTypeConverter.ExternalTools, ExternalTools.Count + 1)
|
||||
|
||||
Dim i As Integer = 0
|
||||
|
||||
For Each extA As Tools.ExternalTool In ExternalTools
|
||||
Tools.ExternalAppsTypeConverter.ExternalApps(i) = extA.DisplayName
|
||||
Tools.ExternalToolsTypeConverter.ExternalTools(i) = extA.DisplayName
|
||||
|
||||
i += 1
|
||||
Next
|
||||
|
||||
Tools.ExternalAppsTypeConverter.ExternalApps(i) = ""
|
||||
Tools.ExternalToolsTypeConverter.ExternalTools(i) = ""
|
||||
End Sub
|
||||
|
||||
Public Shared Function GetExtAppByName(ByVal Name As String) As Tools.ExternalTool
|
||||
|
||||
@@ -230,7 +230,7 @@ Namespace Connection
|
||||
Browsable(True), _
|
||||
LocalizedDisplayName("strPropertyNameExternalTool"), _
|
||||
LocalizedDescription("strPropertyDescriptionExternalTool"), _
|
||||
TypeConverter(GetType(Tools.ExternalAppsTypeConverter))> _
|
||||
TypeConverter(GetType(Tools.ExternalToolsTypeConverter))> _
|
||||
Public Property ExtApp() As String
|
||||
Get
|
||||
If Me._Inherit.ExtApp And Me._Parent IsNot Nothing Then
|
||||
@@ -1012,7 +1012,7 @@ Namespace Connection
|
||||
Browsable(True), _
|
||||
LocalizedDisplayName("strPropertyNameExternalToolBefore"), _
|
||||
LocalizedDescription("strPropertyDescriptionExternalToolBefore"), _
|
||||
TypeConverter(GetType(Tools.ExternalAppsTypeConverter))> _
|
||||
TypeConverter(GetType(Tools.ExternalToolsTypeConverter))> _
|
||||
Public Overridable Property PreExtApp() As String
|
||||
Get
|
||||
If Me._Inherit.PreExtApp And Me._Parent IsNot Nothing Then
|
||||
@@ -1039,7 +1039,7 @@ Namespace Connection
|
||||
Browsable(True), _
|
||||
LocalizedDisplayName("strPropertyNameExternalToolAfter"), _
|
||||
LocalizedDescription("strPropertyDescriptionExternalToolAfter"), _
|
||||
TypeConverter(GetType(Tools.ExternalAppsTypeConverter))> _
|
||||
TypeConverter(GetType(Tools.ExternalToolsTypeConverter))> _
|
||||
Public Overridable Property PostExtApp() As String
|
||||
Get
|
||||
If Me._Inherit.PostExtApp And Me._Parent IsNot Nothing Then
|
||||
@@ -1581,7 +1581,7 @@ Namespace Connection
|
||||
Case Connection.Protocol.Protocols.ICA
|
||||
Return Connection.Protocol.ICA.Defaults.Port
|
||||
Case Connection.Protocol.Protocols.IntApp
|
||||
Return Connection.Protocol.IntApp.Defaults.Port
|
||||
Return Connection.Protocol.IntegratedProgram.Defaults.Port
|
||||
End Select
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage(My.Language.strConnectionSetDefaultPortFailed, ex, Messages.MessageClass.ErrorMsg)
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
Imports mRemoteNG.App.Native
|
||||
Imports System.Threading
|
||||
Imports mRemoteNG.App.Runtime
|
||||
Imports mRemoteNG.Tools
|
||||
|
||||
Namespace Connection
|
||||
Namespace Protocol
|
||||
Public Class IntApp
|
||||
Inherits Connection.Protocol.Base
|
||||
|
||||
#Region "Private Properties"
|
||||
Private IntAppProcessStartInfo As New ProcessStartInfo()
|
||||
Private Arguments As String
|
||||
Private ExtApp As Tools.ExternalTool
|
||||
#End Region
|
||||
|
||||
#Region "Public Properties"
|
||||
Private _IntAppHandle As IntPtr
|
||||
Public Property IntAppHandle() As IntPtr
|
||||
Get
|
||||
Return Me._IntAppHandle
|
||||
End Get
|
||||
Set(ByVal value As IntPtr)
|
||||
Me._IntAppHandle = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private _IntAppProcess As Process
|
||||
Public Property IntAppProcess() As Process
|
||||
Get
|
||||
Return Me._IntAppProcess
|
||||
End Get
|
||||
Set(ByVal value As Process)
|
||||
Me._IntAppProcess = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private _IntAppPath As String
|
||||
Public Property IntAppPath() As String
|
||||
Get
|
||||
Return _IntAppPath
|
||||
End Get
|
||||
Set(ByVal value As String)
|
||||
_IntAppPath = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Public ReadOnly Property Focused() As Boolean
|
||||
Get
|
||||
If GetForegroundWindow() = IntAppHandle Then
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
#End Region
|
||||
|
||||
#Region "Private Events & Handlers"
|
||||
Private Sub ProcessExited(ByVal sender As Object, ByVal e As System.EventArgs)
|
||||
MyBase.Event_Closed(Me)
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
#Region "Public Methods"
|
||||
Public Sub New()
|
||||
|
||||
End Sub
|
||||
|
||||
Public Overrides Function SetProps() As Boolean
|
||||
ExtApp = App.Runtime.GetExtAppByName(InterfaceControl.Info.ExtApp)
|
||||
If InterfaceControl.Info IsNot Nothing Then
|
||||
ExtApp.ConnectionInfo = InterfaceControl.Info
|
||||
End If
|
||||
|
||||
_IntAppPath = ExtApp.ParseText(ExtApp.FileName)
|
||||
Arguments = ExtApp.ParseText(ExtApp.Arguments)
|
||||
|
||||
Return MyBase.SetProps()
|
||||
End Function
|
||||
|
||||
Public Overrides Function Connect() As Boolean
|
||||
Try
|
||||
If ExtApp.TryIntegrate = False Then
|
||||
ExtApp.Start(Me.InterfaceControl.Info)
|
||||
Me.Close()
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
IntAppProcessStartInfo.UseShellExecute = True
|
||||
IntAppProcessStartInfo.FileName = _IntAppPath
|
||||
IntAppProcessStartInfo.Arguments = Arguments
|
||||
|
||||
IntAppProcess = Process.Start(IntAppProcessStartInfo)
|
||||
IntAppProcess.EnableRaisingEvents = True
|
||||
IntAppProcess.WaitForInputIdle()
|
||||
|
||||
AddHandler IntAppProcess.Exited, AddressOf ProcessExited
|
||||
|
||||
Dim TryCount As Integer = 0
|
||||
Do Until IntAppProcess.MainWindowHandle <> IntPtr.Zero And Me.InterfaceControl.Handle <> IntPtr.Zero And Me.IntAppProcess.MainWindowTitle <> "Default IME"
|
||||
If TryCount >= My.Settings.MaxPuttyWaitTime * 2 Then
|
||||
Exit Do
|
||||
End If
|
||||
|
||||
IntAppProcess.Refresh()
|
||||
|
||||
Thread.Sleep(500)
|
||||
|
||||
TryCount += 1
|
||||
Loop
|
||||
|
||||
IntAppHandle = IntAppProcess.MainWindowHandle
|
||||
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, My.Language.strIntAppStuff, True)
|
||||
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, String.Format(My.Language.strIntAppHandle, IntAppHandle.ToString), True)
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, String.Format(My.Language.strIntAppTitle, IntAppProcess.MainWindowTitle), True)
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, String.Format(My.Language.strIntAppParentHandle, Me.InterfaceControl.Parent.Handle.ToString), True)
|
||||
|
||||
SetParent(Me.IntAppHandle, Me.InterfaceControl.Parent.Handle)
|
||||
SetWindowLong(Me.IntAppHandle, 0, WS_VISIBLE)
|
||||
ShowWindow(Me.IntAppHandle, SW_SHOWMAXIMIZED)
|
||||
|
||||
Resize(Me, New EventArgs)
|
||||
|
||||
MyBase.Connect()
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strIntAppConnectionFailed & vbNewLine & ex.Message)
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
|
||||
Public Overrides Sub Focus()
|
||||
Try
|
||||
SetForegroundWindow(IntAppHandle)
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strIntAppFocusFailed & vbNewLine & ex.Message, True)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Public Overrides Sub Resize(ByVal sender As Object, ByVal e As EventArgs)
|
||||
Try
|
||||
If InterfaceControl.Size = Size.Empty Then Return
|
||||
MoveWindow(IntAppHandle, -SystemInformation.FrameBorderSize.Width, -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height), Me.InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width * 2), Me.InterfaceControl.Height + SystemInformation.CaptionHeight + (SystemInformation.FrameBorderSize.Height * 2), True)
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strIntAppResizeFailed & vbNewLine & ex.Message, True)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Public Overrides Sub Close()
|
||||
Try
|
||||
If IntAppProcess.HasExited = False Then
|
||||
IntAppProcess.Kill()
|
||||
End If
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strIntAppKillFailed & vbNewLine & ex.Message, True)
|
||||
End Try
|
||||
|
||||
Try
|
||||
If IntAppProcess.HasExited = False Then
|
||||
IntAppProcess.Dispose()
|
||||
End If
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strIntAppDisposeFailed & vbNewLine & ex.Message, True)
|
||||
End Try
|
||||
|
||||
MyBase.Close()
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
#Region "Public Shared Methods"
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "Enums"
|
||||
Public Enum Defaults
|
||||
Port = 0
|
||||
End Enum
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
End Namespace
|
||||
End Namespace
|
||||
121
mRemoteV1/Connection/Connection.Protocol.IntegratedProgram.vb
Normal file
@@ -0,0 +1,121 @@
|
||||
Imports mRemoteNG.App.Native
|
||||
Imports System.Threading
|
||||
Imports mRemoteNG.App.Runtime
|
||||
Imports mRemoteNG.Tools
|
||||
|
||||
Namespace Connection
|
||||
Namespace Protocol
|
||||
Public Class IntegratedProgram
|
||||
Inherits Base
|
||||
#Region "Public Methods"
|
||||
Public Overrides Function SetProps() As Boolean
|
||||
If InterfaceControl.Info IsNot Nothing Then
|
||||
_externalTool = GetExtAppByName(InterfaceControl.Info.ExtApp)
|
||||
_externalTool.ConnectionInfo = InterfaceControl.Info
|
||||
End If
|
||||
|
||||
Return MyBase.SetProps()
|
||||
End Function
|
||||
|
||||
Public Overrides Function Connect() As Boolean
|
||||
Try
|
||||
If _externalTool.TryIntegrate = False Then
|
||||
_externalTool.Start(InterfaceControl.Info)
|
||||
Close()
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
_process = New Process()
|
||||
|
||||
With _process.StartInfo
|
||||
.UseShellExecute = True
|
||||
.FileName = _externalTool.FileName
|
||||
.Arguments = _externalTool.ParseArguments(_externalTool.Arguments)
|
||||
End With
|
||||
|
||||
_process.EnableRaisingEvents = True
|
||||
AddHandler _process.Exited, AddressOf ProcessExited
|
||||
|
||||
_process.Start()
|
||||
_process.WaitForInputIdle(My.Settings.MaxPuttyWaitTime * 1000)
|
||||
|
||||
Dim startTicks As Integer = Environment.TickCount
|
||||
While _handle.ToInt32 = 0 And Environment.TickCount < startTicks + (My.Settings.MaxPuttyWaitTime * 1000)
|
||||
_process.Refresh()
|
||||
If Not _process.MainWindowTitle = "Default IME" Then _handle = _process.MainWindowHandle
|
||||
If _handle.ToInt32 = 0 Then Thread.Sleep(0)
|
||||
End While
|
||||
|
||||
SetParent(_handle, InterfaceControl.Handle)
|
||||
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, My.Language.strIntAppStuff, True)
|
||||
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, String.Format(My.Language.strIntAppHandle, _handle.ToString), True)
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, String.Format(My.Language.strIntAppTitle, _process.MainWindowTitle), True)
|
||||
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, String.Format(My.Language.strIntAppParentHandle, InterfaceControl.Parent.Handle.ToString), True)
|
||||
|
||||
Resize(Me, New EventArgs)
|
||||
|
||||
MyBase.Connect()
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage(My.Language.strIntAppConnectionFailed, ex)
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Overrides Sub Focus()
|
||||
Try
|
||||
If ConnectionWindow.InTabDrag Then Return
|
||||
SetForegroundWindow(_handle)
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage(My.Language.strIntAppFocusFailed, ex, , True)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Public Overrides Sub Resize(ByVal sender As Object, ByVal e As EventArgs)
|
||||
Try
|
||||
If InterfaceControl.Size = Size.Empty Then Return
|
||||
MoveWindow(_handle, -SystemInformation.FrameBorderSize.Width, -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height), InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width * 2), InterfaceControl.Height + SystemInformation.CaptionHeight + (SystemInformation.FrameBorderSize.Height * 2), True)
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage(My.Language.strIntAppResizeFailed, ex, , True)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Public Overrides Sub Close()
|
||||
Try
|
||||
If Not _process.HasExited Then _process.Kill()
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage(My.Language.strIntAppKillFailed, ex, , True)
|
||||
End Try
|
||||
|
||||
Try
|
||||
If Not _process.HasExited Then _process.Dispose()
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage(My.Language.strIntAppDisposeFailed, ex, , True)
|
||||
End Try
|
||||
|
||||
MyBase.Close()
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
#Region "Private Fields"
|
||||
Private _externalTool As ExternalTool
|
||||
Private _handle As IntPtr
|
||||
Private _process As Process
|
||||
#End Region
|
||||
|
||||
#Region "Private Methods"
|
||||
Private Sub ProcessExited(ByVal sender As Object, ByVal e As EventArgs)
|
||||
Event_Closed(Me)
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
#Region "Enumerations"
|
||||
Public Enum Defaults
|
||||
Port = 0
|
||||
End Enum
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
End Namespace
|
||||
@@ -1,113 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" >
|
||||
<head>
|
||||
<title>External Applications</title>
|
||||
<link href="Main.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
<span class="heading1">Introduction to External Applications</span></p>
|
||||
<p>
|
||||
External applications can help you get things done that can't be done in
|
||||
mRemote.<br />
|
||||
You can for example start a CMD Console or launch your favorite FTP tool from
|
||||
within mRemote.<br />
|
||||
This wouldn't make much sense by itself because you can already launch your
|
||||
applications by using the Windows Start Menu, Quick Launch or whatever you
|
||||
prefer to use
|
||||
to start your apps.</p>
|
||||
<p>
|
||||
But there's more!</p>
|
||||
<p>
|
||||
In mRemote you can launch applications and tell them what to do with the use of
|
||||
arguments (parameters) and variables of the currently selected Connection.<br />
|
||||
You can for example select your home router's SSH Connection entry and do a
|
||||
traceroute (tracert) on that host.</p>
|
||||
<p>
|
||||
This is much more comfortable and powerful than opening the console and typing
|
||||
tracert YourHost.</p>
|
||||
<p class="heading4">
|
||||
Notes:</p>
|
||||
<ul>
|
||||
<li>Throught this document I will refer to External Applications as Ext. apps or
|
||||
Ext. app.</li>
|
||||
<li>Ext. apps are stored in c:\documents and settings\username\local
|
||||
settings\application data\Felix_Deimel\mRemote\extApps.xml</li>
|
||||
</ul>
|
||||
<p>
|
||||
<span class="heading1">Variables</span></p>
|
||||
<p>
|
||||
Variables and arguments can be used to tell the ext. app what to do.<br />
|
||||
Here's a list of variables currently supported by mRemote:</p>
|
||||
<ul>
|
||||
<li>%Name%</li>
|
||||
<li>%Hostname%</li>
|
||||
<li>%Port%</li>
|
||||
<li>%Username%</li>
|
||||
<li>%Password%</li>
|
||||
<li>%Domain%</li>
|
||||
<li>%Description%</li>
|
||||
<li>%MacAddress%</li>
|
||||
<li>%UserField%</li>
|
||||
</ul>
|
||||
<p>
|
||||
The variables always refer to the currently selected Connection.</p>
|
||||
<p>
|
||||
<span class="heading1">Example</span></p>
|
||||
<p>
|
||||
First of all start the Ext. Apps management interface. To do this click Tools in the main menu and
|
||||
select External Applications.<br />
|
||||
You will see a screen like on the following screenshot.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/01.png" /></p>
|
||||
<p>
|
||||
The fields below the list are greyed out because you haven't created a Ext. App
|
||||
entry yet.<br />
|
||||
To create one right click the blank area in the list and select Add like in the
|
||||
screenshot below.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/02.png" /></p>
|
||||
<p>
|
||||
This is what you'll get:</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/03.png" /></p>
|
||||
<p>
|
||||
So the three fields are now available and need to be filled.<br />
|
||||
The Display Name is simply the name you will see when you want to launch that
|
||||
application, so give it a descriptive name.<br />
|
||||
I named mine Traceroute as I will create a Ext. App launcher that will do a
|
||||
tracert command in the console.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/04.png" /></p>
|
||||
<p>
|
||||
Ok, the next thing we'll need is a filename. This is the application that we
|
||||
want to be executed.<br />
|
||||
I simply type in cmd for a windows cmd console.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/05.png" /></p>
|
||||
<p>
|
||||
Now the fun part comes in - the arguments.<br />
|
||||
The windows cmd has a command line argument that tells the console to launch the
|
||||
command followed by that argument and stay open.<br />
|
||||
It's /K. (There's also /C, this is useful when you want the console to close
|
||||
after the command was executed)<br />
|
||||
In this case I'll use /K as I want to scan through the result when the command
|
||||
completes.<br />
|
||||
After that I just type tracert %HostName%. This tells the console to do a
|
||||
traceroute on the hostname of the currently selected Connection.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/06.png" /></p>
|
||||
<p>
|
||||
Alright! That's all we'll need.<br />
|
||||
Now right click one of you connections, click Tools, External Applications
|
||||
and select Traceroute.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/07.png" /></p>
|
||||
<p>
|
||||
Voil<69>! A console window will popup and execute your tracert command.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External%20Apps/08.png" /></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
245
mRemoteV1/Help/ExternalTools.htm
Normal file
@@ -0,0 +1,245 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" >
|
||||
<head>
|
||||
<title>External Tools</title>
|
||||
<link href="Main.css" rel="stylesheet" type="text/css" />
|
||||
<style type="text/css">
|
||||
.style1
|
||||
{
|
||||
white-space: nowrap;
|
||||
font-family: 'Courier New', monospace;
|
||||
height: 25px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
<span class="heading1">Introduction to External Tools</span></p>
|
||||
<p>
|
||||
External Tools can help you get things done that can't be done in
|
||||
mRemoteNG.<br />
|
||||
You can for example start a command prompt or launch your favorite FTP tool from
|
||||
within mRemoteNG.<br />
|
||||
This wouldn't make much sense by itself because you can already launch your
|
||||
applications by using the Windows Start Menu, Quick Launch or whatever you
|
||||
prefer to use
|
||||
to start your apps.</p>
|
||||
<p>
|
||||
But there's more!</p>
|
||||
<p>
|
||||
In mRemoteNG, you can launch applications and tell them what to do with the use of
|
||||
arguments (parameters) and variables of the currently selected Connection.
|
||||
You can, for example, select your home router's SSH Connection entry and do a
|
||||
traceroute (tracert) on that host.
|
||||
This is much quicker and more powerful than opening the console and typing
|
||||
"tracert yourhost".</p>
|
||||
<p>
|
||||
The external tools configuration is stored in %APPDATA%\mRemoteNG\extApps.xml</p>
|
||||
|
||||
<p>
|
||||
<span class="heading1">Variables</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Variables and arguments can be used to tell the external tool what to do.</p>
|
||||
<p>
|
||||
This is the list of variables supported by mRemoteNG:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>%NAME%</li>
|
||||
<li>%HOSTNAME%</li>
|
||||
<li>%PORT%</li>
|
||||
<li>%USERNAME%</li>
|
||||
<li>%PASSWORD%</li>
|
||||
<li>%DOMAIN%</li>
|
||||
<li>%DESCRIPTION%</li>
|
||||
<li>%MACADDRESS%</li>
|
||||
<li>%USERFIELD%</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Variables always refer to the currently selected connection. Variable names are case-insensitive.
|
||||
Variables can be used in both the Filename and Arguments fields.</p>
|
||||
|
||||
<p>
|
||||
mRemoteNG will also expand environment variables such as %PATH% and
|
||||
%USERPROFILE%.
|
||||
If you need to use an environment variable with the same name as an mRemoteNG
|
||||
variable, use \% instead of %. The most common use of this is for the USERNAME
|
||||
environment variable. %USERNAME% will be expanded to the username set in the
|
||||
currently selected connection. \%USERNAME\% will be expanded to the value set in
|
||||
the USERNAME environment variable.</p>
|
||||
|
||||
<p>If you need to send a variable name to a program without mRemoteNG expanding it,
|
||||
use ^% instead of %. mRemoteNG will remove the caret (^) and leave the rest
|
||||
unchanged. For example, ^%USERNAME^% will be sent to the program as %USERNAME%
|
||||
and will not be expanded.</p>
|
||||
|
||||
<p>
|
||||
<span class="heading1">Special Character Escaping</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Expanded variables will be escaped using the rules below. There are two levels
|
||||
of escaping that are done. The first is escaping for standard argument splitting
|
||||
(C/C++ argv, CommandLineToArgvW, etc). The second is escaping shell
|
||||
metacharacters for ShellExecute.</p>
|
||||
<p>
|
||||
<span class="heading2">Argument splitting escaping:</span></p>
|
||||
|
||||
<ul>
|
||||
<li>Each quotation mark will be escaped by a backslash.</li>
|
||||
<li>One or more backslashes (\) followed by a quotation mark ("):
|
||||
<ul>
|
||||
<li>Each backslash will be escaped by another backslash.</li>
|
||||
<li>The quotation mark will be escaped by a backslash.</li>
|
||||
If the connection's user field contains
|
||||
"This" is a \"test\".<br/>
|
||||
Then %USERFIELD% is replaced with
|
||||
\"This\" is a \\\"test\\\".
|
||||
</ul>
|
||||
</li>
|
||||
<li>A variable name followed by a quotation mark (for example, %USERFIELD%") with
|
||||
a value ending in one or more backslashes:
|
||||
<ul>
|
||||
<li>Each backslash will be escaped by another backslash.</li>
|
||||
<li>Example:</li>
|
||||
If the connection's user field contains c:\Example\<br/>
|
||||
Then "%USERFIELD%" is replaced with "c:\Example\\"
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
To disable
|
||||
argument splitting escaping for a variable, precede its name with a minus (-)
|
||||
sign. For example, %-USERFIELD%.</p>
|
||||
<p>
|
||||
<span class="heading2">Shell metacharacter escaping:</span></p>
|
||||
|
||||
<ul>
|
||||
<li>The shell metacharacters are ( ) % ! ^ " < > & |</li>
|
||||
<li>Each shell metacharacter will be escaped by a caret (^).</li>
|
||||
</ul>
|
||||
<p>
|
||||
To disable both argument splitting and shell metacharacter escaping for a
|
||||
variable, precede its name with an exclamation point (!). For example,
|
||||
%!USERFIELD%. This is not recommended and may cause unexpected results.</p>
|
||||
<p>
|
||||
Only variables that have been expanded will be escaped. It is up to you to
|
||||
escape the rest of the arguments.</p>
|
||||
|
||||
<p>
|
||||
<span class="heading1">Variable Examples</span></p>
|
||||
|
||||
<table>
|
||||
<tr><th>Arguments</th><th>User Field</th><th>Result</th></tr>
|
||||
<tr>
|
||||
<td class='monospace'>%USERFIELD%</td><td class='monospace'>"Example" Text</td><td class='monospace'>
|
||||
\^"Example\^" Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>%-USERFIELD%</td><td class='monospace'>"Example" Text</td><td class='monospace'>
|
||||
^"Example^" Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>%!USERFIELD%</td><td class='monospace'>"Example" Text</td><td class='monospace'>
|
||||
"Example" Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='style1'>^%USERFIELD^%</td><td class='style1'>"Example" Text</td>
|
||||
<td class='style1'>%USERFIELD%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>^^%USERFIELD^^%</td><td class='monospace'>"Example" Text</td><td class='monospace'>
|
||||
^%USERFIELD^%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>-d "%USERFIELD%"</td><td class='monospace'>c:\Example\</td><td class='monospace'>-d "c:\Example\\"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>-d "%-USERFIELD%"</td><td class='monospace'>c:\Example\</td><td class='monospace'>-d "c:\Example\"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>-d "%USERFIELD%"</td><td class='monospace'>Left
|
||||
& Right</td><td class='monospace'>-d "Left ^& Right"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>-d "%!USERFIELD%"</td><td class='monospace'>Left
|
||||
& Right</td><td class='monospace'>-d "Left & Right"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>%WINDIR%</td><td>N/A</td><td class='monospace'>c:\Windows\</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>\%WINDIR\%</td><td>N/A</td><td class='monospace'>c:\Windows\</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>\^%WINDIR\^%</td><td>N/A</td><td class='monospace'>
|
||||
\%WINDIR\%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='monospace'>\\%WINDIR\\%</td><td>N/A</td><td class='monospace'>\\%WINDIR\\%</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<span class="heading1">Example</span></p>
|
||||
<p>
|
||||
First of all, start the external tools editor. To do this, click Tools in the main menu and
|
||||
select External Tools.<br />
|
||||
You will see a screen like on the following screenshot.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/01.png" /></p>
|
||||
<p>
|
||||
The fields below the list are greyed out because you haven't created an external tool
|
||||
entry yet.<br />
|
||||
To create one, right click the blank area in the list and select Add, as in the
|
||||
screenshot below.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/02.png" /></p>
|
||||
<p>
|
||||
This is what you'll get:</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/03.png" /></p>
|
||||
<p>
|
||||
So the three fields are now available and need to be filled.<br />
|
||||
The Display Name is simply the name you will see when you want to launch that
|
||||
tool, so give it a descriptive name.<br />
|
||||
I named mine Traceroute as I will create a external tool that will start the
|
||||
tracert command in the console.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/04.png" /></p>
|
||||
<p>
|
||||
Ok, the next thing we'll need is a filename. This is the program that we
|
||||
want to be executed.<br />
|
||||
I simply type in cmd for a Windows cmd console.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/05.png" /></p>
|
||||
<p>
|
||||
Now the fun part comes in—the arguments.<br />
|
||||
The Windows cmd has a command line argument that tells the console to launch the
|
||||
command followed by that argument and stay open.<br />
|
||||
It's /K. (There's also /C, this is useful when you want the console to close
|
||||
after the command was executed)<br />
|
||||
In this case, I'll use /K as I want to look through the result when the command
|
||||
completes.<br />
|
||||
After that, I just type tracert %HostName%. This tells the console to do a
|
||||
traceroute on the hostname of the currently selected Connection.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/06.png" /></p>
|
||||
<p>
|
||||
Alright! That's all we'll need.<br />
|
||||
Now right click one of you connections, click Tools, External Tools
|
||||
and select Traceroute.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/07.png" /></p>
|
||||
<p>
|
||||
Voil<69>! A console window will popup and execute your tracert command.</p>
|
||||
<p>
|
||||
<img alt="" src="Screenshots/External Tools/08.png" /></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -30,7 +30,7 @@
|
||||
<li><a href="SSHFileTransfer.htm">SSH File Transfer</a></li>
|
||||
<li><a href="QuickConnect.htm">Quick Connect</a></li>
|
||||
<li><a href="ImportFromAD.htm">Import from Active Directory</a></li>
|
||||
<li><a href="ExternalApps.htm">External Applications</a></li>
|
||||
<li><a href="ExternalTools.htm">External Tools</a></li>
|
||||
<li><a href="PortScan.htm">Port Scan</a></li>
|
||||
</ul>
|
||||
<p><a href="QuickReference.htm">Quick Reference</a></p>
|
||||
|
||||
@@ -107,6 +107,25 @@ a:hover
|
||||
|
||||
|
||||
|
||||
/* TABLES */
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
th,td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: lightgrey;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
/* MISC STYLES */
|
||||
|
||||
@@ -117,4 +136,13 @@ a:hover
|
||||
color: #000000;
|
||||
font-family: 'Courier New' , Monospace;
|
||||
background-color: #C1C1C1;
|
||||
}
|
||||
}
|
||||
|
||||
.monospace {
|
||||
white-space: nowrap;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.nowrap {
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -52,17 +52,19 @@ Namespace Tools
|
||||
Return Regex.Replace(argument, "(\\*)""", "$1$1\""")
|
||||
End Function
|
||||
|
||||
Public Shared Function QuoteArgument(ByVal argument As String, Optional ByVal forceQuotes As Boolean = False) As String
|
||||
If Not forceQuotes And Not String.IsNullOrEmpty(argument) And Not argument.Contains(" ") Then Return argument
|
||||
Public Shared Function EscapeBackslashesForTrailingQuote(ByVal argument As String) As String
|
||||
If String.IsNullOrEmpty(argument) Then Return argument
|
||||
|
||||
' Sequence of backslashes followed by the end of the string
|
||||
' (which will become a double quote):
|
||||
' double up all the backslashes
|
||||
If Not String.IsNullOrEmpty(argument) Then
|
||||
argument = Regex.Replace(argument, "(\\*)$", "$1$1")
|
||||
End If
|
||||
Return Regex.Replace(argument, "(\\*)$", "$1$1")
|
||||
End Function
|
||||
|
||||
Return """" & argument & """"
|
||||
Public Shared Function QuoteArgument(ByVal argument As String, Optional ByVal forceQuotes As Boolean = False) As String
|
||||
If Not forceQuotes And Not String.IsNullOrEmpty(argument) And Not argument.Contains(" ") Then Return argument
|
||||
|
||||
Return """" & EscapeBackslashesForTrailingQuote(argument) & """"
|
||||
End Function
|
||||
|
||||
Public Shared Function EscapeShellMetacharacters(ByVal argument As String) As String
|
||||
|
||||
297
mRemoteV1/Tools/ExternalTool.vb
Normal file
@@ -0,0 +1,297 @@
|
||||
Imports mRemoteNG.App.Runtime
|
||||
Imports System.IO
|
||||
Imports System.ComponentModel
|
||||
|
||||
Namespace Tools
|
||||
Public Class ExternalTool
|
||||
#Region "Public Properties"
|
||||
Public Property DisplayName() As String
|
||||
Public Property FileName() As String
|
||||
Public Property WaitForExit() As Boolean
|
||||
Public Property Arguments() As String
|
||||
Public Property TryIntegrate() As Boolean
|
||||
Public Property ConnectionInfo() As Connection.Info
|
||||
|
||||
Public ReadOnly Property Icon() As Icon
|
||||
Get
|
||||
If File.Exists(FileName) Then
|
||||
Return Misc.GetIconFromFile(FileName)
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public ReadOnly Property Image() As Image
|
||||
Get
|
||||
If Icon IsNot Nothing Then
|
||||
Return Icon.ToBitmap
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
#End Region
|
||||
|
||||
#Region "Constructors"
|
||||
Public Sub New(Optional ByVal displayName As String = "", Optional ByVal fileName As String = "", Optional ByVal arguments As String = "")
|
||||
Me.DisplayName = displayName
|
||||
Me.FileName = fileName
|
||||
Me.Arguments = arguments
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
#Region "Public Methods"
|
||||
' Start external app
|
||||
Public Sub Start(Optional ByVal startConnectionInfo As Connection.Info = Nothing)
|
||||
Try
|
||||
If String.IsNullOrEmpty(_FileName) Then Throw New InvalidOperationException("FileName cannot be blank.")
|
||||
|
||||
If TryIntegrate Then
|
||||
StartIntegrated(startConnectionInfo)
|
||||
Return
|
||||
End If
|
||||
|
||||
ConnectionInfo = startConnectionInfo
|
||||
|
||||
Dim process As New Process()
|
||||
With process.StartInfo
|
||||
.UseShellExecute = True
|
||||
.FileName = FileName
|
||||
.Arguments = ParseArguments(Arguments)
|
||||
End With
|
||||
|
||||
process.Start()
|
||||
|
||||
If WaitForExit Then process.WaitForExit()
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage("ExternalApp.Start() failed.", ex)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
' Start external app integrated
|
||||
Public Sub StartIntegrated(Optional ByVal startConnectionInfo As Connection.Info = Nothing)
|
||||
Try
|
||||
ConnectionInfo = startConnectionInfo
|
||||
|
||||
Dim newConnectionInfo As New Connection.Info
|
||||
|
||||
newConnectionInfo.Protocol = Connection.Protocol.Protocols.IntApp
|
||||
newConnectionInfo.ExtApp = DisplayName
|
||||
newConnectionInfo.Name = DisplayName
|
||||
newConnectionInfo.Panel = "Int. Apps"
|
||||
newConnectionInfo.Hostname = ConnectionInfo.Hostname
|
||||
newConnectionInfo.Port = ConnectionInfo.Port
|
||||
newConnectionInfo.Username = ConnectionInfo.Username
|
||||
newConnectionInfo.Password = ConnectionInfo.Password
|
||||
newConnectionInfo.Domain = ConnectionInfo.Domain
|
||||
newConnectionInfo.Description = ConnectionInfo.Description
|
||||
newConnectionInfo.MacAddress = ConnectionInfo.MacAddress
|
||||
newConnectionInfo.UserField = ConnectionInfo.UserField
|
||||
newConnectionInfo.Description = ConnectionInfo.Description
|
||||
newConnectionInfo.PreExtApp = ConnectionInfo.PreExtApp
|
||||
newConnectionInfo.PostExtApp = ConnectionInfo.PostExtApp
|
||||
|
||||
OpenConnection(newConnectionInfo)
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddExceptionMessage("ExternalApp.StartIntegrated() failed.", ex, , True)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Private Enum EscapeType
|
||||
All
|
||||
ShellMetacharacters
|
||||
None
|
||||
End Enum
|
||||
|
||||
Private Structure Replacement
|
||||
Public Sub New(ByVal start As Integer, ByVal length As Integer, ByVal value As String)
|
||||
Me.Start = start
|
||||
Me.Length = length
|
||||
Me.Value = value
|
||||
End Sub
|
||||
|
||||
Public Property Start As Integer
|
||||
Public Property Length As Integer
|
||||
Public Property Value As String
|
||||
End Structure
|
||||
|
||||
Public Function ParseArguments(ByVal input As String) As String
|
||||
Dim index As Integer = 0
|
||||
Dim replacements As New List(Of Replacement)
|
||||
|
||||
Do
|
||||
Dim tokenStart As Integer = input.IndexOf("%", index, StringComparison.InvariantCulture)
|
||||
If tokenStart = -1 Then Exit Do
|
||||
|
||||
Dim tokenEnd As Integer = input.IndexOf("%", tokenStart + 1, StringComparison.InvariantCulture)
|
||||
If tokenEnd = -1 Then Exit Do
|
||||
|
||||
Dim tokenLength As Integer = tokenEnd - tokenStart + 1
|
||||
|
||||
Dim variableNameStart As Integer = tokenStart + 1
|
||||
Dim variableNameLength As Integer = tokenLength - 2
|
||||
|
||||
Dim isEnvironmentVariable As Boolean = False
|
||||
|
||||
Dim variableName As String
|
||||
|
||||
If tokenStart > 0 Then
|
||||
Dim tokenStartPrefix As Char = input.Substring(tokenStart - 1, 1)
|
||||
Dim tokenEndPrefix As Char = input.Substring(tokenEnd - 1, 1)
|
||||
|
||||
If tokenStartPrefix = "\" And tokenEndPrefix = "\" Then
|
||||
isEnvironmentVariable = True
|
||||
|
||||
' Add the first backslash to the token
|
||||
tokenStart = tokenStart - 1
|
||||
tokenLength = tokenLength + 1
|
||||
|
||||
' Remove the last backslash from the name
|
||||
variableNameLength = variableNameLength - 1
|
||||
ElseIf tokenStartPrefix = "^" And tokenEndPrefix = "^" Then
|
||||
' Add the first caret to the token
|
||||
tokenStart = tokenStart - 1
|
||||
tokenLength = tokenLength + 1
|
||||
|
||||
' Remove the last caret from the name
|
||||
variableNameLength = variableNameLength - 1
|
||||
|
||||
variableName = input.Substring(variableNameStart, variableNameLength)
|
||||
replacements.Add(New Replacement(tokenStart, tokenLength, String.Format("%{0}%", variableName)))
|
||||
|
||||
index = tokenEnd
|
||||
Continue Do
|
||||
End If
|
||||
End If
|
||||
|
||||
Dim token As String = input.Substring(tokenStart, tokenLength)
|
||||
|
||||
Dim escape As EscapeType = EscapeType.All
|
||||
Dim prefix As String = input.Substring(variableNameStart, 1)
|
||||
Select Case prefix
|
||||
Case "-"
|
||||
escape = EscapeType.ShellMetacharacters
|
||||
Case "!"
|
||||
escape = EscapeType.None
|
||||
End Select
|
||||
|
||||
If Not escape = EscapeType.All Then
|
||||
' Remove the escape character from the name
|
||||
variableNameStart = variableNameStart + 1
|
||||
variableNameLength = variableNameLength - 1
|
||||
End If
|
||||
|
||||
If variableNameLength = 0 Then
|
||||
index = tokenEnd
|
||||
Continue Do
|
||||
End If
|
||||
|
||||
variableName = input.Substring(variableNameStart, variableNameLength)
|
||||
|
||||
Dim replacementValue As String = token
|
||||
If Not isEnvironmentVariable Then
|
||||
replacementValue = GetVariableReplacement(variableName, token)
|
||||
End If
|
||||
|
||||
Dim haveReplacement As Boolean = False
|
||||
|
||||
If Not replacementValue = token Then
|
||||
haveReplacement = True
|
||||
Else
|
||||
replacementValue = Environment.GetEnvironmentVariable(variableName)
|
||||
If replacementValue IsNot Nothing Then haveReplacement = True
|
||||
End If
|
||||
|
||||
If haveReplacement Then
|
||||
Dim trailing As Char
|
||||
If tokenEnd + 2 <= input.Length Then
|
||||
trailing = input.Substring(tokenEnd + 1, 1)
|
||||
Else
|
||||
trailing = String.Empty
|
||||
End If
|
||||
|
||||
If escape = EscapeType.All Then
|
||||
replacementValue = CommandLineArguments.EscapeBackslashes(replacementValue)
|
||||
If trailing = """" Then
|
||||
replacementValue = CommandLineArguments.EscapeBackslashesForTrailingQuote(replacementValue)
|
||||
End If
|
||||
End If
|
||||
|
||||
If escape = EscapeType.All Or escape = EscapeType.ShellMetacharacters Then
|
||||
replacementValue = CommandLineArguments.EscapeShellMetacharacters(replacementValue)
|
||||
End If
|
||||
|
||||
replacements.Add(New Replacement(tokenStart, tokenLength, replacementValue))
|
||||
index = tokenEnd + 1
|
||||
Else
|
||||
index = tokenEnd
|
||||
End If
|
||||
Loop
|
||||
|
||||
Dim result As String = input
|
||||
|
||||
For index = result.Length To 0 Step -1
|
||||
For Each replacement As Replacement In replacements
|
||||
If Not replacement.Start = index Then Continue For
|
||||
|
||||
Dim before As String = result.Substring(0, replacement.Start)
|
||||
Dim after As String = result.Substring(replacement.Start + replacement.Length)
|
||||
result = before & replacement.Value & after
|
||||
Next
|
||||
Next
|
||||
|
||||
Return result
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
#Region "Private Methods"
|
||||
Private Function GetVariableReplacement(ByVal variable As String, ByVal original As String) As String
|
||||
Dim replacement As String
|
||||
Select Case variable.ToLowerInvariant()
|
||||
Case "name"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.Name
|
||||
Case "hostname"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.Hostname
|
||||
Case "port"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.Port
|
||||
Case "username"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.Username
|
||||
Case "password"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.Password
|
||||
Case "domain"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.Domain
|
||||
Case "description"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.Description
|
||||
' ReSharper disable once StringLiteralTypo
|
||||
Case "macaddress"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.MacAddress
|
||||
' ReSharper disable once StringLiteralTypo
|
||||
Case "userfield"
|
||||
If ConnectionInfo Is Nothing Then replacement = "" Else replacement = ConnectionInfo.UserField
|
||||
Case Else
|
||||
Return original
|
||||
End Select
|
||||
Return replacement
|
||||
End Function
|
||||
#End Region
|
||||
End Class
|
||||
|
||||
Public Class ExternalToolsTypeConverter
|
||||
Inherits StringConverter
|
||||
|
||||
Public Shared ExternalTools As String() = New String() {}
|
||||
|
||||
Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection
|
||||
Return New StandardValuesCollection(ExternalTools)
|
||||
End Function
|
||||
|
||||
Public Overloads Overrides Function GetStandardValuesExclusive(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As ITypeDescriptorContext) As Boolean
|
||||
Return True
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -1,220 +0,0 @@
|
||||
Imports mRemoteNG.App.Runtime
|
||||
Imports System.IO
|
||||
Imports System.ComponentModel
|
||||
|
||||
Namespace Tools
|
||||
Public Class ExternalTool
|
||||
#Region "Properties"
|
||||
Private _DisplayName As String
|
||||
Public Property DisplayName() As String
|
||||
Get
|
||||
Return _DisplayName
|
||||
End Get
|
||||
Set(ByVal value As String)
|
||||
_DisplayName = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private _FileName As String
|
||||
Public Property FileName() As String
|
||||
Get
|
||||
Return _FileName
|
||||
End Get
|
||||
Set(ByVal value As String)
|
||||
_FileName = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private _WaitForExit As Boolean
|
||||
Public Property WaitForExit() As Boolean
|
||||
Get
|
||||
Return _WaitForExit
|
||||
End Get
|
||||
Set(ByVal value As Boolean)
|
||||
_WaitForExit = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private _Arguments As String
|
||||
Public Property Arguments() As String
|
||||
Get
|
||||
Return _Arguments
|
||||
End Get
|
||||
Set(ByVal value As String)
|
||||
_Arguments = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private _TryIntegrate As Boolean
|
||||
Public Property TryIntegrate() As Boolean
|
||||
Get
|
||||
Return _TryIntegrate
|
||||
End Get
|
||||
Set(ByVal value As Boolean)
|
||||
_TryIntegrate = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
|
||||
|
||||
Private _ConnectionInfo As Connection.Info
|
||||
Public Property ConnectionInfo() As Connection.Info
|
||||
Get
|
||||
Return _ConnectionInfo
|
||||
End Get
|
||||
Set(ByVal value As Connection.Info)
|
||||
_ConnectionInfo = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Public ReadOnly Property Icon() As Icon
|
||||
Get
|
||||
If File.Exists(Me._FileName) Then
|
||||
Return Tools.Misc.GetIconFromFile(Me._FileName)
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public ReadOnly Property Image() As Image
|
||||
Get
|
||||
Dim iC As Icon = Me.Icon
|
||||
If iC IsNot Nothing Then
|
||||
Return iC.ToBitmap
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
#End Region
|
||||
|
||||
Public Sub New()
|
||||
Me.New("")
|
||||
End Sub
|
||||
|
||||
Public Sub New(ByVal DisplayName As String)
|
||||
Me.New(DisplayName, "", "")
|
||||
End Sub
|
||||
|
||||
Public Sub New(ByVal DisplayName As String, ByVal Filename As String, ByVal Arguments As String)
|
||||
_DisplayName = DisplayName
|
||||
_FileName = Filename
|
||||
_Arguments = Arguments
|
||||
End Sub
|
||||
|
||||
' Start external app
|
||||
Public Function Start(Optional ByVal ConnectionInfo As Connection.Info = Nothing) As Process
|
||||
Try
|
||||
If _FileName = "" Then
|
||||
Throw New Exception("No Filename specified!")
|
||||
End If
|
||||
|
||||
If _TryIntegrate = True Then
|
||||
StartIntApp(ConnectionInfo)
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
_ConnectionInfo = ConnectionInfo
|
||||
|
||||
Dim process As New Process()
|
||||
With process.StartInfo
|
||||
.UseShellExecute = True
|
||||
.FileName = ParseText(_FileName)
|
||||
|
||||
.Arguments = ParseText(_Arguments)
|
||||
End With
|
||||
|
||||
process.Start()
|
||||
|
||||
If _WaitForExit Then
|
||||
process.WaitForExit()
|
||||
End If
|
||||
|
||||
Return process
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn't start external application." & vbNewLine & ex.Message)
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
|
||||
' Start external app integrated
|
||||
Public Sub StartIntApp(Optional ByVal ConnectionInfo As Connection.Info = Nothing)
|
||||
Try
|
||||
_ConnectionInfo = ConnectionInfo
|
||||
|
||||
Dim nCI As New Connection.Info
|
||||
|
||||
nCI.Protocol = Connection.Protocol.Protocols.IntApp
|
||||
nCI.ExtApp = Me.DisplayName
|
||||
nCI.Name = Me.DisplayName
|
||||
nCI.Panel = "Int. Apps"
|
||||
nCI.Hostname = _ConnectionInfo.Hostname
|
||||
nCI.Port = _ConnectionInfo.Port
|
||||
nCI.Username = _ConnectionInfo.Username
|
||||
nCI.Password = _ConnectionInfo.Password
|
||||
nCI.Domain = _ConnectionInfo.Domain
|
||||
nCI.Description = _ConnectionInfo.Description
|
||||
nCI.MacAddress = _ConnectionInfo.MacAddress
|
||||
nCI.UserField = _ConnectionInfo.UserField
|
||||
nCI.Description = _ConnectionInfo.Description
|
||||
nCI.PreExtApp = _ConnectionInfo.PreExtApp
|
||||
nCI.PostExtApp = _ConnectionInfo.PostExtApp
|
||||
|
||||
OpenConnection(nCI)
|
||||
Catch ex As Exception
|
||||
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Public Function ParseText(ByVal Text As String) As String
|
||||
Dim pText As String = Text
|
||||
|
||||
Try
|
||||
If _ConnectionInfo IsNot Nothing Then
|
||||
pText = Replace(pText, "%Name%", _ConnectionInfo.Name, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%HostName%", _ConnectionInfo.Hostname, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Port%", _ConnectionInfo.Port, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%UserName%", _ConnectionInfo.Username, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Password%", _ConnectionInfo.Password, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Domain%", _ConnectionInfo.Domain, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Description%", _ConnectionInfo.Description, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%MacAddress%", _ConnectionInfo.MacAddress, , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%UserField%", _ConnectionInfo.UserField, , , CompareMethod.Text)
|
||||
Else
|
||||
pText = Replace(pText, "%Name%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%HostName%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Port%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%UserName%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Password%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Domain%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%Description%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%MacAddress%", "", , , CompareMethod.Text)
|
||||
pText = Replace(pText, "%UserField%", "", , , CompareMethod.Text)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
MessageCollector.AddMessage(Messages.MessageClass.WarningMsg, "ParseText failed (Tools.ExternalApp)" & vbNewLine & ex.Message, True)
|
||||
End Try
|
||||
|
||||
Return pText
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Public Class ExternalAppsTypeConverter
|
||||
Inherits StringConverter
|
||||
|
||||
Public Shared ExternalApps As String() = New String() {}
|
||||
|
||||
Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection
|
||||
Return New StandardValuesCollection(ExternalApps)
|
||||
End Function
|
||||
|
||||
Public Overloads Overrides Function GetStandardValuesExclusive(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As ITypeDescriptorContext) As Boolean
|
||||
Return True
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -368,15 +368,16 @@ Namespace Tree
|
||||
SetNodeImageIndex(treeNode, Img)
|
||||
End Sub
|
||||
|
||||
Private Delegate Sub SetNodeImageIndexCB(ByVal tNode As TreeNode, ByVal ImgIndex As Integer)
|
||||
Private Shared Sub SetNodeImageIndex(ByVal tNode As TreeNode, ByVal ImgIndex As Integer)
|
||||
If _TreeView.InvokeRequired Then
|
||||
Dim s As New SetNodeImageIndexCB(AddressOf SetNodeImageIndex)
|
||||
_TreeView.Invoke(s, New Object() {tNode, ImgIndex})
|
||||
Else
|
||||
tNode.ImageIndex = ImgIndex
|
||||
tNode.SelectedImageIndex = ImgIndex
|
||||
Private Delegate Sub SetNodeImageIndexDelegate(ByVal treeNode As TreeNode, ByVal imageIndex As Integer)
|
||||
Private Shared Sub SetNodeImageIndex(ByVal treeNode As TreeNode, ByVal imageIndex As Integer)
|
||||
If treeNode Is Nothing OrElse treeNode.TreeView Is Nothing Then Return
|
||||
If treeNode.TreeView.InvokeRequired Then
|
||||
treeNode.TreeView.Invoke(New SetNodeImageIndexDelegate(AddressOf SetNodeImageIndex), New Object() {treeNode, imageIndex})
|
||||
Return
|
||||
End If
|
||||
|
||||
treeNode.ImageIndex = imageIndex
|
||||
treeNode.SelectedImageIndex = imageIndex
|
||||
End Sub
|
||||
|
||||
Public Shared Sub SetNodeToolTip(ByVal e As MouseEventArgs, ByVal tTip As ToolTip)
|
||||
|
||||
@@ -131,8 +131,8 @@ Namespace UI
|
||||
TreeNode20.Tag = "ImportFromAD"
|
||||
TreeNode20.Text = "Import From Active Directory"
|
||||
TreeNode21.Name = "Node1"
|
||||
TreeNode21.Tag = "ExternalApps"
|
||||
TreeNode21.Text = "External Applications"
|
||||
TreeNode21.Tag = "ExternalTools"
|
||||
TreeNode21.Text = "External Tools"
|
||||
TreeNode22.Name = "Node0"
|
||||
TreeNode22.Tag = "PortScan"
|
||||
TreeNode22.Text = "Port Scan"
|
||||
@@ -218,9 +218,9 @@ Namespace UI
|
||||
#End Region
|
||||
|
||||
#Region "Private Methods"
|
||||
Private Sub Help_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
|
||||
Me.tvIndex.Nodes(0).Expand()
|
||||
Me.tvIndex.SelectedNode = Me.tvIndex.Nodes(0).Nodes(0)
|
||||
Private Sub Help_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
|
||||
tvIndex.Nodes(0).ExpandAll()
|
||||
tvIndex.SelectedNode = tvIndex.Nodes(0).Nodes(0)
|
||||
End Sub
|
||||
|
||||
Private Sub Help_Shown(sender As Object, e As EventArgs) Handles Me.Shown
|
||||
|
||||
@@ -286,7 +286,7 @@
|
||||
<Compile Include="Connection\Connection.Protocol.HTTPBase.vb" />
|
||||
<Compile Include="Connection\Connection.Protocol.HTTPS.vb" />
|
||||
<Compile Include="Connection\Connection.Protocol.ICA.vb" />
|
||||
<Compile Include="Connection\Connection.Protocol.IntApp.vb" />
|
||||
<Compile Include="Connection\Connection.Protocol.IntegratedProgram.vb" />
|
||||
<Compile Include="Connection\Connection.Protocol.List.vb" />
|
||||
<Compile Include="Connection\Connection.Protocol.Protocols.vb" />
|
||||
<Compile Include="Connection\Connection.Protocol.PuttyBase.vb" />
|
||||
@@ -361,7 +361,7 @@
|
||||
</Compile>
|
||||
<Compile Include="Tools\Tools.Controls.vb">
|
||||
</Compile>
|
||||
<Compile Include="Tools\Tools.ExternalApp.vb" />
|
||||
<Compile Include="Tools\ExternalTool.vb" />
|
||||
<Compile Include="Tools\Tools.LocalizedAttributes.vb" />
|
||||
<Compile Include="Tools\Tools.Misc.vb" />
|
||||
<Compile Include="Tools\Tools.PortScan.vb" />
|
||||
@@ -636,7 +636,7 @@
|
||||
<Content Include="Help\PortScan.htm">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\ExternalApps.htm">
|
||||
<Content Include="Help\ExternalTools.htm">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\ErrorsAndInfos.htm">
|
||||
@@ -723,28 +723,28 @@
|
||||
<Content Include="Help\Screenshots\Configuration\17.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\01.png">
|
||||
<Content Include="Help\Screenshots\External Tools\01.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\02.png">
|
||||
<Content Include="Help\Screenshots\External Tools\02.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\03.png">
|
||||
<Content Include="Help\Screenshots\External Tools\03.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\04.png">
|
||||
<Content Include="Help\Screenshots\External Tools\04.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\05.png">
|
||||
<Content Include="Help\Screenshots\External Tools\05.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\06.png">
|
||||
<Content Include="Help\Screenshots\External Tools\06.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\07.png">
|
||||
<Content Include="Help\Screenshots\External Tools\07.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\External Apps\08.png">
|
||||
<Content Include="Help\Screenshots\External Tools\08.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Help\Screenshots\Main Menu\File.png">
|
||||
|
||||