mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Compare commits
98 Commits
v1.75Hotfi
...
v1.75Hotfi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81b0be0489 | ||
|
|
3074a211f8 | ||
|
|
0659b140f5 | ||
|
|
0b8160ae34 | ||
|
|
dbf2b7b4b6 | ||
|
|
1e8afc8ea4 | ||
|
|
70bd2e8a78 | ||
|
|
8045544051 | ||
|
|
0cef4dc9b3 | ||
|
|
f1cfa4330a | ||
|
|
a50b370262 | ||
|
|
064fd217ba | ||
|
|
692b26622c | ||
|
|
72a56d33d0 | ||
|
|
ce4bfc55c1 | ||
|
|
f0faec9def | ||
|
|
e6ef28050c | ||
|
|
547ec3cb3a | ||
|
|
fc0f278962 | ||
|
|
1f3db15892 | ||
|
|
e3e4c49427 | ||
|
|
1520b8bf73 | ||
|
|
c9e7f82905 | ||
|
|
d2357fa779 | ||
|
|
703178ddf1 | ||
|
|
4e9c5de16c | ||
|
|
3d1fcc35df | ||
|
|
e20d7afb72 | ||
|
|
07e2bc3858 | ||
|
|
f3b11d6f72 | ||
|
|
69f310c02c | ||
|
|
3308f1146c | ||
|
|
8e8cf3df8d | ||
|
|
26fdd924ef | ||
|
|
ea3494f6e7 | ||
|
|
9f028d9104 | ||
|
|
f40be696c7 | ||
|
|
95a503a390 | ||
|
|
88c51f4933 | ||
|
|
686005071e | ||
|
|
e16d31d605 | ||
|
|
8b201d22cb | ||
|
|
0f6f8d43bd | ||
|
|
8f171cddd9 | ||
|
|
c77c323f73 | ||
|
|
9e358309e4 | ||
|
|
485438f38d | ||
|
|
fe26a60337 | ||
|
|
d2c2de4dd7 | ||
|
|
d49d58f7f8 | ||
|
|
164d4fff8b | ||
|
|
7726406674 | ||
|
|
ed38b39fec | ||
|
|
9188d4316e | ||
|
|
cf374c6b8b | ||
|
|
82388dcbc3 | ||
|
|
7a6a99e2b6 | ||
|
|
c383736834 | ||
|
|
6e5e78df3b | ||
|
|
311bf1b641 | ||
|
|
5c9933791c | ||
|
|
039d4d11aa | ||
|
|
c0f2d2aa84 | ||
|
|
45099bfa07 | ||
|
|
695ae9d970 | ||
|
|
21eb0064b1 | ||
|
|
513fe402af | ||
|
|
b27e5754e8 | ||
|
|
fa7231d77b | ||
|
|
f5a30ecb33 | ||
|
|
7f22289889 | ||
|
|
f80c39077a | ||
|
|
75c60a1cc4 | ||
|
|
2cf38d6b7c | ||
|
|
482c9c1574 | ||
|
|
882e59a260 | ||
|
|
7a036956b7 | ||
|
|
7520b20cf9 | ||
|
|
d47ccd75d5 | ||
|
|
56ff81a0ed | ||
|
|
8db76f5324 | ||
|
|
a9442ea06e | ||
|
|
92bd0d3ea0 | ||
|
|
512d7322b2 | ||
|
|
45645c439f | ||
|
|
84ebb82cae | ||
|
|
576f6a3bd6 | ||
|
|
96df821eca | ||
|
|
8589778e92 | ||
|
|
a8a7de9ee6 | ||
|
|
1d99340425 | ||
|
|
a8cdfb56f3 | ||
|
|
0958cdaa2d | ||
|
|
ebfb3dd31e | ||
|
|
3943b8753f | ||
|
|
9e26ea1866 | ||
|
|
8152a87514 | ||
|
|
b28775c2c6 |
@@ -1,9 +1,57 @@
|
||||
1.75.7007 (2017-06-14):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#583: SSH (PuTTYNG) Sessions are not properly integrated into the main mRemoteNG window (Sorry!)
|
||||
|
||||
|
||||
1.75.7006 (2017-06-13):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#377: Use all space on About page
|
||||
#527: Additional protections to avoid problems on update check in heavily firewalled environments
|
||||
#530: Fixed issue where using External Tool on existing connection causes creation of 'New Connection' entry
|
||||
#531: Update PuTTYNG to 0.69
|
||||
#546: Quick Connect from notification area icon displays warning when clicking on a folder (see #334)
|
||||
|
||||
|
||||
1.75.7005 (2017-04-27):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#410: Update PuTTYNG to 0.68
|
||||
#434: Fix complier warnings CA1049 & CA2111
|
||||
#442: Fixed issue loading PuTTY sessions that have spaces in the name
|
||||
#502: Problems with ParentID for Duplicated Containers/Connections with SQL Connection Storage
|
||||
#514: Expanded property not saved/loaded properly from SQL
|
||||
#518: Exception when Importing File
|
||||
|
||||
|
||||
General Changes:
|
||||
----------------
|
||||
Minor code cleanup/optimizations/null checks
|
||||
|
||||
|
||||
1.75.7003 (2017-03-24):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#464: Resolved issue when importing a connections file while using SQL server feature
|
||||
|
||||
|
||||
1.75.7002 (2017-03-10):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#448: Resolved issue with SQL saving
|
||||
|
||||
|
||||
1.75.7001 (2017-03-10):
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#408: Update SQL scripts
|
||||
#448: Resolved issue with SQL saving
|
||||
|
||||
|
||||
1.75 hotfix 1 (2017-03-06):
|
||||
|
||||
@@ -99,8 +99,8 @@ Copyright
|
||||
Freely redistributable with attribution
|
||||
http://www.dotnetmagic.com/magic_download.html
|
||||
|
||||
PuTTY 0.67
|
||||
Copyright <20> 1997-2016 Simon Tatham
|
||||
PuTTY 0.68
|
||||
Copyright <20> 1997-2017 Simon Tatham
|
||||
MIT License
|
||||
http://www.chiark.greenend.org.uk/~sgtatham/putty/
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<?define RequiredDotNetFrameworkServicePackLevel = "" ?>
|
||||
<?define RequiredDotNetFrameworkVersion = "$(var.RequiredDotNetFrameworkMajorVersion).$(var.RequiredDotNetFrameworkMinorVersion)" ?>
|
||||
<?define Rdp80Kb = "KB2592687" ?>
|
||||
<?define Rdp81Kb = "KB2923545" ?>
|
||||
<?define Rdp81Kb = "KB2830477" ?>
|
||||
<?define MinimumRdpKb = $(var.Rdp80Kb) ?>
|
||||
<?define RdpDtlsKb = "KB2574819" ?>
|
||||
<?define IGNOREPREREQUISITES = 0 ?>
|
||||
|
||||
@@ -114,22 +114,6 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Portable|x86' ">
|
||||
<DefineConstants>HarvestPath=$(SolutionDir)mRemoteV1\bin\Release Portable;HelpFilesHarvestPath=$(SolutionDir)mRemoteV1\Resources\Help</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>set /p buildenv=<buildenv.tmp
|
||||
|
||||
REM Sign MSI
|
||||
IF EXIST C:\mRemoteNG_code_signing_cert.pfx (
|
||||
IF %25buildenv: Portable=%25==Release (
|
||||
powershell "&""$(SolutionDir)Tools\signfiles.ps1""" %27%25cd%25%27
|
||||
)
|
||||
)
|
||||
|
||||
REM Rename MSI to include version number
|
||||
powershell -ExecutionPolicy Bypass -File "$(SolutionDir)Tools\rename_installer_with_version.ps1" $(SolutionDir)
|
||||
|
||||
REM Copy MSI to Release folder
|
||||
IF %25buildenv: Portable=%25==Release (powershell -ExecutionPolicy Bypass -File "$(SolutionDir)Tools\copy_release_installer.ps1" $(TargetDir) $(SolutionDir)Release)</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>REM Clean the TargetDir
|
||||
rmdir /S /Q "$(TargetDir)"
|
||||
@@ -142,4 +126,19 @@ call "$(WIX)bin\heat.exe" dir "$(SolutionDir)mRemoteV1\bin\$(Configuration)" -ag
|
||||
REM Convert the license file "COPYING.TXT" to "License.rtf" to be shown in the installer GUI
|
||||
call "$(ProjectDir)Resources\Pandoc\pandoc.exe" -s -t rtf -o "$(ProjectDir)\Resources\License.rtf" "$(SolutionDir)COPYING.TXT"</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>:: When passing paths to powershell scripts, check if the path ends with a backslash "\"
|
||||
:: If it does, then the backslash may be interpreted as an escape character. Add another backslash to cancel the first one.
|
||||
|
||||
powershell -noprofile -command "sleep 2"
|
||||
set /p buildenv=<buildenv.tmp
|
||||
set solutionDir=$(SolutionDir)\
|
||||
set targetDir=%25cd%25
|
||||
set psScriptsDir=$(SolutionDir)Tools
|
||||
set certPath=$(CertPath)
|
||||
set certPassword=$(CertPassword)
|
||||
|
||||
:: Call the post build powershell script
|
||||
powershell.exe -ExecutionPolicy Bypass -File "%25psScriptsDir%25\postbuild_installer.ps1" -SolutionDir "%25solutionDir%25" -TargetDir "%25targetDir%25" -TargetFileName "mRemoteNG.exe" -ConfigurationName "%25buildenv%25" -CertificatePath "%25certPath%25" -CertificatePassword "%25certPassword%25"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -6,7 +6,7 @@
|
||||
<String Id="Install_NeedToBeAdminToInstall">You need to be an administrator to install this product.</String>
|
||||
<String Id="Install_NeedDotNetFrameworkVersion">mRemoteNG requires Microsoft .NET Framework [REQUIREDDOTNETFRAMEWORKVERSION] or higher.</String>
|
||||
<String Id="Install_OSVersionRequirement">mRemoteNG requires Windows 7 SP1 or higher to run. Please update your operating system and try again.</String>
|
||||
<String Id="Install_RDP80Requirement">mRemoteNG requires RDP 8.0 or higher to run. Windows 7 users will need to install KB2592687</String>
|
||||
<String Id="Install_RDP80Requirement">mRemoteNG requires RDP 8.0 or higher to run. Windows 7 users will need to install either KB2592687 (RDP 8.0) or KB2830477 (RDP 8.1)</String>
|
||||
<String Id="Install_RDPDtlsRequirement">mRemoteNG requires KB2574819 in order to create RDP connections. Windows 7 users will need to install this KB.</String>
|
||||
<String Id="Install_Win7RequiresSP1">For mRemoteNG to run on Windows 7, it requires Service Pack 1 to be installed. Please install Service Pack 1 and try again.</String>
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<Condition Message="!(loc.Install_RDPDtlsRequirement)">
|
||||
<![CDATA[Installed OR (IGNOREPREREQUISITES = 1) OR (VersionNT >= 602 OR VersionNT64 >= 602) OR ((VersionNT = 601 OR VersionNT64 = 601) AND (RDP_DTLS_UPDATE_INSTALLED = 1))]]>
|
||||
</Condition>
|
||||
<!-- If Win7, require RDP 8.0 update (KB2592687) -->
|
||||
<!-- If Win7, require RDP 8.0 (KB2592687) or 8.1 (KB2830477) update -->
|
||||
<Condition Message="!(loc.Install_RDP80Requirement)">
|
||||
<![CDATA[Installed OR (IGNOREPREREQUISITES = 1) OR (VersionNT >= 602 OR VersionNT64 >= 602) OR ((VersionNT = 601 OR VersionNT64 = 601) AND (MINIMUM_RDP_VERSION_INSTALLED = 1))]]>
|
||||
</Condition>
|
||||
|
||||
63
Jenkinsfile_publish.groovy
Normal file
63
Jenkinsfile_publish.groovy
Normal file
@@ -0,0 +1,63 @@
|
||||
node('windows') {
|
||||
def jobDir = pwd()
|
||||
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\""
|
||||
def vsToolsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools"
|
||||
def vsExtensionsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow"
|
||||
def nunitTestAdapterPath = "C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\VisualStudio\\14.0\\Extensions"
|
||||
|
||||
|
||||
stage ('Clean output dir') {
|
||||
bat script: "rmdir /S /Q \"${jobDir}\\Release\" 2>nul", returnStatus: true
|
||||
}
|
||||
|
||||
stage ('Checkout Branch') {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: [[name: '*/${TargetBranch}']],
|
||||
doGenerateSubmoduleConfigurations: false,
|
||||
extensions: [],
|
||||
submoduleCfg: [],
|
||||
userRemoteConfigs: [[
|
||||
credentialsId: '9c3fbff4-5b90-402f-a298-00e607fcec87',
|
||||
url: 'https://github.com/mRemoteNG/mRemoteNG.git'
|
||||
]]
|
||||
])
|
||||
}
|
||||
|
||||
stage ('Restore NuGet Packages') {
|
||||
def nugetPath = "C:\\nuget.exe"
|
||||
bat "${nugetPath} restore ${solutionFilePath}"
|
||||
}
|
||||
|
||||
withCredentials([file(credentialsId: '9b674d57-6792-48e3-984a-4d1bab2abb64', variable: 'CODE_SIGNING_CERT')]) {
|
||||
withCredentials([usernamePassword(credentialsId: '05b7449b-05c0-490f-8661-236242526e62', passwordVariable: 'MRNG_CERT_PASSWORD', usernameVariable: 'NO_USERNAME')]) {
|
||||
stage ('Build mRemoteNG (Normal - MSI)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /p:Configuration=\"Release Installer\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
|
||||
archiveArtifacts artifacts: "Release\\*.msi", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
|
||||
}
|
||||
|
||||
stage ('Build mRemoteNG (Portable)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /p:Configuration=\"Release Portable\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
|
||||
archiveArtifacts artifacts: "Release\\*.zip", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ('Run Unit Tests (Normal - MSI)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release\\mRemoteNGTests.dll\""
|
||||
}
|
||||
|
||||
stage ('Run Unit Tests (Portable)') {
|
||||
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release Portable\\mRemoteNGTests.dll\""
|
||||
}
|
||||
|
||||
stage ('Publish to GitHub') {
|
||||
withCredentials([string(credentialsId: '5443a369-dbe8-42d3-b4e8-04d0b4e9039a', variable: 'GH_AUTH_TOKEN')]) {
|
||||
def zipPath = "${jobDir}\\Release\\*.zip"
|
||||
def msiPath = "${jobDir}\\Release\\*.msi"
|
||||
// because batch files suck at handling newline characters, we have to convert to base64 in groovy and back to text in powershell
|
||||
def base64Description = env.ReleaseDescription.bytes.encodeBase64().toString()
|
||||
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\publish_to_github.ps1\" -Owner \"mRemoteNG\" -Repository \"mRemoteNG\" -ReleaseTitle \"${env.ReleaseTitle}\" -TagName \"${env.TagName}\" -TargetCommitish \"${env.TargetBranch}\" -Description \"${base64Description}\" -IsDraft ${env.IsDraft} -IsPrerelease ${env.IsPreRelease} -ZipFilePath \"${zipPath}\" -MsiFilePath \"${msiPath}\" -AuthToken \"${env.GH_AUTH_TOKEN}\" -DescriptionIsBase64Encoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
10
README.MD
10
README.MD
@@ -10,8 +10,8 @@
|
||||
|
||||
| Update Channel | Build Status | Downloads |
|
||||
| ---------------|--------------|-----------|
|
||||
| Stable | [](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/master/) | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.74) |
|
||||
| Beta | [](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/beta_channel/) | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75Beta3) |
|
||||
| Stable | [](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/master/) | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75Hotfix7) |
|
||||
| Beta | | [](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75Hotfix7) |
|
||||
| Development | [](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/develop/) | - |
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ Currently these protocols are supported:
|
||||
* VNC (Virtual Network Computing)
|
||||
* ICA (Independent Computing Architecture)
|
||||
* SSH (Secure Shell)
|
||||
* Telnet (TELecommunication NETwork)
|
||||
* HTTP/S (Hypertext Transfer Protocol)
|
||||
* Rlogin (Rlogin)
|
||||
* Telnet (Teletype Network)
|
||||
* HTTP/S (Hypertext Transfer Protocol Secure)
|
||||
* Rlogin (Remote Login)
|
||||
* RAW
|
||||
|
||||
mRemoteNG can be installed on Windows 7 or later.
|
||||
|
||||
15
Tools/copy_puttyng.ps1
Normal file
15
Tools/copy_puttyng.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
Write-Output "Copying PUTTYNG to correct directory"
|
||||
Copy-Item -Path (Join-Path -Path $SolutionDir -ChildPath "mRemoteV1\Resources\PuTTYNG.exe") -Destination $TargetDir -Force
|
||||
|
||||
Write-Output ""
|
||||
@@ -1,16 +1,21 @@
|
||||
$sourcePath = $args[0]
|
||||
$destinationDir = $args[1]
|
||||
param (
|
||||
[string]
|
||||
$SourcePath,
|
||||
|
||||
Write-Host $sourcePath
|
||||
Write-Host $destinationDir
|
||||
[string]
|
||||
$DestinationDir
|
||||
)
|
||||
|
||||
if (!(Test-Path -Path $destinationDir))
|
||||
Write-Host $SourcePath
|
||||
Write-Host $DestinationDir
|
||||
|
||||
if (!(Test-Path -Path $DestinationDir))
|
||||
{
|
||||
New-Item -Path $destinationDir -ItemType "directory"
|
||||
New-Item -Path $DestinationDir -ItemType "directory"
|
||||
}
|
||||
|
||||
$sourceFiles = Get-ChildItem -Path $sourcePath -Recurse | ?{$_.Extension -match "exe|msi"}
|
||||
$sourceFiles = Get-ChildItem -Path $SourcePath -Recurse | ?{$_.Extension -match "exe|msi"}
|
||||
foreach ($item in $sourceFiles)
|
||||
{
|
||||
Copy-Item -Path $item.FullName -Destination $destinationDir -Force
|
||||
Copy-Item -Path $item.FullName -Destination $DestinationDir -Force
|
||||
}
|
||||
23
Tools/move_help_files.ps1
Normal file
23
Tools/move_help_files.ps1
Normal file
@@ -0,0 +1,23 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
$path_HelpFilesDir = Join-Path -Path $TargetDir -ChildPath "Help"
|
||||
|
||||
Write-Output "Moving Help files to correct directory"
|
||||
|
||||
# Remove stale Help files, if they exist
|
||||
if (Test-Path -Path $path_HelpFilesDir) {
|
||||
Remove-Item -Path $path_HelpFilesDir -Recurse -Force
|
||||
}
|
||||
|
||||
# Move Help files
|
||||
Move-Item -Path (Join-Path -Path $TargetDir -ChildPath "Resources\Help") -Destination $path_HelpFilesDir -Force
|
||||
Start-Sleep -Seconds 2
|
||||
Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "Resources") -Recurse -Force
|
||||
|
||||
Write-Output ""
|
||||
43
Tools/postbuild_installer.ps1
Normal file
43
Tools/postbuild_installer.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetFileName,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName,
|
||||
|
||||
[string]
|
||||
$CertificatePath,
|
||||
|
||||
[string]
|
||||
$CertificatePassword,
|
||||
|
||||
[string[]]
|
||||
$ExcludeFromSigning
|
||||
)
|
||||
|
||||
Write-Output "+=================================================================+"
|
||||
Write-Output "| Beginning mRemoteNG Installer Post Build |"
|
||||
Write-Output "+=================================================================+"
|
||||
Format-Table -AutoSize -Wrap -InputObject @{
|
||||
"SolutionDir" = $SolutionDir
|
||||
"TargetDir" = $TargetDir
|
||||
"TargetFileName" = $TargetFileName
|
||||
"ConfigurationName" = $ConfigurationName
|
||||
"ExcludeFromSigning" = $ExcludeFromSigning
|
||||
}
|
||||
|
||||
|
||||
& "$PSScriptRoot\sign_binaries.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning
|
||||
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\rename_installer_with_version.ps1" -SolutionDir $SolutionDir
|
||||
& "$PSScriptRoot\copy_release_installer.ps1" -SourcePath $TargetDir -DestinationDir (Join-Path -Path $SolutionDir -ChildPath "Release")
|
||||
47
Tools/postbuild_mremotev1.ps1
Normal file
47
Tools/postbuild_mremotev1.ps1
Normal file
@@ -0,0 +1,47 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetFileName,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName,
|
||||
|
||||
[string]
|
||||
$CertificatePath,
|
||||
|
||||
[string]
|
||||
$CertificatePassword,
|
||||
|
||||
[string[]]
|
||||
$ExcludeFromSigning
|
||||
)
|
||||
|
||||
Write-Output "+=================================================================+"
|
||||
Write-Output "| Beginning mRemoteV1 Post Build |"
|
||||
Write-Output "+=================================================================+"
|
||||
Format-Table -AutoSize -Wrap -InputObject @{
|
||||
"SolutionDir" = $SolutionDir
|
||||
"TargetDir" = $TargetDir
|
||||
"TargetFileName" = $TargetFileName
|
||||
"ConfigurationName" = $ConfigurationName
|
||||
"ExcludeFromSigning" = $ExcludeFromSigning
|
||||
}
|
||||
|
||||
|
||||
|
||||
& "$PSScriptRoot\copy_puttyng.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
|
||||
& "$PSScriptRoot\move_help_files.ps1" -TargetDir $TargetDir
|
||||
& "$PSScriptRoot\set_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName
|
||||
& "$PSScriptRoot\tidy_files_for_release.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\sign_binaries.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning
|
||||
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
& "$PSScriptRoot\zip_portable_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
|
||||
198
Tools/publish_to_github.ps1
Normal file
198
Tools/publish_to_github.ps1
Normal file
@@ -0,0 +1,198 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Owner,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Repository,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$ReleaseTitle,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$TagName,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# Either the SHA of the commit to target or the branch name.
|
||||
$TargetCommitish,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Description,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
[ValidateSet("true","false")]
|
||||
# true/false
|
||||
$IsDraft,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
[ValidateSet("true","false")]
|
||||
# true/false
|
||||
$IsPrerelease,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# Path to the zip file to upload with the release
|
||||
$ZipFilePath,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#Path to the msi file to upload with the release
|
||||
$MsiFilePath,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# The OAuth2 token to use for authentication.
|
||||
$AuthToken,
|
||||
|
||||
[switch]
|
||||
# Enable this switch to treat $Description as a Base64 encoded string. It will be decoded before being used elsewhere in the script.
|
||||
$DescriptionIsBase64Encoded
|
||||
)
|
||||
|
||||
|
||||
$githubUrl = 'https://api.github.com'
|
||||
if ($DescriptionIsBase64Encoded) {
|
||||
$Description = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Description)))
|
||||
}
|
||||
|
||||
|
||||
function Publish-Release {
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Owner,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Repository,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$ReleaseTitle,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$TagName,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# Either the SHA of the commit to target or the branch name.
|
||||
$TargetCommitish,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Description,
|
||||
|
||||
[bool]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$IsDraft,
|
||||
|
||||
[bool]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$IsPrerelease,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# The OAuth2 token to use for authentication.
|
||||
$AuthToken
|
||||
)
|
||||
|
||||
$body_publishRelease = @{
|
||||
"tag_name" = $TagName
|
||||
"target_commitish" = $TargetCommitish
|
||||
"name" = $ReleaseTitle
|
||||
"body" = $Description
|
||||
"draft" = $IsDraft
|
||||
"prerelease" = $IsPrerelease
|
||||
}
|
||||
|
||||
$req_publishRelease = Invoke-WebRequest -Uri "$githubUrl/repos/$Owner/$Repository/releases" -Method Post -Headers @{"Authorization"="token $AuthToken"} -Body (ConvertTo-Json -InputObject $body_publishRelease -Compress) -ErrorAction Stop
|
||||
$response_publishRelease = ConvertFrom-Json -InputObject $req_publishRelease.Content
|
||||
|
||||
Write-Output $response_publishRelease
|
||||
}
|
||||
|
||||
|
||||
function Get-GitHubRelease {
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Owner,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$Repository,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
#
|
||||
$ReleaseId,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# The OAuth2 token to use for authentication.
|
||||
$AuthToken
|
||||
)
|
||||
|
||||
$req_getRelease = Invoke-WebRequest -Uri "$githubUrl/repos/$Owner/$Repository/releases/$ReleaseId" -Method Get -Headers @{"Authorization"="token $AuthToken"} -ErrorAction Stop
|
||||
$response_getRelease = ConvertFrom-Json -InputObject $req_getRelease.Content
|
||||
|
||||
Write-Output $response_getRelease
|
||||
}
|
||||
|
||||
|
||||
function Upload-ReleaseAsset {
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$UploadUri,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# Path to the file to upload with the release
|
||||
$FilePath,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# Content type of the file
|
||||
$ContentType,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
# The OAuth2 token to use for authentication.
|
||||
$AuthToken
|
||||
)
|
||||
|
||||
$UploadUri = $UploadUri -replace "(\{[\w,\?]*\})$"
|
||||
$file = Get-Item -Path $FilePath
|
||||
|
||||
$req_uploadZipAsset = Invoke-WebRequest -Uri "$($UploadUri)?name=$($file.Name)" -Method Post -Headers @{"Authorization"="token $AuthToken"} -ContentType $ContentType -InFile $file.FullName -ErrorAction Stop
|
||||
}
|
||||
|
||||
|
||||
|
||||
$release = Publish-Release -Owner $Owner -Repository $Repository -ReleaseTitle $ReleaseTitle -TagName $TagName -TargetCommitish $TargetCommitish -Description $Description -IsDraft ([bool]::Parse($IsDraft)) -IsPrerelease ([bool]::Parse($IsPrerelease)) -AuthToken $AuthToken
|
||||
$zipUpload = Upload-ReleaseAsset -UploadUri $release.upload_url -FilePath $ZipFilePath -ContentType "application/zip" -AuthToken $AuthToken
|
||||
$msiUpload = Upload-ReleaseAsset -UploadUri $release.upload_url -FilePath $MsiFilePath -ContentType "application/octet-stream" -AuthToken $AuthToken
|
||||
Write-Output (Get-GitHubRelease -Owner $Owner -Repository $Repository -ReleaseId $release.id -AuthToken $AuthToken)
|
||||
@@ -1,11 +1,15 @@
|
||||
$solutionDir = $args[0]
|
||||
$renameTarget = $solutionDir + "InstallerProjects\Installer\bin\Release\en-US\mRemoteNG-Installer.msi"
|
||||
param (
|
||||
[string]
|
||||
$SolutionDir
|
||||
)
|
||||
|
||||
Write-Host $solutionDir
|
||||
$renameTarget = $SolutionDir + "InstallerProjects\Installer\bin\Release\en-US\mRemoteNG-Installer.msi"
|
||||
|
||||
Write-Host $SolutionDir
|
||||
Write-Host $renameTarget
|
||||
|
||||
$targetVersionedFile = "$solutionDir\mRemoteV1\bin\Release\mRemoteNG.exe"
|
||||
$version = &"$solutionDir\Tools\sigcheck.exe" /accepteula -q -n $targetVersionedFile
|
||||
$targetVersionedFile = "$SolutionDir\mRemoteV1\bin\Release\mRemoteNG.exe"
|
||||
$version = &"$SolutionDir\Tools\sigcheck.exe" /accepteula -q -n $targetVersionedFile
|
||||
|
||||
|
||||
$renameTargetFileObject = Get-Item -Path $renameTarget -ErrorAction SilentlyContinue
|
||||
|
||||
30
Tools/set_LargeAddressAware.ps1
Normal file
30
Tools/set_LargeAddressAware.ps1
Normal file
@@ -0,0 +1,30 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetFileName
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
# Find editbin.exe
|
||||
$path_editBin = @((Resolve-Path -Path "C:\Program Files*\Microsoft Visual Studio*\VC\bin\editbin.exe").Path)[0]
|
||||
|
||||
# Verify editbin certificate
|
||||
$microsoft_cert_thumbprint = "3BDA323E552DB1FDE5F4FBEE75D6D5B2B187EEDC"
|
||||
$editbin_signature = Get-AuthenticodeSignature -FilePath $path_editBin
|
||||
if (($editbin_signature.Status -ne "Valid") -or ($editbin_signature.SignerCertificate.Thumbprint -ne $microsoft_cert_thumbprint)) {
|
||||
Write-Error "Could not validate the signature of editbin.exe - we can not set LargeAddressAware" -ErrorAction Stop
|
||||
}
|
||||
|
||||
|
||||
$path_outputExe = Join-Path -Path $TargetDir -ChildPath $TargetFileName
|
||||
|
||||
# Set LargeAddressAware
|
||||
Write-Output "Setting LargeAddressAware on binary file `"$path_outputExe`""
|
||||
& $path_editBin "/largeaddressaware" "$path_outputExe"
|
||||
|
||||
Write-Output ""
|
||||
80
Tools/sign_binaries.ps1
Normal file
80
Tools/sign_binaries.ps1
Normal file
@@ -0,0 +1,80 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName,
|
||||
|
||||
[string[]]
|
||||
# File names to exclude from signing
|
||||
$Exclude,
|
||||
|
||||
[string]
|
||||
# The code signing certificate to use when signing the files.
|
||||
$CertificatePath,
|
||||
|
||||
[string]
|
||||
# Password to unlock the code signing certificate.
|
||||
$CertificatePassword
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
|
||||
$timeserver = "http://timestamp.verisign.com/scripts/timstamp.dll"
|
||||
|
||||
|
||||
if ($ConfigurationName -notmatch "Release") {
|
||||
Write-Output "This is not a release build - we won't sign files."
|
||||
return
|
||||
}
|
||||
|
||||
if ($CertificatePath -eq "" -or !(Test-Path -Path $CertificatePath -PathType Leaf)) {
|
||||
Write-Output "Certificate is not present - we won't sign files."
|
||||
return
|
||||
}
|
||||
|
||||
if ($CertificatePassword -eq "") {
|
||||
Write-Output "No certificate password was provided - we won't sign files."
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
$certKeyStore = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet
|
||||
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificatePath, $CertificatePassword, $certKeyStore) -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Output "Error loading certificate file - we won't sign files."
|
||||
Write-Output $Error[0]
|
||||
return
|
||||
}
|
||||
|
||||
# Sign MSI if we are building a release version and the certificate is available
|
||||
Write-Output "Signing Binaries"
|
||||
Write-Output "Getting files from path: $TargetDir"
|
||||
$signableFiles = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"} | ?{$Exclude -notcontains $_.Name}
|
||||
|
||||
$excluded_files = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"} | ?{$Exclude -contains $_.Name}
|
||||
$excluded_files | ForEach-Object `
|
||||
-Begin { Write-Output "The following files were excluded from signing due to being on the exclusion list:" } `
|
||||
-Process { Write-Output "-- $($_.FullName)" }
|
||||
|
||||
Write-Output "Signable files count: $($signableFiles.Count)"
|
||||
|
||||
|
||||
foreach ($file in $signableFiles) {
|
||||
Set-AuthenticodeSignature -Certificate $cert -TimestampServer $timeserver -IncludeChain all -FilePath $file.FullName
|
||||
}
|
||||
|
||||
|
||||
# Release certificate
|
||||
if ($cert -ne $null) {
|
||||
$cert.Dispose()
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
@@ -1,13 +0,0 @@
|
||||
$timeserver = "http://timestamp.verisign.com/scripts/timstamp.dll"
|
||||
$certPath = "C:\mRemoteNG_code_signing_cert.pfx"
|
||||
$certPassword = (Get-Credential -Message "Enter the password for the certificate" -UserName "USERNAME NOT NEEDED").Password
|
||||
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certPath, $certPassword)
|
||||
$targetPath = $args[0]
|
||||
|
||||
|
||||
Write-Output "Getting files from path: $targetPath"
|
||||
$signableFiles = Get-ChildItem -Path $targetPath -Recurse | ?{$_.Extension -match "dll|exe|msi"}
|
||||
Write-Output "Signable files count: $($signableFiles.Count)"
|
||||
foreach ($file in $signableFiles) {
|
||||
Set-AuthenticodeSignature -Certificate $cert -TimestampServer $timeserver -IncludeChain all -FilePath $file.FullName
|
||||
}
|
||||
33
Tools/tidy_files_for_release.ps1
Normal file
33
Tools/tidy_files_for_release.ps1
Normal file
@@ -0,0 +1,33 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
# Remove unnecessary files from Release versions
|
||||
if ($ConfigurationName -match "Release") {
|
||||
Write-Output "Removing unnecessary files from Release versions"
|
||||
Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "app.publish") -Recurse -Force
|
||||
$filesToDelete = Get-ChildItem -Path $TargetDir -Recurse -Include @(
|
||||
"*.pdb",
|
||||
"*.publish",
|
||||
"*.xml",
|
||||
"*.backup",
|
||||
"*.log",
|
||||
"*vshost*",
|
||||
"*.tmp"
|
||||
)
|
||||
Remove-Item -Path $filesToDelete.FullName
|
||||
Write-Output $filesToDelete.FullName
|
||||
}
|
||||
else {
|
||||
Write-Output "We will not remove anything - this is not a release build."
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
36
Tools/verify_binary_signatures.ps1
Normal file
36
Tools/verify_binary_signatures.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
|
||||
# Sign MSI if we are building a release version and the certificate is available
|
||||
if ($ConfigurationName -match "Release") {
|
||||
Write-Output "Verifying signature of binaries"
|
||||
Write-Output "Getting files from path: $TargetDir"
|
||||
$signableFiles = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"}
|
||||
Write-Output "Signable files count: $($signableFiles.Count)"
|
||||
$badSignatureFound = $false
|
||||
foreach ($file in $signableFiles) {
|
||||
$signature = Get-AuthenticodeSignature -FilePath $file.FullName
|
||||
if ($signature.Status -ne "Valid") {
|
||||
Write-Warning "File $($file.FullName) does not have a valid signature."
|
||||
$badSignatureFound = $true
|
||||
}
|
||||
}
|
||||
if ($badSignatureFound) {
|
||||
Write-Output "One or more files were improperly signed."
|
||||
} else {
|
||||
Write-Output "All files have valid signatures."
|
||||
}
|
||||
} else {
|
||||
Write-Output "This is not a release build - we won't verify file signatures."
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
28
Tools/zip_portable_files.ps1
Normal file
28
Tools/zip_portable_files.ps1
Normal file
@@ -0,0 +1,28 @@
|
||||
param (
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$SolutionDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$TargetDir,
|
||||
|
||||
[string]
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
|
||||
$path_packageZipScript = Join-Path -Path $SolutionDir -ChildPath "Tools\build-relport.cmd"
|
||||
|
||||
|
||||
# Package Zip
|
||||
if ($ConfigurationName -match "Release" -and $ConfigurationName -match "Portable") {
|
||||
Write-Output "Packaging Release Portable ZIP"
|
||||
& $path_packageZipScript
|
||||
}
|
||||
else {
|
||||
Write-Output "We will not zip anything - this isnt a portable release build."
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNGTests.TestHelpers;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.Config.Serializers
|
||||
{
|
||||
public class DataTableDeserializerTests
|
||||
{
|
||||
private DataTableDeserializer _deserializer;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void WeCanDeserializeATree()
|
||||
{
|
||||
var model = CreateConnectionTreeModel();
|
||||
var dataTable = CreateDataTable(model.RootNodes[0]);
|
||||
_deserializer = new DataTableDeserializer(dataTable);
|
||||
var output = _deserializer.Deserialize();
|
||||
Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(model.GetRecursiveChildList().Count()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WeCanDeserializeASingleEntry()
|
||||
{
|
||||
var dataTable = CreateDataTable(new ConnectionInfo());
|
||||
_deserializer = new DataTableDeserializer(dataTable);
|
||||
var output = _deserializer.Deserialize();
|
||||
Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
|
||||
private DataTable CreateDataTable(ConnectionInfo tableContent)
|
||||
{
|
||||
var serializer = new DataTableSerializer(new SaveFilter());
|
||||
return serializer.Serialize(tableContent);
|
||||
}
|
||||
|
||||
private ConnectionTreeModel CreateConnectionTreeModel()
|
||||
{
|
||||
var builder = new ConnectionTreeModelBuilder();
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using mRemoteNG.Container;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNGTests.TestHelpers;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.Config.Serializers
|
||||
@@ -20,13 +21,6 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
_dataTableSerializer = new DataTableSerializer(_saveFilter);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown()
|
||||
{
|
||||
_saveFilter = null;
|
||||
_dataTableSerializer = null;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllItemsSerialized()
|
||||
{
|
||||
@@ -35,6 +29,14 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
Assert.That(dataTable.Rows.Count, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReturnsEmptyDataTableWhenGivenEmptyConnectionTreeModel()
|
||||
{
|
||||
var model = new ConnectionTreeModel();
|
||||
var dataTable = _dataTableSerializer.Serialize(model);
|
||||
Assert.That(dataTable.Rows.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UsernameSerializedWhenSaveSecurityAllowsIt()
|
||||
{
|
||||
@@ -109,20 +111,18 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
Assert.That(dataTable.Rows[0]["InheritUsername"], Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanSerializeEmptyConnectionInfo()
|
||||
{
|
||||
var dataTable = _dataTableSerializer.Serialize(new ConnectionInfo());
|
||||
Assert.That(dataTable.Rows.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
|
||||
private ConnectionTreeModel CreateConnectionTreeModel()
|
||||
{
|
||||
var model = new ConnectionTreeModel();
|
||||
var root = new RootNodeInfo(RootNodeType.Connection);
|
||||
var folder1 = new ContainerInfo {Name = "folder1", Username = "user1", Domain = "domain1", Password = "password1"};
|
||||
var con1 = new ConnectionInfo {Name = "Con1", Username = "user1", Domain = "domain1", Password = "password1" };
|
||||
var con2 = new ConnectionInfo {Name = "Con2", Username = "user2", Domain = "domain2", Password = "password2" };
|
||||
|
||||
root.AddChild(folder1);
|
||||
root.AddChild(con2);
|
||||
folder1.AddChild(con1);
|
||||
model.AddRootNode(root);
|
||||
return model;
|
||||
var builder = new ConnectionTreeModelBuilder();
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,14 @@ namespace mRemoteNGTests.Connection
|
||||
Assert.That(secondConnection.Domain, Is.EqualTo(_connectionInfo.Domain));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CloneDoesNotSetParentOfNewConnectionInfo()
|
||||
{
|
||||
_connectionInfo.SetParent(new ContainerInfo());
|
||||
var clonedConnection = _connectionInfo.Clone();
|
||||
Assert.That(clonedConnection.Parent, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFromCopiesProperties()
|
||||
{
|
||||
|
||||
@@ -263,6 +263,14 @@ namespace mRemoteNGTests.Container
|
||||
Assert.That(clone.ConstantID, Is.Not.EqualTo(_containerInfo.ConstantID));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClonedContainerDoesNotHaveParentSet()
|
||||
{
|
||||
_containerInfo.SetParent(new ContainerInfo());
|
||||
var clone = _containerInfo.Clone();
|
||||
Assert.That(clone.Parent, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClonedContainerContainsClonedChildren()
|
||||
{
|
||||
|
||||
25
mRemoteNGTests/TestHelpers/ConnectionTreeModelBuilder.cs
Normal file
25
mRemoteNGTests/TestHelpers/ConnectionTreeModelBuilder.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNGTests.TestHelpers
|
||||
{
|
||||
public class ConnectionTreeModelBuilder
|
||||
{
|
||||
public ConnectionTreeModel Build()
|
||||
{
|
||||
var model = new ConnectionTreeModel();
|
||||
var root = new RootNodeInfo(RootNodeType.Connection);
|
||||
var folder1 = new ContainerInfo { Name = "folder1", Username = "user1", Domain = "domain1", Password = "password1" };
|
||||
var con1 = new ConnectionInfo { Name = "Con1", Username = "user1", Domain = "domain1", Password = "password1" };
|
||||
var con2 = new ConnectionInfo { Name = "Con2", Username = "user2", Domain = "domain2", Password = "password2" };
|
||||
|
||||
root.AddChild(folder1);
|
||||
root.AddChild(con2);
|
||||
folder1.AddChild(con1);
|
||||
model.AddRootNode(root);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug Portable|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug Portable\</OutputPath>
|
||||
<OutputPath>bin\Debug Portable\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;PORTABLE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
@@ -45,7 +45,7 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release Portable|x86'">
|
||||
<OutputPath>bin\x86\Release Portable\</OutputPath>
|
||||
<OutputPath>bin\Release Portable\</OutputPath>
|
||||
<DefineConstants>TRACE;PORTABLE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -111,6 +111,7 @@
|
||||
<Compile Include="App\LoggerTests.cs" />
|
||||
<Compile Include="App\UpdaterTests.cs" />
|
||||
<Compile Include="BinaryFileTests.cs" />
|
||||
<Compile Include="Config\Serializers\DataTableDeserializerTests.cs" />
|
||||
<Compile Include="Config\Serializers\DataTableSerializerTests.cs" />
|
||||
<Compile Include="Config\Serializers\PortScanDeserializerTests.cs" />
|
||||
<Compile Include="Config\Serializers\PuttyConnectionManagerDeserializerTests.cs" />
|
||||
@@ -129,6 +130,7 @@
|
||||
<Compile Include="Security\Authentication\PasswordAuthenticatorTests.cs" />
|
||||
<Compile Include="Security\KeyDerivation\Pkcs5S2KeyGeneratorTests.cs" />
|
||||
<Compile Include="Security\SecureStringExtensionsTests.cs" />
|
||||
<Compile Include="TestHelpers\ConnectionTreeModelBuilder.cs" />
|
||||
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
|
||||
<Compile Include="Tree\ClickHandlers\TreeNodeCompositeClickHandlerTests.cs" />
|
||||
<Compile Include="Tree\ConnectionTreeDragAndDropHandlerTests.cs" />
|
||||
|
||||
@@ -20,6 +20,7 @@ Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug Portable|x86 = Debug Portable|x86
|
||||
Debug|x86 = Debug|x86
|
||||
Release Installer|x86 = Release Installer|x86
|
||||
Release Portable|x86 = Release Portable|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
@@ -28,6 +29,8 @@ Global
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.Build.0 = Debug Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.Build.0 = Debug|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.Build.0 = Release|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.ActiveCfg = Release Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.Build.0 = Release Portable|x86
|
||||
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.ActiveCfg = Release|x86
|
||||
@@ -36,6 +39,8 @@ Global
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.Build.0 = Debug Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.Build.0 = Debug|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.Build.0 = Release|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.ActiveCfg = Release Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.Build.0 = Release Portable|x86
|
||||
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.ActiveCfg = Release|x86
|
||||
@@ -43,11 +48,14 @@ Global
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|x86.ActiveCfg = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.Build.0 = Debug|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x86.Build.0 = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Portable|x86.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x86.ActiveCfg = Release|x86
|
||||
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x86.Build.0 = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.ActiveCfg = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.Build.0 = Release|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|x86.ActiveCfg = Release Portable|x86
|
||||
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|x86.ActiveCfg = Release|x86
|
||||
EndGlobalSection
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#pragma warning disable 169
|
||||
|
||||
namespace mRemoteNG.App
|
||||
@@ -42,11 +45,17 @@ namespace mRemoteNG.App
|
||||
internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, System.Text.StringBuilder lParam);
|
||||
internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, string lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr SendMessage([In] IntPtr hWnd, [In] uint msg, [Out] StringBuilder wParam, [In] IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
|
||||
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
@@ -76,6 +85,10 @@ namespace mRemoteNG.App
|
||||
|
||||
[DllImport("user32", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
|
||||
|
||||
[DllImport("kernel32", SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static extern bool CloseHandle(IntPtr handle);
|
||||
#endregion
|
||||
|
||||
#region Structures
|
||||
@@ -286,7 +299,10 @@ namespace mRemoteNG.App
|
||||
public const int WA_ACTIVE = 0x1;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Sent to both the window being activated and the window being deactivated.
|
||||
/// If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the
|
||||
/// top-level window being deactivated, then to the window procedure of the top-level window being activated. If the
|
||||
/// windows use different input queues, the message is sent asynchronously, so the window is activated immediately.
|
||||
/// </summary>
|
||||
public const int WA_CLICKACTIVE = 0x2;
|
||||
#endregion
|
||||
@@ -455,6 +471,12 @@ namespace mRemoteNG.App
|
||||
public const int VK_C = 0x67;
|
||||
#endregion
|
||||
|
||||
#region EM
|
||||
public const uint ECM_FIRST = 0x1500;
|
||||
public const uint EM_SETCUEBANNER = ECM_FIRST + 1;
|
||||
public const uint EM_GETCUEBANNER = ECM_FIRST + 2;
|
||||
#endregion
|
||||
|
||||
#region LB
|
||||
public const int LB_ERR = -1;
|
||||
public const int LB_SELECTSTRING = 0x18C;
|
||||
|
||||
@@ -27,6 +27,9 @@ namespace mRemoteNG.App.Update
|
||||
char[] keyValueSeparators = { ':', '=' };
|
||||
char[] commentCharacters = { '#', ';', '\'' };
|
||||
|
||||
// no separators means no valid update data...
|
||||
if (content.Trim().IndexOfAny(keyValueSeparators) == -1) return;
|
||||
|
||||
using (var sr = new StringReader(content))
|
||||
{
|
||||
string line;
|
||||
@@ -43,6 +46,10 @@ namespace mRemoteNG.App.Update
|
||||
if (parts.Length != 2)
|
||||
continue;
|
||||
|
||||
// make sure we have valid data in both parts before adding to the collection. If either part is empty, then it's not valid data.
|
||||
if(string.IsNullOrEmpty(parts[0].Trim()) || string.IsNullOrEmpty(parts[1].Trim()))
|
||||
continue;
|
||||
|
||||
Items.Add(parts[0].Trim(), parts[1].Trim());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,13 @@ namespace mRemoteNG.Config.DataProviders
|
||||
{
|
||||
if (!SqlDatabaseConnector.IsConnected)
|
||||
OpenConnection();
|
||||
var sqlBulkCopy = new SqlBulkCopy(SqlDatabaseConnector.SqlConnection) {DestinationTableName = "dbo.tblCons"};
|
||||
sqlBulkCopy.WriteToServer(dataTable);
|
||||
sqlBulkCopy.Close();
|
||||
using (var sqlBulkCopy = new SqlBulkCopy(SqlDatabaseConnector.SqlConnection))
|
||||
{
|
||||
foreach (DataColumn col in dataTable.Columns)
|
||||
sqlBulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
|
||||
sqlBulkCopy.DestinationTableName = "dbo.tblCons";
|
||||
sqlBulkCopy.WriteToServer(dataTable);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenConnection()
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace mRemoteNG.Config.Import
|
||||
var connectionTreeModel = xmlConnectionsDeserializer.Deserialize(true);
|
||||
|
||||
var rootImportContainer = new ContainerInfo { Name = Path.GetFileNameWithoutExtension(fileName) };
|
||||
rootImportContainer.Children.AddRange(connectionTreeModel.RootNodes.First().Children);
|
||||
rootImportContainer.AddChildRange(connectionTreeModel.RootNodes.First().Children.ToArray());
|
||||
destinationContainer.AddChild(rootImportContainer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
@@ -42,7 +43,8 @@ namespace mRemoteNG.Config.Putty
|
||||
private IEnumerable<PuttySessionInfo> GetSessionToRemove(IEnumerable<string> sessionNamesFromProvider)
|
||||
{
|
||||
var currentlyKnownSessionNames = Sessions.Select(session => session.Name);
|
||||
var sessionNamesToRemove = currentlyKnownSessionNames.Except(sessionNamesFromProvider);
|
||||
var normalizedSessionNames = sessionNamesFromProvider.Select(HttpUtility.UrlDecode);
|
||||
var sessionNamesToRemove = currentlyKnownSessionNames.Except(normalizedSessionNames);
|
||||
return Sessions.Where(session => sessionNamesToRemove.Contains(session.Name));
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace mRemoteNG.Config.Putty
|
||||
|
||||
if (raw && !sessionNames.Contains("Default%20Settings"))
|
||||
sessionNames.Insert(0, "Default%20Settings");
|
||||
else if (!sessionNames.Contains("Default Settings"))
|
||||
else if (!raw && !sessionNames.Contains("Default Settings"))
|
||||
sessionNames.Insert(0, "Default Settings");
|
||||
|
||||
return sessionNames.ToArray();
|
||||
|
||||
@@ -43,10 +43,16 @@ namespace mRemoteNG.Config.Serializers
|
||||
var nodeList = new List<ConnectionInfo>();
|
||||
foreach (DataRow row in _dataTable.Rows)
|
||||
{
|
||||
if ((string)row["Type"] == "Connection")
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch ((string)row["Type"])
|
||||
{
|
||||
case "Connection":
|
||||
nodeList.Add(DeserializeConnectionInfo(row));
|
||||
else if ((string)row["Type"] == "Container")
|
||||
break;
|
||||
case "Container":
|
||||
nodeList.Add(DeserializeContainerInfo(row));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nodeList;
|
||||
}
|
||||
@@ -69,8 +75,15 @@ namespace mRemoteNG.Config.Serializers
|
||||
{
|
||||
connectionInfo.Name = (string)dataRow["Name"];
|
||||
connectionInfo.ConstantID = (string)dataRow["ConstantID"];
|
||||
|
||||
// This throws a NPE - Parent is a connectionInfo object which will be null at this point.
|
||||
// The Parent object is linked properly later in CreateNodeHierarchy()
|
||||
//connectionInfo.Parent.ConstantID = (string)dataRow["ParentID"];
|
||||
//connectionInfo is ContainerInfo ? ((ContainerInfo)connectionInfo).IsExpanded.ToString() : "" = dataRow["Expanded"];
|
||||
|
||||
var info = connectionInfo as ContainerInfo;
|
||||
if(info != null)
|
||||
info.IsExpanded = (bool)dataRow["Expanded"];
|
||||
|
||||
connectionInfo.Description = (string)dataRow["Description"];
|
||||
connectionInfo.Icon = (string)dataRow["Icon"];
|
||||
connectionInfo.Panel = (string)dataRow["Panel"];
|
||||
@@ -195,7 +208,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
var id = (string) row["ConstantID"];
|
||||
var connectionInfo = connectionList.First(node => node.ConstantID == id);
|
||||
var parentId = (string) row["ParentID"];
|
||||
if (parentId == "0")
|
||||
if (parentId == "0" || connectionList.All(node => node.ConstantID != parentId))
|
||||
rootNode.AddChild(connectionInfo);
|
||||
else
|
||||
(connectionList.First(node => node.ConstantID == parentId) as ContainerInfo)?.AddChild(connectionInfo);
|
||||
|
||||
@@ -25,147 +25,162 @@ namespace mRemoteNG.Config.Serializers
|
||||
|
||||
public DataTable Serialize(ConnectionTreeModel connectionTreeModel)
|
||||
{
|
||||
var rootNode = (RootNodeInfo)connectionTreeModel.RootNodes.First(node => node is RootNodeInfo);
|
||||
return Serialize(rootNode);
|
||||
try
|
||||
{
|
||||
_dataTable = BuildTable();
|
||||
_currentNodeIndex = 0;
|
||||
var rootNode = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo);
|
||||
return Serialize(rootNode);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return _dataTable;
|
||||
}
|
||||
}
|
||||
|
||||
public DataTable Serialize(ConnectionInfo serializationTarget)
|
||||
{
|
||||
_dataTable = new DataTable(TableName);
|
||||
CreateSchema();
|
||||
SetPrimaryKey();
|
||||
_dataTable = BuildTable();
|
||||
_currentNodeIndex = 0;
|
||||
SerializeNodesRecursive(serializationTarget);
|
||||
return _dataTable;
|
||||
}
|
||||
|
||||
private void CreateSchema()
|
||||
private DataTable BuildTable()
|
||||
{
|
||||
// Note: these columns must be defined in the same order that they exist in the DB
|
||||
_dataTable.Columns.Add("ID", typeof(int));
|
||||
_dataTable.Columns[0].AutoIncrement = true;
|
||||
_dataTable.Columns.Add("ConstantID", typeof(string));
|
||||
_dataTable.Columns.Add("PositionID", typeof(int));
|
||||
_dataTable.Columns.Add("ParentID", typeof(string));
|
||||
_dataTable.Columns.Add("LastChange", typeof(SqlDateTime));
|
||||
_dataTable.Columns.Add("Name", typeof(string));
|
||||
_dataTable.Columns.Add("Type", typeof(string));
|
||||
_dataTable.Columns.Add("Expanded", typeof(bool));
|
||||
_dataTable.Columns.Add("Description", typeof(string));
|
||||
_dataTable.Columns.Add("Icon", typeof(string));
|
||||
_dataTable.Columns.Add("Panel", typeof(string));
|
||||
_dataTable.Columns.Add("Username", typeof(string));
|
||||
_dataTable.Columns.Add("DomainName", typeof(string));
|
||||
_dataTable.Columns.Add("Password", typeof(string));
|
||||
_dataTable.Columns.Add("Hostname", typeof(string));
|
||||
_dataTable.Columns.Add("Protocol", typeof(string));
|
||||
_dataTable.Columns.Add("PuttySession", typeof(string));
|
||||
_dataTable.Columns.Add("Port", typeof(int));
|
||||
_dataTable.Columns.Add("ConnectToConsole", typeof(bool));
|
||||
_dataTable.Columns.Add("UseCredSsp", typeof(bool));
|
||||
_dataTable.Columns.Add("RenderingEngine", typeof(string));
|
||||
_dataTable.Columns.Add("ICAEncryptionStrength", typeof(string));
|
||||
_dataTable.Columns.Add("RDPAuthenticationLevel", typeof(string));
|
||||
_dataTable.Columns.Add("Colors", typeof(string));
|
||||
_dataTable.Columns.Add("Resolution", typeof(string));
|
||||
_dataTable.Columns.Add("DisplayWallpaper", typeof(bool));
|
||||
_dataTable.Columns.Add("DisplayThemes", typeof(bool));
|
||||
_dataTable.Columns.Add("EnableFontSmoothing", typeof(bool));
|
||||
_dataTable.Columns.Add("EnableDesktopComposition", typeof(bool));
|
||||
_dataTable.Columns.Add("CacheBitmaps", typeof(bool));
|
||||
_dataTable.Columns.Add("RedirectDiskDrives", typeof(bool));
|
||||
_dataTable.Columns.Add("RedirectPorts", typeof(bool));
|
||||
_dataTable.Columns.Add("RedirectPrinters", typeof(bool));
|
||||
_dataTable.Columns.Add("RedirectSmartCards", typeof(bool));
|
||||
_dataTable.Columns.Add("RedirectSound", typeof(string));
|
||||
_dataTable.Columns.Add("RedirectKeys", typeof(bool));
|
||||
_dataTable.Columns.Add("Connected", typeof(bool));
|
||||
_dataTable.Columns.Add("PreExtApp", typeof(string));
|
||||
_dataTable.Columns.Add("PostExtApp", typeof(string));
|
||||
_dataTable.Columns.Add("MacAddress", typeof(string));
|
||||
_dataTable.Columns.Add("UserField", typeof(string));
|
||||
_dataTable.Columns.Add("ExtApp", typeof(string));
|
||||
_dataTable.Columns.Add("VNCCompression", typeof(string));
|
||||
_dataTable.Columns.Add("VNCEncoding", typeof(string));
|
||||
_dataTable.Columns.Add("VNCAuthMode", typeof(string));
|
||||
_dataTable.Columns.Add("VNCProxyType", typeof(string));
|
||||
_dataTable.Columns.Add("VNCProxyIP", typeof(string));
|
||||
_dataTable.Columns.Add("VNCProxyPort", typeof(int));
|
||||
_dataTable.Columns.Add("VNCProxyUsername", typeof(string));
|
||||
_dataTable.Columns.Add("VNCProxyPassword", typeof(string));
|
||||
_dataTable.Columns.Add("VNCColors", typeof(string));
|
||||
_dataTable.Columns.Add("VNCSmartSizeMode", typeof(string));
|
||||
_dataTable.Columns.Add("VNCViewOnly", typeof(bool));
|
||||
_dataTable.Columns.Add("RDGatewayUsageMethod", typeof(string));
|
||||
_dataTable.Columns.Add("RDGatewayHostname", typeof(string));
|
||||
_dataTable.Columns.Add("RDGatewayUseConnectionCredentials", typeof(string));
|
||||
_dataTable.Columns.Add("RDGatewayUsername", typeof(string));
|
||||
_dataTable.Columns.Add("RDGatewayPassword", typeof(string));
|
||||
_dataTable.Columns.Add("RDGatewayDomain", typeof(string));
|
||||
_dataTable.Columns.Add("InheritCacheBitmaps", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritColors", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritDescription", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritDisplayThemes", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritDisplayWallpaper", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritEnableFontSmoothing", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritEnableDesktopComposition", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritDomain", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritIcon", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritPanel", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritPassword", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritPort", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritProtocol", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritPuttySession", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectDiskDrives", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectKeys", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectPorts", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectPrinters", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectSmartCards", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectSound", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritResolution", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritUseConsoleSession", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritUseCredSsp", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRenderingEngine", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritICAEncryptionStrength", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDPAuthenticationLevel", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritUsername", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritPreExtApp", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritPostExtApp", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritMacAddress", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritUserField", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritExtApp", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCCompression", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCEncoding", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCAuthMode", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCProxyType", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCProxyIP", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCProxyPort", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCProxyUsername", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCProxyPassword", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCColors", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCSmartSizeMode", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritVNCViewOnly", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDGatewayUsageMethod", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDGatewayHostname", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDGatewayUseConnectionCredentials", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDGatewayUsername", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDGatewayPassword", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDGatewayDomain", typeof(bool));
|
||||
_dataTable.Columns.Add("LoadBalanceInfo", typeof(string));
|
||||
_dataTable.Columns.Add("AutomaticResize", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritLoadBalanceInfo", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritAutomaticResize", typeof(bool));
|
||||
_dataTable.Columns.Add("RDPMinutesToIdleTimeout", typeof(int));
|
||||
_dataTable.Columns.Add("RDPAlertIdleTimeout", typeof(bool));
|
||||
_dataTable.Columns.Add("SoundQuality", typeof(string));
|
||||
_dataTable.Columns.Add("InheritRDPMinutesToIdleTimeout", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRDPAlertIdleTimeout", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritSoundQuality", typeof(bool));
|
||||
var dataTable = new DataTable(TableName);
|
||||
CreateSchema(dataTable);
|
||||
SetPrimaryKey(dataTable);
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
private void SetPrimaryKey()
|
||||
private void CreateSchema(DataTable dataTable)
|
||||
{
|
||||
_dataTable.PrimaryKey = new[] { _dataTable.Columns["ConstantID"] };
|
||||
// Note: these columns must be defined in the same order that they exist in the DB
|
||||
dataTable.Columns.Add("ID", typeof(int));
|
||||
dataTable.Columns[0].AutoIncrement = true;
|
||||
dataTable.Columns.Add("ConstantID", typeof(string));
|
||||
dataTable.Columns.Add("PositionID", typeof(int));
|
||||
dataTable.Columns.Add("ParentID", typeof(string));
|
||||
dataTable.Columns.Add("LastChange", typeof(SqlDateTime));
|
||||
dataTable.Columns.Add("Name", typeof(string));
|
||||
dataTable.Columns.Add("Type", typeof(string));
|
||||
dataTable.Columns.Add("Expanded", typeof(bool));
|
||||
dataTable.Columns.Add("Description", typeof(string));
|
||||
dataTable.Columns.Add("Icon", typeof(string));
|
||||
dataTable.Columns.Add("Panel", typeof(string));
|
||||
dataTable.Columns.Add("Username", typeof(string));
|
||||
dataTable.Columns.Add("DomainName", typeof(string));
|
||||
dataTable.Columns.Add("Password", typeof(string));
|
||||
dataTable.Columns.Add("Hostname", typeof(string));
|
||||
dataTable.Columns.Add("Protocol", typeof(string));
|
||||
dataTable.Columns.Add("PuttySession", typeof(string));
|
||||
dataTable.Columns.Add("Port", typeof(int));
|
||||
dataTable.Columns.Add("ConnectToConsole", typeof(bool));
|
||||
dataTable.Columns.Add("UseCredSsp", typeof(bool));
|
||||
dataTable.Columns.Add("RenderingEngine", typeof(string));
|
||||
dataTable.Columns.Add("ICAEncryptionStrength", typeof(string));
|
||||
dataTable.Columns.Add("RDPAuthenticationLevel", typeof(string));
|
||||
dataTable.Columns.Add("Colors", typeof(string));
|
||||
dataTable.Columns.Add("Resolution", typeof(string));
|
||||
dataTable.Columns.Add("DisplayWallpaper", typeof(bool));
|
||||
dataTable.Columns.Add("DisplayThemes", typeof(bool));
|
||||
dataTable.Columns.Add("EnableFontSmoothing", typeof(bool));
|
||||
dataTable.Columns.Add("EnableDesktopComposition", typeof(bool));
|
||||
dataTable.Columns.Add("CacheBitmaps", typeof(bool));
|
||||
dataTable.Columns.Add("RedirectDiskDrives", typeof(bool));
|
||||
dataTable.Columns.Add("RedirectPorts", typeof(bool));
|
||||
dataTable.Columns.Add("RedirectPrinters", typeof(bool));
|
||||
dataTable.Columns.Add("RedirectSmartCards", typeof(bool));
|
||||
dataTable.Columns.Add("RedirectSound", typeof(string));
|
||||
dataTable.Columns.Add("RedirectKeys", typeof(bool));
|
||||
dataTable.Columns.Add("Connected", typeof(bool));
|
||||
dataTable.Columns.Add("PreExtApp", typeof(string));
|
||||
dataTable.Columns.Add("PostExtApp", typeof(string));
|
||||
dataTable.Columns.Add("MacAddress", typeof(string));
|
||||
dataTable.Columns.Add("UserField", typeof(string));
|
||||
dataTable.Columns.Add("ExtApp", typeof(string));
|
||||
dataTable.Columns.Add("VNCCompression", typeof(string));
|
||||
dataTable.Columns.Add("VNCEncoding", typeof(string));
|
||||
dataTable.Columns.Add("VNCAuthMode", typeof(string));
|
||||
dataTable.Columns.Add("VNCProxyType", typeof(string));
|
||||
dataTable.Columns.Add("VNCProxyIP", typeof(string));
|
||||
dataTable.Columns.Add("VNCProxyPort", typeof(int));
|
||||
dataTable.Columns.Add("VNCProxyUsername", typeof(string));
|
||||
dataTable.Columns.Add("VNCProxyPassword", typeof(string));
|
||||
dataTable.Columns.Add("VNCColors", typeof(string));
|
||||
dataTable.Columns.Add("VNCSmartSizeMode", typeof(string));
|
||||
dataTable.Columns.Add("VNCViewOnly", typeof(bool));
|
||||
dataTable.Columns.Add("RDGatewayUsageMethod", typeof(string));
|
||||
dataTable.Columns.Add("RDGatewayHostname", typeof(string));
|
||||
dataTable.Columns.Add("RDGatewayUseConnectionCredentials", typeof(string));
|
||||
dataTable.Columns.Add("RDGatewayUsername", typeof(string));
|
||||
dataTable.Columns.Add("RDGatewayPassword", typeof(string));
|
||||
dataTable.Columns.Add("RDGatewayDomain", typeof(string));
|
||||
dataTable.Columns.Add("InheritCacheBitmaps", typeof(bool));
|
||||
dataTable.Columns.Add("InheritColors", typeof(bool));
|
||||
dataTable.Columns.Add("InheritDescription", typeof(bool));
|
||||
dataTable.Columns.Add("InheritDisplayThemes", typeof(bool));
|
||||
dataTable.Columns.Add("InheritDisplayWallpaper", typeof(bool));
|
||||
dataTable.Columns.Add("InheritEnableFontSmoothing", typeof(bool));
|
||||
dataTable.Columns.Add("InheritEnableDesktopComposition", typeof(bool));
|
||||
dataTable.Columns.Add("InheritDomain", typeof(bool));
|
||||
dataTable.Columns.Add("InheritIcon", typeof(bool));
|
||||
dataTable.Columns.Add("InheritPanel", typeof(bool));
|
||||
dataTable.Columns.Add("InheritPassword", typeof(bool));
|
||||
dataTable.Columns.Add("InheritPort", typeof(bool));
|
||||
dataTable.Columns.Add("InheritProtocol", typeof(bool));
|
||||
dataTable.Columns.Add("InheritPuttySession", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRedirectDiskDrives", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRedirectKeys", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRedirectPorts", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRedirectPrinters", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRedirectSmartCards", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRedirectSound", typeof(bool));
|
||||
dataTable.Columns.Add("InheritResolution", typeof(bool));
|
||||
dataTable.Columns.Add("InheritUseConsoleSession", typeof(bool));
|
||||
dataTable.Columns.Add("InheritUseCredSsp", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRenderingEngine", typeof(bool));
|
||||
dataTable.Columns.Add("InheritICAEncryptionStrength", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDPAuthenticationLevel", typeof(bool));
|
||||
dataTable.Columns.Add("InheritUsername", typeof(bool));
|
||||
dataTable.Columns.Add("InheritPreExtApp", typeof(bool));
|
||||
dataTable.Columns.Add("InheritPostExtApp", typeof(bool));
|
||||
dataTable.Columns.Add("InheritMacAddress", typeof(bool));
|
||||
dataTable.Columns.Add("InheritUserField", typeof(bool));
|
||||
dataTable.Columns.Add("InheritExtApp", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCCompression", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCEncoding", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCAuthMode", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCProxyType", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCProxyIP", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCProxyPort", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCProxyUsername", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCProxyPassword", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCColors", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCSmartSizeMode", typeof(bool));
|
||||
dataTable.Columns.Add("InheritVNCViewOnly", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDGatewayUsageMethod", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDGatewayHostname", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDGatewayUseConnectionCredentials", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDGatewayUsername", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDGatewayPassword", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDGatewayDomain", typeof(bool));
|
||||
dataTable.Columns.Add("LoadBalanceInfo", typeof(string));
|
||||
dataTable.Columns.Add("AutomaticResize", typeof(bool));
|
||||
dataTable.Columns.Add("InheritLoadBalanceInfo", typeof(bool));
|
||||
dataTable.Columns.Add("InheritAutomaticResize", typeof(bool));
|
||||
dataTable.Columns.Add("RDPMinutesToIdleTimeout", typeof(int));
|
||||
dataTable.Columns.Add("RDPAlertIdleTimeout", typeof(bool));
|
||||
dataTable.Columns.Add("SoundQuality", typeof(string));
|
||||
dataTable.Columns.Add("InheritRDPMinutesToIdleTimeout", typeof(bool));
|
||||
dataTable.Columns.Add("InheritRDPAlertIdleTimeout", typeof(bool));
|
||||
dataTable.Columns.Add("InheritSoundQuality", typeof(bool));
|
||||
}
|
||||
|
||||
private void SetPrimaryKey(DataTable dataTable)
|
||||
{
|
||||
dataTable.PrimaryKey = new[] { dataTable.Columns["ConstantID"] };
|
||||
}
|
||||
|
||||
private void SerializeNodesRecursive(ConnectionInfo connectionInfo)
|
||||
@@ -186,7 +201,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
dataRow["Name"] = connectionInfo.Name;
|
||||
dataRow["Type"] = connectionInfo.GetTreeNodeType().ToString();
|
||||
dataRow["ConstantID"] = connectionInfo.ConstantID;
|
||||
dataRow["ParentID"] = connectionInfo.Parent.ConstantID;
|
||||
dataRow["ParentID"] = connectionInfo.Parent?.ConstantID ?? "";
|
||||
dataRow["PositionID"] = _currentNodeIndex;
|
||||
dataRow["LastChange"] = (SqlDateTime)DateTime.Now;
|
||||
var info = connectionInfo as ContainerInfo;
|
||||
|
||||
@@ -78,7 +78,6 @@ namespace mRemoteNG.Connection
|
||||
var newConnectionInfo = new ConnectionInfo();
|
||||
newConnectionInfo.CopyFrom(this);
|
||||
newConnectionInfo.ConstantID = MiscTools.CreateConstantID();
|
||||
newConnectionInfo.SetParent(Parent);
|
||||
newConnectionInfo.Inheritance = Inheritance.Clone();
|
||||
return newConnectionInfo;
|
||||
}
|
||||
@@ -172,7 +171,7 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
var inheritType = Inheritance.GetType();
|
||||
var inheritPropertyInfo = inheritType.GetProperty(propertyName);
|
||||
var inheritPropertyValue = Convert.ToBoolean(inheritPropertyInfo.GetValue(Inheritance, null));
|
||||
var inheritPropertyValue = inheritPropertyInfo != null && Convert.ToBoolean(inheritPropertyInfo.GetValue(Inheritance, null));
|
||||
return inheritPropertyValue;
|
||||
}
|
||||
|
||||
@@ -180,15 +179,20 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
var connectionInfoType = Parent.GetType();
|
||||
var parentPropertyInfo = connectionInfoType.GetProperty(propertyName);
|
||||
if (parentPropertyInfo == null)
|
||||
return default(TPropertyType); // shouldn't get here...
|
||||
var parentPropertyValue = (TPropertyType)parentPropertyInfo.GetValue(Parent, null);
|
||||
|
||||
return parentPropertyValue;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static int GetDefaultPort(ProtocolType protocol)
|
||||
{
|
||||
try
|
||||
{
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch (protocol)
|
||||
{
|
||||
case ProtocolType.RDP:
|
||||
|
||||
@@ -179,7 +179,6 @@ namespace mRemoteNG.Container
|
||||
var newContainer = new ContainerInfo();
|
||||
newContainer.CopyFrom(this);
|
||||
newContainer.ConstantID = MiscTools.CreateConstantID();
|
||||
newContainer.SetParent(Parent);
|
||||
newContainer.OpenConnections = new ProtocolList();
|
||||
newContainer.Inheritance = Inheritance.Clone();
|
||||
foreach (var child in Children.ToArray())
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -33,7 +33,7 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
[assembly: AssemblyVersion("1.75.7001.*")]
|
||||
[assembly: AssemblyVersion("1.75.7007.*")]
|
||||
|
||||
[assembly:NeutralResourcesLanguageAttribute("en")]
|
||||
|
||||
|
||||
Binary file not shown.
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.UI.Forms;
|
||||
|
||||
|
||||
@@ -114,7 +115,7 @@ namespace mRemoteNG.Tools
|
||||
private void ConMenItem_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button != MouseButtons.Left) return;
|
||||
if (!(((ToolStripMenuItem) sender).Tag is ConnectionInfo)) return;
|
||||
if (((ToolStripMenuItem)sender).Tag is ContainerInfo) return;
|
||||
if (frmMain.Default.Visible == false)
|
||||
ShowForm();
|
||||
_connectionInitiator.OpenConnection((ConnectionInfo) ((ToolStripMenuItem) sender).Tag);
|
||||
|
||||
@@ -1,54 +1,92 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
using mRemoteNG.App;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
// ReSharper disable MemberCanBeMadeStatic.Global
|
||||
|
||||
namespace mRemoteNG.Tools
|
||||
{
|
||||
public class SystemMenu
|
||||
{
|
||||
public sealed class SystemMenu : SafeHandleZeroOrMinusOneIsInvalid, IDisposable
|
||||
{
|
||||
[Flags]
|
||||
public enum Flags
|
||||
{
|
||||
MF_STRING = App.NativeMethods.MF_STRING,
|
||||
MF_SEPARATOR = App.NativeMethods.MF_SEPARATOR,
|
||||
MF_BYCOMMAND = App.NativeMethods.MF_BYCOMMAND,
|
||||
MF_BYPOSITION = App.NativeMethods.MF_BYPOSITION,
|
||||
MF_POPUP = App.NativeMethods.MF_POPUP,
|
||||
WM_SYSCOMMAND = App.NativeMethods.WM_SYSCOMMAND
|
||||
MF_STRING = NativeMethods.MF_STRING,
|
||||
MF_SEPARATOR = NativeMethods.MF_SEPARATOR,
|
||||
MF_BYCOMMAND = NativeMethods.MF_BYCOMMAND,
|
||||
MF_BYPOSITION = NativeMethods.MF_BYPOSITION,
|
||||
MF_POPUP = NativeMethods.MF_POPUP,
|
||||
WM_SYSCOMMAND = NativeMethods.WM_SYSCOMMAND
|
||||
}
|
||||
|
||||
public IntPtr SystemMenuHandle;
|
||||
public IntPtr FormHandle;
|
||||
|
||||
public SystemMenu(IntPtr Handle)
|
||||
|
||||
private bool disposed;
|
||||
internal IntPtr SystemMenuHandle;
|
||||
private readonly IntPtr FormHandle;
|
||||
|
||||
public SystemMenu(IntPtr Handle) :base(true)
|
||||
{
|
||||
FormHandle = Handle;
|
||||
SystemMenuHandle = App.NativeMethods.GetSystemMenu(FormHandle, false);
|
||||
}
|
||||
SystemMenuHandle = NativeMethods.GetSystemMenu(FormHandle, false);
|
||||
SetHandle(SystemMenuHandle);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
SystemMenuHandle = App.NativeMethods.GetSystemMenu(FormHandle, true);
|
||||
SystemMenuHandle = NativeMethods.GetSystemMenu(FormHandle, true);
|
||||
}
|
||||
|
||||
public void AppendMenuItem(IntPtr ParentMenu, Flags Flags, IntPtr ID, string Text)
|
||||
{
|
||||
App.NativeMethods.AppendMenu(ParentMenu, (int)Flags, ID, Text);
|
||||
NativeMethods.AppendMenu(ParentMenu, (int)Flags, ID, Text);
|
||||
}
|
||||
|
||||
public IntPtr CreatePopupMenuItem()
|
||||
{
|
||||
return App.NativeMethods.CreatePopupMenu();
|
||||
return NativeMethods.CreatePopupMenu();
|
||||
}
|
||||
|
||||
public bool InsertMenuItem(IntPtr SysMenu, int Position, Flags Flags, IntPtr SubMenu, string Text)
|
||||
{
|
||||
return App.NativeMethods.InsertMenu(SysMenu, Position, (int)Flags, SubMenu, Text);
|
||||
return NativeMethods.InsertMenu(SysMenu, Position, (int)Flags, SubMenu, Text);
|
||||
}
|
||||
|
||||
public IntPtr SetBitmap(IntPtr Menu, int Position, Flags Flags, Bitmap Bitmap)
|
||||
{
|
||||
return new IntPtr(Convert.ToInt32(App.NativeMethods.SetMenuItemBitmaps(Menu, Position, (int)Flags, Bitmap.GetHbitmap(), Bitmap.GetHbitmap())));
|
||||
return new IntPtr(Convert.ToInt32(NativeMethods.SetMenuItemBitmaps(Menu, Position, (int)Flags, Bitmap.GetHbitmap(), Bitmap.GetHbitmap())));
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return NativeMethods.CloseHandle(SystemMenuHandle);
|
||||
}
|
||||
|
||||
|
||||
/* If we don't have the finalizer, then we get this warning: https://msdn.microsoft.com/library/ms182329.aspx (CA2216: Disposable types should declare finalizer)
|
||||
* If we DO have the finalizer, then we get this warning: https://msdn.microsoft.com/library/ms244737.aspx (CA1063: Implement IDisposable correctly)
|
||||
*
|
||||
* Since the handle is likely going to be in use for the entierty of the process, the finalizer isn't very important since when we're calling it
|
||||
* the process is likely exiting. Leaks would be moot once it exits. CA2216 is the lesser of 2 evils as far as I can tell. Suppress.
|
||||
~SystemMenu()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
*/
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2216:DisposableTypesShouldDeclareFinalizer")]
|
||||
public new void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed) return;
|
||||
if (!disposing) return;
|
||||
|
||||
ReleaseHandle();
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,11 +63,6 @@ namespace mRemoteNG.Tree
|
||||
connectionInfo?.RemoveParent();
|
||||
}
|
||||
|
||||
public void CloneNode(ConnectionInfo connectionInfo)
|
||||
{
|
||||
connectionInfo.Clone();
|
||||
}
|
||||
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
private void RaiseCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs args)
|
||||
{
|
||||
|
||||
@@ -717,7 +717,11 @@ namespace mRemoteNG.UI.Controls
|
||||
|
||||
private void OnImportFileClicked(object sender, EventArgs e)
|
||||
{
|
||||
var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo ?? _connectionTree.SelectedNode.Parent;
|
||||
ContainerInfo selectedNodeAsContainer;
|
||||
if (_connectionTree.SelectedNode == null)
|
||||
selectedNodeAsContainer = Runtime.ConnectionTreeModel.RootNodes.First();
|
||||
else
|
||||
selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo ?? _connectionTree.SelectedNode.Parent;
|
||||
Import.ImportFromFile(selectedNodeAsContainer);
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +215,7 @@ namespace mRemoteNG.UI.Controls
|
||||
public void DuplicateSelectedNode()
|
||||
{
|
||||
var newNode = SelectedNode.Clone();
|
||||
SelectedNode.Parent.AddChildBelow(newNode, SelectedNode);
|
||||
newNode.Parent.SetChildBelow(newNode, SelectedNode);
|
||||
Runtime.SaveConnectionsAsync();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace mRemoteNG.UI.Window
|
||||
this.lblEdition = new System.Windows.Forms.Label();
|
||||
this.pbLogo = new System.Windows.Forms.PictureBox();
|
||||
this.pnlBottom = new System.Windows.Forms.Panel();
|
||||
this.verText = new System.Windows.Forms.TextBox();
|
||||
this.lblCredits = new System.Windows.Forms.Label();
|
||||
this.txtCredits = new System.Windows.Forms.TextBox();
|
||||
this.txtChangeLog = new System.Windows.Forms.TextBox();
|
||||
@@ -41,7 +42,6 @@ namespace mRemoteNG.UI.Window
|
||||
this.lblChangeLog = new System.Windows.Forms.Label();
|
||||
this.lblLicense = new System.Windows.Forms.Label();
|
||||
this.lblCopyright = new System.Windows.Forms.Label();
|
||||
this.verText = new System.Windows.Forms.TextBox();
|
||||
this.pnlTop.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pbLogo)).BeginInit();
|
||||
this.pnlBottom.SuspendLayout();
|
||||
@@ -105,6 +105,18 @@ namespace mRemoteNG.UI.Window
|
||||
this.pnlBottom.Size = new System.Drawing.Size(1121, 559);
|
||||
this.pnlBottom.TabIndex = 1;
|
||||
//
|
||||
// verText
|
||||
//
|
||||
this.verText.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.verText.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.verText.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.verText.Location = new System.Drawing.Point(69, 51);
|
||||
this.verText.Name = "verText";
|
||||
this.verText.Size = new System.Drawing.Size(147, 20);
|
||||
this.verText.TabIndex = 12;
|
||||
this.verText.TabStop = false;
|
||||
this.verText.Text = "w.x.y.z";
|
||||
//
|
||||
// lblCredits
|
||||
//
|
||||
this.lblCredits.AutoSize = true;
|
||||
@@ -119,6 +131,8 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// txtCredits
|
||||
//
|
||||
this.txtCredits.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.txtCredits.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.txtCredits.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.txtCredits.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
@@ -136,6 +150,9 @@ namespace mRemoteNG.UI.Window
|
||||
//
|
||||
// txtChangeLog
|
||||
//
|
||||
this.txtChangeLog.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.txtChangeLog.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.txtChangeLog.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.txtChangeLog.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
@@ -211,18 +228,6 @@ namespace mRemoteNG.UI.Window
|
||||
this.lblCopyright.Text = "Copyright";
|
||||
this.lblCopyright.UseCompatibleTextRendering = true;
|
||||
//
|
||||
// verText
|
||||
//
|
||||
this.verText.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.verText.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.verText.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.verText.Location = new System.Drawing.Point(69, 51);
|
||||
this.verText.Name = "verText";
|
||||
this.verText.Size = new System.Drawing.Size(147, 20);
|
||||
this.verText.TabIndex = 12;
|
||||
this.verText.TabStop = false;
|
||||
this.verText.Text = "w.x.y.z";
|
||||
//
|
||||
// AboutWindow
|
||||
//
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
@@ -251,7 +256,8 @@ namespace mRemoteNG.UI.Window
|
||||
public AboutWindow(DockContent Panel)
|
||||
{
|
||||
WindowType = WindowType.About;
|
||||
DockPnl = Panel;
|
||||
DockPnl = Panel;
|
||||
DockPnl = new DockContent();
|
||||
InitializeComponent();
|
||||
Runtime.FontOverride(this);
|
||||
}
|
||||
|
||||
@@ -1248,44 +1248,19 @@
|
||||
<Reference Include="mscorlib" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell -noprofile -command "sleep 2"
|
||||
call "$(DevEnvDir)..\tools\vsvars32.bat"
|
||||
set /p buildenv=<buildenv.tmp
|
||||
|
||||
echo Copy PUTTYNG to correct directory
|
||||
copy /Y "$(SolutionDir)mRemoteV1\Resources\PuTTYNG.exe" .\
|
||||
|
||||
echo Move Help files to correct directory
|
||||
IF EXIST Help (
|
||||
del /s /q Help >NUL
|
||||
rmdir /s /q Help >NUL
|
||||
)
|
||||
move /Y Resources\Help .\
|
||||
<PostBuildEvent>:: When passing paths to powershell scripts, check if the path ends with a backslash "\"
|
||||
:: If it does, then the backslash may be interpreted as an escape character. Add another backslash to cancel the first one.
|
||||
|
||||
powershell -noprofile -command "sleep 2"
|
||||
rmdir /s /q Resources >NUL
|
||||
set /p buildenv=<buildenv.tmp
|
||||
set solutionDir=$(SolutionDir)\
|
||||
set targetDir=%25cd%25
|
||||
set psScriptsDir=$(SolutionDir)Tools
|
||||
set certPath=$(CertPath)
|
||||
set certPassword=$(CertPassword)
|
||||
|
||||
echo Set LargeAddressAware on binary
|
||||
editbin /largeaddressaware mRemoteNG.exe
|
||||
|
||||
|
||||
IF EXIST C:\mRemoteNG_code_signing_cert.pfx (
|
||||
echo Signing binaries
|
||||
IF %25buildenv: Portable=%25==Release (
|
||||
powershell "&""$(SolutionDir)Tools\signfiles.ps1""" '%25cd%25'
|
||||
)
|
||||
)
|
||||
|
||||
IF %25buildenv: Portable=%25==Release (
|
||||
echo Remove unnecessary files from Release versions
|
||||
rmdir /s /q app.publish
|
||||
del /q *.pdb *.publish *.xml *.backup *.log *vshost* *.tmp
|
||||
)
|
||||
|
||||
IF %25buildenv: =%25==ReleasePortable (
|
||||
echo Package ZIP Release Portable
|
||||
"$(SolutionDir)Tools\build-relport.cmd"
|
||||
)</PostBuildEvent>
|
||||
:: Call the post build powershell script
|
||||
powershell.exe -ExecutionPolicy Bypass -File "%25psScriptsDir%25\postbuild_mremotev1.ps1" -SolutionDir "%25solutionDir%25" -TargetDir "%25targetDir%25" -TargetFileName "mRemoteNG.exe" -ConfigurationName "%25buildenv%25" -CertificatePath "%25certPath%25" -CertificatePassword "%25certPassword%25" -ExcludeFromSigning "PuTTYNG.exe"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
||||
Reference in New Issue
Block a user