mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-19 23:29:45 +08:00
Compare commits
192 Commits
v1.75Beta2
...
v1.75Hotfi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
3eb96ef765 | ||
|
|
8805584cbe | ||
|
|
be5c66bd93 | ||
|
|
5347e5a3aa | ||
|
|
9b22254b6c | ||
|
|
6a67e0ea8b | ||
|
|
7b118995ea | ||
|
|
35b4564644 | ||
|
|
30df947365 | ||
|
|
b1ec975612 | ||
|
|
1034e434c4 | ||
|
|
f419bff545 | ||
|
|
69eec0135e | ||
|
|
2849baf857 | ||
|
|
768fdcd0e4 | ||
|
|
9b38308ad1 | ||
|
|
afcdf96e5c | ||
|
|
3e40b08525 | ||
|
|
237cf037be | ||
|
|
2445c74638 | ||
|
|
6a69ed48a9 | ||
|
|
217693937f | ||
|
|
22300577cf | ||
|
|
6a07f4e731 | ||
|
|
63ace60dcc | ||
|
|
601951582d | ||
|
|
9250dde5b0 | ||
|
|
29ca72d8ca | ||
|
|
87c89a0de5 | ||
|
|
73f72e39d3 | ||
|
|
e00ba62606 | ||
|
|
48d53cecce | ||
|
|
e0fd81e938 | ||
|
|
04f6f4f9cf | ||
|
|
25d1e0a74d | ||
|
|
cbd9d16e4c | ||
|
|
cb708b3217 | ||
|
|
4e5a22a7e8 | ||
|
|
3722db93c6 | ||
|
|
b43331dc27 | ||
|
|
80c6ce81e1 | ||
|
|
1a776359c4 | ||
|
|
113e4035e5 | ||
|
|
a03095ab8e | ||
|
|
d03f830622 | ||
|
|
9b42dc9f10 | ||
|
|
fd7adf3c64 | ||
|
|
d0b7e72f15 | ||
|
|
5a61c6b7df | ||
|
|
c897eae04e | ||
|
|
c33095cd0e | ||
|
|
05d8b7983a | ||
|
|
166d9f7133 | ||
|
|
2ce31f35cc | ||
|
|
ce5d0cefe3 | ||
|
|
6cc668fe83 | ||
|
|
ac0aa8daf4 | ||
|
|
16b094be44 | ||
|
|
b3e6fd7b96 | ||
|
|
893d5d92f3 | ||
|
|
77add0b39d | ||
|
|
b4f8ab0a49 | ||
|
|
1d46c44c21 | ||
|
|
12da35f875 | ||
|
|
8970a15d4e | ||
|
|
82217478d9 | ||
|
|
4c792308bb | ||
|
|
978d94a2cd | ||
|
|
b195d89b76 | ||
|
|
875888a341 | ||
|
|
6631a13d20 | ||
|
|
28728fe29f | ||
|
|
aa954cbea9 | ||
|
|
dae339f494 | ||
|
|
5bcb59f876 | ||
|
|
9132592fd7 | ||
|
|
ca592fac77 | ||
|
|
ea657824c2 | ||
|
|
99e7072e27 | ||
|
|
ad32f4a0a3 | ||
|
|
b9cdd0996d | ||
|
|
e92a76f95b | ||
|
|
10d152342f | ||
|
|
7e4b0635b2 | ||
|
|
eec17f10d5 | ||
|
|
ac9d5dfa95 | ||
|
|
4c2b3738c2 | ||
|
|
6f29183b45 | ||
|
|
dd65c9c588 | ||
|
|
cb8bb05627 | ||
|
|
256f6d8fdd | ||
|
|
a88fdddecb | ||
|
|
fd5e3e24df | ||
|
|
244d27427d | ||
|
|
55c42a3cca | ||
|
|
3c9cfbdf92 | ||
|
|
46dd58d26e | ||
|
|
051dd2e567 | ||
|
|
17ccf40082 | ||
|
|
0f2b61694d | ||
|
|
0aed66df47 | ||
|
|
94a6e9a886 | ||
|
|
355f48b6ba | ||
|
|
d1a6526c22 | ||
|
|
975a308647 | ||
|
|
5138eaeb68 | ||
|
|
45dfaa1b21 | ||
|
|
715f92f3d5 | ||
|
|
8d5a765040 | ||
|
|
34fa6b158b | ||
|
|
78c1f6b8e3 | ||
|
|
adccb91106 | ||
|
|
1e213dfff7 | ||
|
|
d469fa1d40 | ||
|
|
737db469ba | ||
|
|
a44a33d508 | ||
|
|
a518d41c78 | ||
|
|
d5360c6568 | ||
|
|
d468107311 | ||
|
|
3f65e1bfa0 | ||
|
|
a22758f5cd | ||
|
|
88b5b9d1e7 | ||
|
|
e38f7c880e | ||
|
|
6367b58994 | ||
|
|
5a54b5ee64 | ||
|
|
002e41f418 | ||
|
|
f7787c748a | ||
|
|
f9b18b45a4 | ||
|
|
8966f44272 | ||
|
|
3dbcbae61f | ||
|
|
24508abe7a | ||
|
|
27f8f2542e | ||
|
|
44ee3ceec8 | ||
|
|
b08112aec0 | ||
|
|
9d2bbda2b9 | ||
|
|
6eff685b18 | ||
|
|
2d08146de8 | ||
|
|
f131420a44 | ||
|
|
245ea5463e |
103
CHANGELOG.TXT
103
CHANGELOG.TXT
@@ -1,3 +1,96 @@
|
||||
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
|
||||
|
||||
|
||||
1.75 hotfix 1 (2017-03-06):
|
||||
|
||||
General Changes:
|
||||
----------------
|
||||
#437: Modify version numbering scheme
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#422: Uncaught exception when clicking in connection tree whitespace
|
||||
#312: Resolved KeePass auto-type issue
|
||||
#427: Export does not respect filtering user/password/domain
|
||||
|
||||
|
||||
1.75 (2017-03-01):
|
||||
|
||||
Known Issue:
|
||||
------------
|
||||
File hash check will fail when updating from 1.75 Beta 1 to newer versions.
|
||||
Exception will be: "MD5 Hashes didn't match!" for 1.75 Beta 1 - 1.75 RC1
|
||||
|
||||
|
||||
Features/Enhancements:
|
||||
----------------------
|
||||
#344 - Use SHA512 File Hashes to validate downloads (in the update mechanism & posted to the Downloads page)
|
||||
|
||||
|
||||
1.75 RC1 (2017-01-27):
|
||||
|
||||
Known Issue:
|
||||
------------
|
||||
Portable build MD5 check will fail when updating from 1.75 Beta 1 to newer versions.
|
||||
|
||||
|
||||
Features/Enhancements:
|
||||
----------------------
|
||||
Added Release Channels to the update check functionality allowing users to select one of 3 release channels for updates: Stable, Beta, Dev
|
||||
#360: Help -> About, Version # is now selectable/copyable
|
||||
#221: RDP: Optional disconnect after X number of minutes of inactivity
|
||||
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#369: Reset Layout Option Does Not Reset Notification Pane
|
||||
#362: Invalid cast exception when using the Notification Area Icon minimize/restore
|
||||
#334: Quick Connect displays warning when clicking on a folder
|
||||
#325: When using a connection with an external app, results in opening the same external app continuously
|
||||
#311: Import from Active Directory does not use machine's domain by default
|
||||
#258: Rename Tab dialog - populate original name in dialog (1.72 functionality)
|
||||
#211, #267: Recursive AD Import wasn't fully functional
|
||||
|
||||
|
||||
General Changes:
|
||||
----------------
|
||||
The usual general code clean up and refactoring
|
||||
#325: Code clean up and additional logging for External Tools based connections
|
||||
#298: Code clean up and additional logging around application startup
|
||||
#291, #236: External Tools code clean up and additional logging
|
||||
|
||||
|
||||
|
||||
1.75 Beta 3 (2016-12-01):
|
||||
|
||||
Known Issue:
|
||||
------------
|
||||
Portable build MD5 check will fail when updating from 1.75 Beta 1 to newer versions.
|
||||
|
||||
|
||||
Fixes:
|
||||
------
|
||||
#289: Install fails during update process (only affects v1.75 beta 1 - v1.75 beta 2)
|
||||
|
||||
|
||||
1.75 Beta 2 (2016-12-01):
|
||||
|
||||
Features/Enhancements:
|
||||
@@ -10,7 +103,7 @@ Fixes:
|
||||
------
|
||||
#254: Component check window position issues and uncaught exception
|
||||
#260: Crash when attempting to load fully encrypted confCons v2.5
|
||||
#261: Double clicking folder in treeview doesnt expand it in 1.75 beta1
|
||||
#261: Double clicking folder in treeview doesn't expand it in 1.75 beta1
|
||||
#271: Install package is not using the last installation path
|
||||
#278: Silent installs not detecting prerequisites
|
||||
|
||||
@@ -54,7 +147,7 @@ Fixes:
|
||||
MR-965, MR-871, MR-629: Error 264 on RDP Connect attempt - Added timeout value to Tools -> Options -> Connections
|
||||
MR-946: Remove old/insecure SharpSSH and related components. Replace with SSH.NET for File Transfer Functionality
|
||||
MR-896: Added prerequisite installer check for KB2574819. Prevents "Class not registered" errors when opening RDP connections.
|
||||
PR-130: Fix Scan button width to fit russian translation
|
||||
PR-130: Fix Scan button width to fit Russian translation
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +155,7 @@ PR-130: Fix Scan button width to fit russian translation
|
||||
|
||||
General Changes:
|
||||
----------------
|
||||
Updated GeckoFx pacakge
|
||||
Updated GeckoFx package
|
||||
Updated DockPanelSuite library to 2.10 Final
|
||||
Japanese translation updated
|
||||
MR-942: Refactored code relating to loading the connections file
|
||||
@@ -137,7 +230,7 @@ Port Scan is now Asynchronous (and is significantly faster)
|
||||
Fixes:
|
||||
------
|
||||
MR-874: Added work-around to installer to ignore installation prerequisites
|
||||
MR-884: Slow startup in some scnearios checking authenticode certificate
|
||||
MR-884: Slow startup in some scenarios checking authenticode certificate
|
||||
MR-872: Crash in External Tools when arguments aren't quoted
|
||||
MR-854: crashes when right clicking on connection tab
|
||||
MR-852: Option "Allow only a single instance of the application" non-functional
|
||||
@@ -278,7 +371,7 @@ Fixed issue MR-398 - Full Screen mode doesn't correctly make use of available sp
|
||||
Fixed issue MR-402 - scrollbar touch moves putty window
|
||||
Fixed issue MR-406 - Items disappear from External Tools toolbar when accessing External Tools panel
|
||||
Fixed issue MR-410 - Unhandled exception when clicking New button under Theme
|
||||
Fixed issue MR-413 - Can't use aplication
|
||||
Fixed issue MR-413 - Can't use application
|
||||
Fixed new connections having a globe icon.
|
||||
Fixed the category names in the themes tab of the options dialog on Windows XP not showing correctly.
|
||||
Fixed PuTTY saved sessions with spaces or special characters not being listed.
|
||||
|
||||
@@ -8,9 +8,12 @@ Sean Kaim (github.com/kmscode)
|
||||
Thanks for the awesome new website!
|
||||
Bennett Blodinger (github.com/benwa)
|
||||
|
||||
Joe Cefoli (github.com/jcefoli)
|
||||
countchappy (github.com/countchappy)
|
||||
Tony Lambert
|
||||
|
||||
|
||||
|
||||
Past Contributors
|
||||
=================
|
||||
|
||||
|
||||
@@ -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
Jenkinsfile
vendored
6
Jenkinsfile
vendored
@@ -5,11 +5,7 @@ node('windows') {
|
||||
def vsExtensionsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow"
|
||||
|
||||
stage 'Checkout Branch'
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
checkout scm
|
||||
|
||||
stage 'Restore NuGet Packages'
|
||||
def nugetPath = "C:\\nuget.exe"
|
||||
|
||||
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: '*/${env.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\\*.msi"
|
||||
def msiPath = "${jobDir}\\Release\\*.zip"
|
||||
// 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
22
README.MD
22
README.MD
@@ -1,16 +1,20 @@
|
||||
# Welcome to the mRemoteNG project!
|
||||
|
||||
[](https://twitter.com/intent/follow?screen_name=mRemoteNG)
|
||||
|
||||
|
||||
[](https://gitter.im/mRemoteNG/PublicChat)
|
||||
|
||||
[](https://www.paypal.me/DavidSparer)
|
||||
|
||||
[](http://ec2-52-39-111-114.us-west-2.compute.amazonaws.com:8080/job/mRemoteNG/job/mRemoteNG/job/develop/)
|
||||
[](https://waffle.io/mRemoteNG/mRemoteNG)
|
||||
[](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.74)
|
||||
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/529)
|
||||
|
||||
[](https://waffle.io/mRemoteNG/mRemoteNG)
|
||||
|
||||
| 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) |
|
||||
| Development | [](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/develop/) | - |
|
||||
|
||||
|
||||
|
||||
mRemoteNG is the next generation of mRemote, a full-featured, multi-tab remote connections manager.
|
||||
|
||||
@@ -36,8 +40,8 @@ https://support.microsoft.com/en-us/kb/2923545
|
||||
|
||||
Windows 8+ support RDP version 8+ out of the box.
|
||||
|
||||
RDP versions are backwards compatible, so an mRemoteNG client running on Windows 10 can connection successfully to a Windows 2003 host (for example).
|
||||
RDP versions are backwards compatible, so an mRemoteNG client running on Windows 10 can connect successfully to a Windows 2003 host (for example).
|
||||
|
||||
|
||||
|
||||
[](https://www.jetbrains.com/resharper/)
|
||||
[](https://www.jetbrains.com/resharper/)
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#Requires -Version 4.0
|
||||
|
||||
$releaseFolder = Join-Path -Path $PSScriptRoot -ChildPath "..\Release" -Resolve
|
||||
$tag = Read-Host -Prompt 'Tag name'
|
||||
|
||||
Write-Host
|
||||
@@ -8,7 +9,7 @@ Write-Host
|
||||
|
||||
Write-Host PORTABLE
|
||||
Write-Host --------
|
||||
$file = gci ..\Release\*.zip | sort LastWriteTime | select -last 1 | % { $_.FullName }
|
||||
$file = Get-ChildItem -Path "$releaseFolder\*.zip" | sort LastWriteTime | select -last 1 | % { $_.FullName }
|
||||
$filename = $file.Split("\") | select -last 1
|
||||
|
||||
$version = $file.tostring().Split("-")[2].trim(".zip")
|
||||
@@ -17,7 +18,7 @@ Write-Host Version: $version
|
||||
Write-Host dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/$tag/$filename
|
||||
Write-Host clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/$tag/CHANGELOG.TXT
|
||||
|
||||
$hash = Get-FileHash -Algorithm MD5 $file | % { $_.Hash }
|
||||
$hash = Get-FileHash -Algorithm SHA512 $file | % { $_.Hash }
|
||||
Write-Host Checksum: $hash
|
||||
|
||||
|
||||
@@ -27,7 +28,7 @@ Write-Host
|
||||
|
||||
Write-Host MSI
|
||||
Write-Host ---
|
||||
$file = gci ..\Release\*.msi | sort LastWriteTime | select -last 1 | % { $_.FullName }
|
||||
$file = Get-ChildItem -Path "$releaseFolder\*.msi" | sort LastWriteTime | select -last 1 | % { $_.FullName }
|
||||
$filename = $file.Split("\") | select -last 1
|
||||
|
||||
$version = $file.tostring().Split("-")[2].trim(".msi")
|
||||
@@ -37,5 +38,5 @@ Write-Host dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/$tag/$
|
||||
Write-Host clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/$tag/CHANGELOG.TXT
|
||||
|
||||
Write-Host CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
$hash = Get-FileHash -Algorithm MD5 $file | % { $_.Hash }
|
||||
$hash = Get-FileHash -Algorithm SHA512 $file | % { $_.Hash }
|
||||
Write-Host Checksum: $hash
|
||||
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
|
||||
168
Tools/publish_to_github.ps1
Normal file
168
Tools/publish_to_github.ps1
Normal file
@@ -0,0 +1,168 @@
|
||||
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 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 "binary/octetstream" -AuthToken $AuthToken
|
||||
Write-Output $release
|
||||
@@ -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 ""
|
||||
84
mRemoteNGTests/App/UpdaterTests.cs
Normal file
84
mRemoteNGTests/App/UpdaterTests.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.App.Update;
|
||||
using mRemoteNGTests.Properties;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.App
|
||||
{
|
||||
[TestFixture]
|
||||
public class UpdaterTests
|
||||
{
|
||||
[Test]
|
||||
public void UpdateStableChannel()
|
||||
{
|
||||
GeneralAppInfo.ApplicationVersion = "1.0.0.0";
|
||||
var CurrentUpdateInfo = UpdateInfo.FromString(Resources.update);
|
||||
Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True);
|
||||
Version v;
|
||||
Version.TryParse(GeneralAppInfo.ApplicationVersion, out v);
|
||||
var IsNewer = CurrentUpdateInfo.Version > v;
|
||||
Assert.That(IsNewer, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateBetaChannel()
|
||||
{
|
||||
GeneralAppInfo.ApplicationVersion = "1.0.0.0";
|
||||
var CurrentUpdateInfo = UpdateInfo.FromString(Resources.beta_update);
|
||||
Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True);
|
||||
Version v;
|
||||
Version.TryParse(GeneralAppInfo.ApplicationVersion, out v);
|
||||
var IsNewer = CurrentUpdateInfo.Version > v;
|
||||
Assert.That(IsNewer, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateDevChannel()
|
||||
{
|
||||
GeneralAppInfo.ApplicationVersion = "1.0.0.0";
|
||||
var CurrentUpdateInfo = UpdateInfo.FromString(Resources.dev_update);
|
||||
Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True);
|
||||
Version v;
|
||||
Version.TryParse(GeneralAppInfo.ApplicationVersion, out v);
|
||||
var IsNewer = CurrentUpdateInfo.Version > v;
|
||||
Assert.That(IsNewer, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateStablePortableChannel()
|
||||
{
|
||||
GeneralAppInfo.ApplicationVersion = "1.0.0.0";
|
||||
var CurrentUpdateInfo = UpdateInfo.FromString(Resources.update_portable);
|
||||
Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True);
|
||||
Version v;
|
||||
Version.TryParse(GeneralAppInfo.ApplicationVersion, out v);
|
||||
var IsNewer = CurrentUpdateInfo.Version > v;
|
||||
Assert.That(IsNewer, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateBetaPortableChannel()
|
||||
{
|
||||
GeneralAppInfo.ApplicationVersion = "1.0.0.0";
|
||||
var CurrentUpdateInfo = UpdateInfo.FromString(Resources.beta_update_portable);
|
||||
Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True);
|
||||
Version v;
|
||||
Version.TryParse(GeneralAppInfo.ApplicationVersion, out v);
|
||||
var IsNewer = CurrentUpdateInfo.Version > v;
|
||||
Assert.That(IsNewer, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateDevPortableChannel()
|
||||
{
|
||||
GeneralAppInfo.ApplicationVersion = "1.0.0.0";
|
||||
var CurrentUpdateInfo = UpdateInfo.FromString(Resources.dev_update_portable);
|
||||
Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True);
|
||||
Version v;
|
||||
Version.TryParse(GeneralAppInfo.ApplicationVersion, out v);
|
||||
var IsNewer = CurrentUpdateInfo.Version > v;
|
||||
Assert.That(IsNewer, Is.True);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,14 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
public class XmlConnectionNodeSerializerTests
|
||||
{
|
||||
private XmlConnectionNodeSerializer _connectionNodeSerializer;
|
||||
private ICryptographyProvider _cryptographyProvider;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(
|
||||
_cryptographyProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(
|
||||
BlockCipherEngines.AES, BlockCipherModes.GCM);
|
||||
_connectionNodeSerializer = new XmlConnectionNodeSerializer(cryptoProvider, "myPassword1".ConvertToSecureString());
|
||||
_connectionNodeSerializer = new XmlConnectionNodeSerializer(_cryptographyProvider, "myPassword1".ConvertToSecureString(), new SaveFilter());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -48,8 +49,7 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
public void AttributesNotSerializedWhenFiltered(string attributeName, ConnectionInfo connectionInfo)
|
||||
{
|
||||
var saveFilter = new SaveFilter(true);
|
||||
var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM);
|
||||
_connectionNodeSerializer = new XmlConnectionNodeSerializer(cryptoProvider, "myPassword1".ConvertToSecureString(), saveFilter);
|
||||
_connectionNodeSerializer = new XmlConnectionNodeSerializer(_cryptographyProvider, "myPassword1".ConvertToSecureString(), saveFilter);
|
||||
var returnVal = _connectionNodeSerializer.SerializeConnectionInfo(connectionInfo);
|
||||
var targetAttribute = returnVal.Attribute(XName.Get(attributeName));
|
||||
Assert.That(targetAttribute?.Value, Is.EqualTo(string.Empty));
|
||||
@@ -59,8 +59,7 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
public void InheritanceNotSerialiedWhenFiltered(string attributeName, ConnectionInfo connectionInfo)
|
||||
{
|
||||
var saveFilter = new SaveFilter(true);
|
||||
var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM);
|
||||
_connectionNodeSerializer = new XmlConnectionNodeSerializer(cryptoProvider, "myPassword1".ConvertToSecureString(), saveFilter);
|
||||
_connectionNodeSerializer = new XmlConnectionNodeSerializer(_cryptographyProvider, "myPassword1".ConvertToSecureString(), saveFilter);
|
||||
var returnVal = _connectionNodeSerializer.SerializeConnectionInfo(connectionInfo);
|
||||
var targetAttribute = returnVal.Attribute(XName.Get(attributeName));
|
||||
Assert.That(targetAttribute?.Value, Is.EqualTo(false.ToString()));
|
||||
|
||||
@@ -28,7 +28,8 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
public void Setup()
|
||||
{
|
||||
_cryptographyProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM);
|
||||
_documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider);
|
||||
var saveFilter = new SaveFilter();
|
||||
_documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider, saveFilter);
|
||||
_connectionTreeModel = SetupConnectionTreeModel();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
{
|
||||
var connectionTreeModel = SetupConnectionTreeModel();
|
||||
var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM);
|
||||
_originalDocument = new XmlConnectionsDocumentCompiler(cryptoProvider).CompileDocument(connectionTreeModel, false, false);
|
||||
var saveFilter = new SaveFilter();
|
||||
_originalDocument = new XmlConnectionsDocumentCompiler(cryptoProvider, saveFilter).CompileDocument(connectionTreeModel, false, false);
|
||||
_documentEncryptor = new XmlConnectionsDocumentEncryptor(cryptoProvider);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
@@ -45,6 +47,27 @@ namespace mRemoteNGTests.Config.Serializers
|
||||
Assert.That(connectionNode, Is.Not.Null);
|
||||
}
|
||||
|
||||
[TestCase("Username", "")]
|
||||
[TestCase("Domain", "")]
|
||||
[TestCase("Password", "")]
|
||||
[TestCase("InheritAutomaticResize", "False")]
|
||||
public void SerializerRespectsSaveFilterSettings(string attributeName, string expectedValue)
|
||||
{
|
||||
_serializer.SaveFilter = new SaveFilter(true);
|
||||
var connectionInfo = new ConnectionInfo
|
||||
{
|
||||
Name = "myConnection",
|
||||
Username = "somefilteredstuff",
|
||||
Domain = "somefilteredstuff",
|
||||
Password = "somefilteredstuff",
|
||||
Inheritance = {AutomaticResize = true}
|
||||
};
|
||||
var serializedConnections = _serializer.Serialize(connectionInfo);
|
||||
var xdoc = XDocument.Parse(serializedConnections);
|
||||
var attributeValue = xdoc.Root?.Element("Node")?.Attribute(attributeName)?.Value;
|
||||
Assert.That(attributeValue, Is.EqualTo(expectedValue));
|
||||
}
|
||||
|
||||
private ConnectionTreeModel SetupConnectionTreeModel()
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
@@ -30,5 +31,43 @@ namespace mRemoteNGTests.Connection
|
||||
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
|
||||
Assert.That(saveTarget.Domain, Is.EqualTo(_testDomain));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanSaveEnumValuesToString()
|
||||
{
|
||||
const ProtocolType targetProtocol = ProtocolType.RAW;
|
||||
var saveTarget = new AllStringPropertySaveTarget();
|
||||
DefaultConnectionInfo.Instance.Protocol = targetProtocol;
|
||||
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
|
||||
Assert.That(saveTarget.Protocol, Is.EqualTo(targetProtocol.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanSaveIntegerValuesToString()
|
||||
{
|
||||
const int targetValue = 123;
|
||||
var saveTarget = new AllStringPropertySaveTarget();
|
||||
DefaultConnectionInfo.Instance.RDPMinutesToIdleTimeout = targetValue;
|
||||
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
|
||||
Assert.That(saveTarget.RDPMinutesToIdleTimeout, Is.EqualTo(targetValue.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanSaveStringValuesToString()
|
||||
{
|
||||
const string targetName = "hello";
|
||||
var saveTarget = new AllStringPropertySaveTarget();
|
||||
DefaultConnectionInfo.Instance.Username = targetName;
|
||||
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
|
||||
Assert.That(saveTarget.Username, Is.EqualTo(targetName));
|
||||
}
|
||||
|
||||
|
||||
private class AllStringPropertySaveTarget
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string Protocol { get; set; }
|
||||
public string RDPMinutesToIdleTimeout { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
77
mRemoteNGTests/Properties/Resources.Designer.cs
generated
77
mRemoteNGTests/Properties/Resources.Designer.cs
generated
@@ -60,6 +60,32 @@ namespace mRemoteNGTests.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Version: 1.75.6164.27544
|
||||
///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi
|
||||
///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
///CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
///Checksum: A1E50ACAC4CB8023527E1E7A0E682459
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string beta_update {
|
||||
get {
|
||||
return ResourceManager.GetString("beta_update", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Version: 1.75.6170.27478
|
||||
///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip
|
||||
///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
///Checksum: 1C35EA199F58001BC4EBB164D8B3D11C.
|
||||
/// </summary>
|
||||
internal static string beta_update_portable {
|
||||
get {
|
||||
return ResourceManager.GetString("beta_update_portable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?>
|
||||
///<Connections Name="Connections" Export="False" Protected="95syzRuZ4mRxpNkZQzoyX8SDpQXLyMq3GncO8o4SyTBoYvn3TAWgn05ZEU2DrjkM" ConfVersion="2.5">
|
||||
@@ -142,6 +168,32 @@ namespace mRemoteNGTests.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Version: 1.75.6164.27544
|
||||
///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi
|
||||
///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
///CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
///Checksum: A1E50ACAC4CB8023527E1E7A0E682459
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string dev_update {
|
||||
get {
|
||||
return ResourceManager.GetString("dev_update", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Version: 1.75.6170.27478
|
||||
///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip
|
||||
///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
///Checksum: 1C35EA199F58001BC4EBB164D8B3D11C.
|
||||
/// </summary>
|
||||
internal static string dev_update_portable {
|
||||
get {
|
||||
return ResourceManager.GetString("dev_update_portable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-16"?>
|
||||
///<!-- ****************************************************************-->
|
||||
@@ -276,5 +328,30 @@ namespace mRemoteNGTests.Properties {
|
||||
return ResourceManager.GetString("test_remotedesktopconnection_rdp", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Version: 1.72.5065.32737
|
||||
///dURL: http://downloads.mremoteng.org/mRemoteNG-Installer-1.72.exe
|
||||
///clURL: http://update.mremoteng.org/changes-1.72.txt
|
||||
///CertificateThumbprint: 1cbd910dbd6e77f26506e7f600736972f700673f
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string update {
|
||||
get {
|
||||
return ResourceManager.GetString("update", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Version: 1.75.6170.27478
|
||||
///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip
|
||||
///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
///Checksum: 1C35EA199F58001BC4EBB164D8B3D11C.
|
||||
/// </summary>
|
||||
internal static string update_portable {
|
||||
get {
|
||||
return ResourceManager.GetString("update_portable", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,12 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="beta_update" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\beta-update.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="beta_update_portable" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\beta-update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="confCons_v2_5" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\confCons_v2_5.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
@@ -142,6 +148,12 @@
|
||||
<data name="confCons_v2_6_passwordis_Password_fullencryption" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\confCons_v2_6_passwordis_Password_fullencryption.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="dev_update" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\dev-update.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="dev_update_portable" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\dev-update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="test_puttyConnectionManager_database" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\test_puttyConnectionManager_database.dat;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
|
||||
</data>
|
||||
@@ -163,4 +175,10 @@
|
||||
<data name="test_remotedesktopconnection_rdp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\test_remotedesktopconnection.rdp;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
|
||||
</data>
|
||||
<data name="update" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\update.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="update_portable" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
</root>
|
||||
5
mRemoteNGTests/Resources/beta-update-portable.txt
Normal file
5
mRemoteNGTests/Resources/beta-update-portable.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Version: 1.75.6170.27478
|
||||
dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip
|
||||
clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
Checksum: 1C35EA199F58001BC4EBB164D8B3D11C
|
||||
5
mRemoteNGTests/Resources/beta-update.txt
Normal file
5
mRemoteNGTests/Resources/beta-update.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Version: 1.75.6164.27544
|
||||
dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi
|
||||
clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
Checksum: A1E50ACAC4CB8023527E1E7A0E682459
|
||||
5
mRemoteNGTests/Resources/dev-update-portable.txt
Normal file
5
mRemoteNGTests/Resources/dev-update-portable.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Version: 1.75.6170.27478
|
||||
dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip
|
||||
clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
Checksum: 1C35EA199F58001BC4EBB164D8B3D11C
|
||||
5
mRemoteNGTests/Resources/dev-update.txt
Normal file
5
mRemoteNGTests/Resources/dev-update.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Version: 1.75.6164.27544
|
||||
dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi
|
||||
clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
Checksum: A1E50ACAC4CB8023527E1E7A0E682459
|
||||
5
mRemoteNGTests/Resources/update-portable.txt
Normal file
5
mRemoteNGTests/Resources/update-portable.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Version: 1.75.6170.27478
|
||||
dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip
|
||||
clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
Checksum: 1C35EA199F58001BC4EBB164D8B3D11C
|
||||
5
mRemoteNGTests/Resources/update.txt
Normal file
5
mRemoteNGTests/Resources/update.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Version: 1.75.6164.27544
|
||||
dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi
|
||||
clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT
|
||||
CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA
|
||||
Checksum: A1E50ACAC4CB8023527E1E7A0E682459
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class ExpandNodeClickHandlerTests
|
||||
{
|
||||
private ExpandNodeClickHandler _clickHandler;
|
||||
private IConnectionTree _connectionTree;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_connectionTree = Substitute.For<IConnectionTree>();
|
||||
_clickHandler = new ExpandNodeClickHandler(_connectionTree);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TargetedNodeIsExpanded()
|
||||
{
|
||||
var folder = new ContainerInfo();
|
||||
_clickHandler.Execute(folder);
|
||||
_connectionTree.Received().ToggleExpansion(folder);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NothingHappensWhenConnectionInfoProvided()
|
||||
{
|
||||
_clickHandler.Execute(new ConnectionInfo());
|
||||
_connectionTree.DidNotReceiveWithAnyArgs().ToggleExpansion(new ConnectionInfo());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExceptionThrownOnConstructorNullArg()
|
||||
{
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
Assert.Throws<ArgumentNullException>(() => new ExpandNodeClickHandler(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class OpenConnectionClickHandlerTests
|
||||
{
|
||||
private OpenConnectionClickHandler _clickHandler;
|
||||
private IConnectionInitiator _connectionInitiator;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_connectionInitiator = Substitute.For<IConnectionInitiator>();
|
||||
_clickHandler = new OpenConnectionClickHandler(_connectionInitiator);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConnectionOpened()
|
||||
{
|
||||
var connectionInfo = new ConnectionInfo();
|
||||
_clickHandler.Execute(connectionInfo);
|
||||
_connectionInitiator.Received().OpenConnection(connectionInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoesNothingWhenGivenContainerInfo()
|
||||
{
|
||||
_clickHandler.Execute(new ContainerInfo());
|
||||
_connectionInitiator.DidNotReceiveWithAnyArgs().OpenConnection(new ConnectionInfo());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExceptionThrownWhenConstructorGivenNullArg()
|
||||
{
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
Assert.Throws<ArgumentNullException>(() => new OpenConnectionClickHandler(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowWhenExecuteGivenNullArg()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _clickHandler.Execute(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class SwitchToConnectionClickHandlerTests
|
||||
{
|
||||
private SwitchToConnectionClickHandler _clickHandler;
|
||||
private IConnectionInitiator _connectionInitiator;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_connectionInitiator = Substitute.For<IConnectionInitiator>();
|
||||
_clickHandler = new SwitchToConnectionClickHandler(_connectionInitiator);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SwitchesToConnection()
|
||||
{
|
||||
var connectionInfo = new ConnectionInfo();
|
||||
_clickHandler.Execute(connectionInfo);
|
||||
_connectionInitiator.Received().SwitchToOpenConnection(connectionInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoesNothingWhenGivenContainerInfo()
|
||||
{
|
||||
_clickHandler.Execute(new ContainerInfo());
|
||||
_connectionInitiator.DidNotReceiveWithAnyArgs().SwitchToOpenConnection(new ConnectionInfo());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExceptionThrownWhenConstructorGivenNullArg()
|
||||
{
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
Assert.Throws<ArgumentNullException>(() => new SwitchToConnectionClickHandler(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowWhenExecuteGivenNullArg()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _clickHandler.Execute(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Tree;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class TreeNodeCompositeClickHandlerTests
|
||||
{
|
||||
private TreeNodeCompositeClickHandler _clickHandler;
|
||||
private ConnectionInfo _connectionInfo;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_clickHandler = new TreeNodeCompositeClickHandler();
|
||||
_connectionInfo = new ConnectionInfo();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExecutesAllItsHandlers()
|
||||
{
|
||||
var handler1 = Substitute.For<ITreeNodeClickHandler>();
|
||||
var handler2 = Substitute.For<ITreeNodeClickHandler>();
|
||||
_clickHandler.ClickHandlers = new[] {handler1, handler2};
|
||||
_clickHandler.Execute(_connectionInfo);
|
||||
handler1.Received().Execute(_connectionInfo);
|
||||
handler2.Received().Execute(_connectionInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowWhenExecuteGivenNullArg()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _clickHandler.Execute(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
51
mRemoteNGTests/Tree/ConnectionTreeTests.cs
Normal file
51
mRemoteNGTests/Tree/ConnectionTreeTests.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Threading;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class ConnectionTreeTests
|
||||
{
|
||||
private ConnectionTree _connectionTree;
|
||||
private ConnectionTreeModel _connectionTreeModel;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_connectionTreeModel = CreateConnectionTreeModel();
|
||||
_connectionTree = new ConnectionTree
|
||||
{
|
||||
PostSetupActions = new IConnectionTreeDelegate[] {new RootNodeExpander()}
|
||||
};
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown()
|
||||
{
|
||||
_connectionTree.Dispose();
|
||||
}
|
||||
|
||||
|
||||
[Test, Apartment(ApartmentState.STA)]
|
||||
public void CanDeleteLastFolderInTheTree()
|
||||
{
|
||||
var lastFolder = new ContainerInfo();
|
||||
_connectionTreeModel.RootNodes[0].AddChild(lastFolder);
|
||||
_connectionTree.ConnectionTreeModel = _connectionTreeModel;
|
||||
_connectionTree.SelectObject(lastFolder);
|
||||
_connectionTree.DeleteSelectedNode();
|
||||
Assert.That(_connectionTree.GetRootConnectionNode().HasChildren, Is.False);
|
||||
}
|
||||
|
||||
private ConnectionTreeModel CreateConnectionTreeModel()
|
||||
{
|
||||
var connectionTreeModel = new ConnectionTreeModel();
|
||||
connectionTreeModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection));
|
||||
return connectionTreeModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
50
mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs
Normal file
50
mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class PreviousSessionOpenerTests
|
||||
{
|
||||
private PreviousSessionOpener _previousSessionOpener;
|
||||
private IConnectionInitiator _connectionInitiator;
|
||||
private IConnectionTree _connectionTree;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_connectionInitiator = Substitute.For<IConnectionInitiator>();
|
||||
_previousSessionOpener = new PreviousSessionOpener(_connectionInitiator);
|
||||
_connectionTree = Substitute.For<IConnectionTree>();
|
||||
_connectionTree.GetRootConnectionNode().Returns(BuildTree());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllRequestedSessionsAreReopened()
|
||||
{
|
||||
_previousSessionOpener.Execute(_connectionTree);
|
||||
_connectionInitiator.ReceivedWithAnyArgs(2).OpenConnection(new ConnectionInfo());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExceptionThrownWhenConstructorGivenNullArg()
|
||||
{
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
Assert.Throws<ArgumentNullException>(() => new PreviousSessionOpener(null));
|
||||
}
|
||||
|
||||
private RootNodeInfo BuildTree()
|
||||
{
|
||||
var root = new RootNodeInfo(RootNodeType.Connection);
|
||||
root.AddChild(new ConnectionInfo { PleaseConnect = true });
|
||||
root.AddChild(new ConnectionInfo());
|
||||
root.AddChild(new ConnectionInfo { PleaseConnect = true });
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
49
mRemoteNGTests/Tree/PreviouslyOpenedFolderExpanderTests.cs
Normal file
49
mRemoteNGTests/Tree/PreviouslyOpenedFolderExpanderTests.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Linq;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class PreviouslyOpenedFolderExpanderTests
|
||||
{
|
||||
private PreviouslyOpenedFolderExpander _folderExpander;
|
||||
private IConnectionTree _connectionTree;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_folderExpander = new PreviouslyOpenedFolderExpander();
|
||||
_connectionTree = Substitute.For<IConnectionTree>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExpandsAllFoldersThatAreMarkedForExpansion()
|
||||
{
|
||||
var connectionTreeModel = GenerateConnectionTreeModel();
|
||||
_connectionTree.ConnectionTreeModel.Returns(connectionTreeModel);
|
||||
_connectionTree.GetRootConnectionNode().Returns(connectionTreeModel.RootNodes[0]);
|
||||
_folderExpander.Execute(_connectionTree);
|
||||
Assert.That(_connectionTree.ExpandedObjects, Is.EquivalentTo(connectionTreeModel.GetRecursiveChildList().OfType<ContainerInfo>().Where(info => info.IsExpanded)));
|
||||
}
|
||||
|
||||
private ConnectionTreeModel GenerateConnectionTreeModel()
|
||||
{
|
||||
var connectionTreeModel = new ConnectionTreeModel();
|
||||
var root = new RootNodeInfo(RootNodeType.Connection) { IsExpanded = true };
|
||||
var folder1 = new ContainerInfo { IsExpanded = true };
|
||||
var folder2 = new ContainerInfo();
|
||||
var con1 = new ConnectionInfo();
|
||||
root.AddChild(folder1);
|
||||
folder1.AddChild(folder2);
|
||||
root.AddChild(con1);
|
||||
connectionTreeModel.AddRootNode(root);
|
||||
return connectionTreeModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.UI.Controls;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Tree
|
||||
{
|
||||
public class SelectedConnectionDeletionConfirmerTests
|
||||
{
|
||||
private SelectedConnectionDeletionConfirmer _deletionConfirmer;
|
||||
private IConnectionTree _connectionTree;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_connectionTree = Substitute.For<IConnectionTree>();
|
||||
_connectionTree.SelectedNode.Returns(new ConnectionInfo());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClickingYesReturnsTrue()
|
||||
{
|
||||
_deletionConfirmer = new SelectedConnectionDeletionConfirmer(_connectionTree, MockClickYes);
|
||||
Assert.That(_deletionConfirmer.Confirm(), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClickingNoReturnsFalse()
|
||||
{
|
||||
_deletionConfirmer = new SelectedConnectionDeletionConfirmer(_connectionTree, MockClickNo);
|
||||
Assert.That(_deletionConfirmer.Confirm(), Is.False);
|
||||
}
|
||||
|
||||
private DialogResult MockClickYes(string promptMessage, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
|
||||
{
|
||||
return DialogResult.Yes;
|
||||
}
|
||||
|
||||
private DialogResult MockClickNo(string promptMessage, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
|
||||
{
|
||||
return DialogResult.No;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs
Normal file
32
mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Threading;
|
||||
using mRemoteNG.UI.Window;
|
||||
using NUnit.Framework;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.UI.Window
|
||||
{
|
||||
public class ConnectionTreeWindowTests
|
||||
{
|
||||
private ConnectionTreeWindow _connectionTreeWindow;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_connectionTreeWindow = new ConnectionTreeWindow(new DockContent());
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown()
|
||||
{
|
||||
_connectionTreeWindow.Close();
|
||||
}
|
||||
|
||||
[Test, Apartment(ApartmentState.STA)]
|
||||
public void CanShowWindow()
|
||||
{
|
||||
_connectionTreeWindow.Show();
|
||||
Assert.That(_connectionTreeWindow.Visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
@@ -31,25 +31,25 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</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>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<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>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
@@ -101,12 +101,15 @@
|
||||
</When>
|
||||
<Otherwise>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="App\LoggerTests.cs" />
|
||||
<Compile Include="App\UpdaterTests.cs" />
|
||||
<Compile Include="BinaryFileTests.cs" />
|
||||
<Compile Include="Config\Serializers\DataTableSerializerTests.cs" />
|
||||
<Compile Include="Config\Serializers\PortScanDeserializerTests.cs" />
|
||||
@@ -127,6 +130,7 @@
|
||||
<Compile Include="Security\KeyDerivation\Pkcs5S2KeyGeneratorTests.cs" />
|
||||
<Compile Include="Security\SecureStringExtensionsTests.cs" />
|
||||
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
|
||||
<Compile Include="Tree\ClickHandlers\TreeNodeCompositeClickHandlerTests.cs" />
|
||||
<Compile Include="Tree\ConnectionTreeDragAndDropHandlerTests.cs" />
|
||||
<Compile Include="Tree\ConnectionTreeModelTests.cs" />
|
||||
<Compile Include="Connection\ConnectionInfoInheritanceTests.cs" />
|
||||
@@ -146,8 +150,15 @@
|
||||
<Compile Include="Security\CryptographyProviderFactoryTests.cs" />
|
||||
<Compile Include="Security\EncryptedSecureStringTests.cs" />
|
||||
<Compile Include="Security\LegacyRijndaelCryptographyProviderTests.cs" />
|
||||
<Compile Include="Tree\ConnectionTreeTests.cs" />
|
||||
<Compile Include="Tree\ClickHandlers\ExpandNodeClickHandlerTests.cs" />
|
||||
<Compile Include="Tree\NodeSearcherTests.cs" />
|
||||
<Compile Include="Tree\ClickHandlers\OpenConnectionClickHandlerTests.cs" />
|
||||
<Compile Include="Tree\PreviouslyOpenedFolderExpanderTests.cs" />
|
||||
<Compile Include="Tree\PreviousSessionOpenerTests.cs" />
|
||||
<Compile Include="Tree\RootNodeInfoTests.cs" />
|
||||
<Compile Include="Tree\ClickHandlers\SwitchToConnectionClickHandlerTests.cs" />
|
||||
<Compile Include="Tree\SelectedConnectionDeletionConfirmerTests.cs" />
|
||||
<Compile Include="UI\Controls\TestForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -157,6 +168,7 @@
|
||||
<Compile Include="UI\Forms\OptionsFormSetupAndTeardown.cs" />
|
||||
<Compile Include="UI\Forms\PasswordFormTests.cs" />
|
||||
<Compile Include="UI\WindowListTests.cs" />
|
||||
<Compile Include="UI\Window\ConnectionTreeWindowTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
@@ -207,6 +219,14 @@
|
||||
<ItemGroup>
|
||||
<None Include="Resources\confCons_v2_5_passwordis_Password_fullencryption.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Resources\beta-update-portable.txt" />
|
||||
<Content Include="Resources\beta-update.txt" />
|
||||
<Content Include="Resources\dev-update-portable.txt" />
|
||||
<Content Include="Resources\dev-update.txt" />
|
||||
<Content Include="Resources\update-portable.txt" />
|
||||
<Content Include="Resources\update.txt" />
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||
<ItemGroup>
|
||||
|
||||
2
mRemoteNGTests/mRemoteNGTests.csproj.DotSettings
Normal file
2
mRemoteNGTests/mRemoteNGTests.csproj.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=tree_005Cclickhandlers/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
@@ -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
|
||||
|
||||
@@ -8,24 +8,23 @@ using System.Windows.Forms;
|
||||
|
||||
namespace mRemoteNG.App
|
||||
{
|
||||
public class CompatibilityChecker
|
||||
public static class CompatibilityChecker
|
||||
{
|
||||
public void CheckCompatibility()
|
||||
public static void CheckCompatibility()
|
||||
{
|
||||
CheckFipsPolicy();
|
||||
CheckLenovoAutoScrollUtility();
|
||||
}
|
||||
|
||||
private void CheckFipsPolicy()
|
||||
private static void CheckFipsPolicy()
|
||||
{
|
||||
if (FipsPolicyEnabledForServer2003() || FipsPolicyEnabledForServer2008AndNewer())
|
||||
{
|
||||
MessageBox.Show(frmMain.Default, string.Format(Language.strErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName, GeneralAppInfo.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error));
|
||||
Environment.Exit(1);
|
||||
}
|
||||
Logger.Instance.InfoFormat("Checking FIPS Policy...");
|
||||
if (!FipsPolicyEnabledForServer2003() && !FipsPolicyEnabledForServer2008AndNewer()) return;
|
||||
MessageBox.Show(frmMain.Default, string.Format(Language.strErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName, GeneralAppInfo.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error));
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
private bool FipsPolicyEnabledForServer2003()
|
||||
private static bool FipsPolicyEnabledForServer2003()
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Lsa");
|
||||
var fipsPolicy = regKey?.GetValue("FIPSAlgorithmPolicy");
|
||||
@@ -34,7 +33,7 @@ namespace mRemoteNG.App
|
||||
return (int)fipsPolicy != 0;
|
||||
}
|
||||
|
||||
private bool FipsPolicyEnabledForServer2008AndNewer()
|
||||
private static bool FipsPolicyEnabledForServer2008AndNewer()
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Lsa\\FIPSAlgorithmPolicy");
|
||||
var fipsPolicy = regKey?.GetValue("Enabled");
|
||||
@@ -43,12 +42,14 @@ namespace mRemoteNG.App
|
||||
return (int)fipsPolicy != 0;
|
||||
}
|
||||
|
||||
private void CheckLenovoAutoScrollUtility()
|
||||
private static void CheckLenovoAutoScrollUtility()
|
||||
{
|
||||
Logger.Instance.InfoFormat("Checking Lenovo AutoScroll Utility...");
|
||||
|
||||
if (!Settings.Default.CompatibilityWarnLenovoAutoScrollUtility)
|
||||
return;
|
||||
|
||||
Process[] proccesses = new Process[] { };
|
||||
var proccesses = new Process[] { };
|
||||
try
|
||||
{
|
||||
proccesses = Process.GetProcessesByName("virtscrl");
|
||||
@@ -58,12 +59,10 @@ namespace mRemoteNG.App
|
||||
Runtime.MessageCollector.AddExceptionMessage("Error in CheckLenovoAutoScrollUtility", ex);
|
||||
}
|
||||
|
||||
if (proccesses.Length > 0)
|
||||
{
|
||||
CTaskDialog.MessageBox(Application.ProductName, Language.strCompatibilityProblemDetected, string.Format(Language.strCompatibilityLenovoAutoScrollUtilityDetected, Application.ProductName), "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.Ok, ESysIcons.Warning, ESysIcons.Warning);
|
||||
if (CTaskDialog.VerificationChecked)
|
||||
Settings.Default.CompatibilityWarnLenovoAutoScrollUtility = false;
|
||||
}
|
||||
if (proccesses.Length <= 0) return;
|
||||
CTaskDialog.MessageBox(Application.ProductName, Language.strCompatibilityProblemDetected, string.Format(Language.strCompatibilityLenovoAutoScrollUtilityDetected, Application.ProductName), "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.Ok, ESysIcons.Warning, ESysIcons.Warning);
|
||||
if (CTaskDialog.VerificationChecked)
|
||||
Settings.Default.CompatibilityWarnLenovoAutoScrollUtility = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace mRemoteNG.App
|
||||
}
|
||||
|
||||
if (exportForm.ShowDialog(frmMain.Default) != DialogResult.OK)
|
||||
return ;
|
||||
return;
|
||||
|
||||
ConnectionInfo exportTarget;
|
||||
switch (exportForm.Scope)
|
||||
@@ -76,12 +76,17 @@ namespace mRemoteNG.App
|
||||
var factory = new CryptographyProviderFactory();
|
||||
var cryptographyProvider = factory.CreateAeadCryptographyProvider(mRemoteNG.Settings.Default.EncryptionEngine, mRemoteNG.Settings.Default.EncryptionBlockCipherMode);
|
||||
cryptographyProvider.KeyDerivationIterations = Settings.Default.EncryptionKeyDerivationIterations;
|
||||
serializer = new XmlConnectionsSerializer(cryptographyProvider);
|
||||
((XmlConnectionsSerializer) serializer).SaveFilter = saveFilter;
|
||||
serializer = new XmlConnectionsSerializer(cryptographyProvider)
|
||||
{
|
||||
Export = true,
|
||||
SaveFilter = saveFilter
|
||||
};
|
||||
break;
|
||||
case ConnectionsSaver.Format.mRCSV:
|
||||
serializer = new CsvConnectionsSerializerMremotengFormat();
|
||||
((CsvConnectionsSerializerMremotengFormat)serializer).SaveFilter = saveFilter;
|
||||
serializer = new CsvConnectionsSerializerMremotengFormat
|
||||
{
|
||||
SaveFilter = saveFilter
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null);
|
||||
|
||||
@@ -11,23 +11,27 @@ namespace mRemoteNG.App.Info
|
||||
{
|
||||
public static class GeneralAppInfo
|
||||
{
|
||||
public static readonly string UrlHome = "http://www.mremoteng.org/";
|
||||
public static readonly string UrlDonate = "http://donate.mremoteng.org/";
|
||||
public static readonly string UrlForum = "http://forum.mremoteng.org/";
|
||||
public static readonly string UrlBugs = "http://bugs.mremoteng.org/";
|
||||
public static readonly string ApplicationVersion = Application.ProductVersion;
|
||||
public const string UrlHome = "http://www.mremoteng.org/";
|
||||
public const string UrlDonate = "http://donate.mremoteng.org/";
|
||||
public const string UrlForum = "http://forum.mremoteng.org/";
|
||||
public const string UrlBugs = "http://bugs.mremoteng.org/";
|
||||
public static string ApplicationVersion = Application.ProductVersion;
|
||||
public static readonly string ProductName = Application.ProductName;
|
||||
public static readonly string Copyright = ((AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyCopyrightAttribute), false)).Copyright;
|
||||
public static readonly string HomePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
||||
public static string ReportingFilePath = "";
|
||||
//public static string ReportingFilePath = "";
|
||||
public static readonly string PuttyPath = HomePath + "\\PuTTYNG.exe";
|
||||
public static string UserAgent
|
||||
{
|
||||
get
|
||||
{
|
||||
var details = new List<string>();
|
||||
details.Add("compatible");
|
||||
details.Add(OSVersion.Platform == PlatformID.Win32NT ? $"Windows NT {OSVersion.Version.Major}.{OSVersion.Version.Minor}": OSVersion.VersionString);
|
||||
var details = new List<string>
|
||||
{
|
||||
"compatible",
|
||||
OSVersion.Platform == PlatformID.Win32NT
|
||||
? $"Windows NT {OSVersion.Version.Major}.{OSVersion.Version.Minor}"
|
||||
: OSVersion.VersionString
|
||||
};
|
||||
if (Is64BitProcess)
|
||||
{
|
||||
details.Add("WOW64");
|
||||
|
||||
@@ -1,34 +1,72 @@
|
||||
namespace mRemoteNG.App.Info
|
||||
using System;
|
||||
|
||||
namespace mRemoteNG.App.Info
|
||||
{
|
||||
public static class UpdateChannelInfo
|
||||
{
|
||||
public static string FileName
|
||||
public const string STABLE = "Stable";
|
||||
public const string BETA = "Beta";
|
||||
public const string DEV = "Development";
|
||||
|
||||
/* no #if here since they are used for unit tests as well */
|
||||
public const string STABLE_PORTABLE = "update-portable.txt";
|
||||
public const string BETA_PORTABLE = "beta-update-portable.txt";
|
||||
public const string DEV_PORTABLE = "dev-update-portable.txt";
|
||||
|
||||
public const string STABLE_MSI = "update.txt";
|
||||
public const string BETA_MSI = "beta-update.txt";
|
||||
public const string DEV_MSI = "dev-update.txt";
|
||||
|
||||
|
||||
public static Uri GetUpdateChannelInfo()
|
||||
{
|
||||
var channel = IsValidChannel(Settings.Default.UpdateChannel) ? Settings.Default.UpdateChannel : STABLE;
|
||||
return GetUpdateTxtUri(channel);
|
||||
}
|
||||
|
||||
private static string GetChannelFileName(string channel)
|
||||
{
|
||||
#if PORTABLE
|
||||
get
|
||||
{
|
||||
/* */
|
||||
/* return PORTABLE update files here */
|
||||
/* */
|
||||
#if DEBUG
|
||||
return "update-portable-debug.txt";
|
||||
#else
|
||||
return Settings.Default.UpdateChannel.ToLowerInvariant() == "debug" ? "update-portable-debug.txt" : "update-portable.txt";
|
||||
#endif
|
||||
}
|
||||
switch (channel)
|
||||
{
|
||||
case STABLE:
|
||||
return STABLE_PORTABLE;
|
||||
case BETA:
|
||||
return BETA_PORTABLE;
|
||||
case DEV:
|
||||
return DEV_PORTABLE;
|
||||
default:
|
||||
return STABLE_PORTABLE;
|
||||
}
|
||||
#else //NOT portable
|
||||
get
|
||||
{
|
||||
/* */
|
||||
/* return INSTALLER update files here */
|
||||
/* */
|
||||
#if DEBUG
|
||||
return "update-debug.txt";
|
||||
#else
|
||||
return Settings.Default.UpdateChannel.ToLowerInvariant() == "debug" ? "update-debug.txt" : "update.txt";
|
||||
#endif
|
||||
}
|
||||
switch (channel)
|
||||
{
|
||||
case STABLE:
|
||||
return STABLE_MSI;
|
||||
case BETA:
|
||||
return BETA_MSI;
|
||||
case DEV:
|
||||
return DEV_MSI;
|
||||
default:
|
||||
return STABLE_MSI;
|
||||
}
|
||||
#endif //endif for PORTABLE
|
||||
}
|
||||
|
||||
private static Uri GetUpdateTxtUri(string channel)
|
||||
{
|
||||
return new Uri(new Uri(Settings.Default.UpdateAddress), new Uri(GetChannelFileName(channel), UriKind.Relative));
|
||||
}
|
||||
|
||||
private static bool IsValidChannel(string s)
|
||||
{
|
||||
return s.Equals(STABLE) || s.Equals(BETA) || s.Equals(DEV);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
#pragma warning disable 169
|
||||
|
||||
namespace mRemoteNG.App
|
||||
{
|
||||
@@ -326,6 +327,11 @@ namespace mRemoteNG.App
|
||||
/// </summary>
|
||||
public const int WM_ACTIVATEAPP = 0x1C;
|
||||
|
||||
/// <summary>
|
||||
/// Sent to a window if the mouse causes the cursor to move within a window and mouse input is not captured.
|
||||
/// </summary>
|
||||
public const int WM_SETCURSOR = 0x20;
|
||||
|
||||
/// <summary>
|
||||
/// Sent when the cursor is in an inactive window and the user presses a mouse button. The parent window receives this message only if the child window passes it to the DefWindowProc function.
|
||||
/// </summary>
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace mRemoteNG.App
|
||||
#region Public Properties
|
||||
public static WindowList WindowList { get; set; }
|
||||
public static MessageCollector MessageCollector { get; set; }
|
||||
public static Controls.NotificationAreaIcon NotificationAreaIcon { get; set; }
|
||||
public static NotificationAreaIcon NotificationAreaIcon { get; set; }
|
||||
public static bool IsConnectionsFileLoaded { get; set; }
|
||||
public static RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; }
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
@@ -42,8 +42,8 @@ namespace mRemoteNG.App
|
||||
public static SecureString EncryptionKey { get; set; } = new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString();
|
||||
public static ConnectionTreeModel ConnectionTreeModel
|
||||
{
|
||||
get { return Windows.TreeForm.ConnectionTreeModel; }
|
||||
set { Windows.TreeForm.ConnectionTreeModel = value; }
|
||||
get { return Windows.TreeForm.ConnectionTree.ConnectionTreeModel; }
|
||||
set { Windows.TreeForm.ConnectionTree.ConnectionTreeModel = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace mRemoteNG.App
|
||||
// Load config
|
||||
connectionsLoader.ConnectionFileName = filename;
|
||||
ConnectionTreeModel = connectionsLoader.LoadConnections(false);
|
||||
Windows.TreeForm.ConnectionTreeModel = ConnectionTreeModel;
|
||||
Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionTreeModel;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -274,7 +274,7 @@ namespace mRemoteNG.App
|
||||
{
|
||||
if (withDialog)
|
||||
{
|
||||
var loadDialog = Controls.ConnectionsLoadDialog();
|
||||
var loadDialog = ConnectionsLoadDialog();
|
||||
if (loadDialog.ShowDialog() != DialogResult.OK) return;
|
||||
connectionsLoader.ConnectionFileName = loadDialog.FileName;
|
||||
}
|
||||
@@ -288,7 +288,7 @@ namespace mRemoteNG.App
|
||||
|
||||
connectionsLoader.UseDatabase = Settings.Default.UseSQLServer;
|
||||
ConnectionTreeModel = connectionsLoader.LoadConnections(false);
|
||||
Windows.TreeForm.ConnectionTreeModel = ConnectionTreeModel;
|
||||
Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionTreeModel;
|
||||
|
||||
if (Settings.Default.UseSQLServer)
|
||||
{
|
||||
@@ -353,6 +353,16 @@ namespace mRemoteNG.App
|
||||
}
|
||||
}
|
||||
|
||||
private static OpenFileDialog ConnectionsLoadDialog()
|
||||
{
|
||||
return new OpenFileDialog
|
||||
{
|
||||
CheckFileExists = true,
|
||||
InitialDirectory = ConnectionsFileInfo.DefaultConnectionsPath,
|
||||
Filter = Language.strFiltermRemoteXML + @"|*.xml|" + Language.strFilterAll + @"|*.*"
|
||||
};
|
||||
}
|
||||
|
||||
private static void CreateBackupFile(string fileName)
|
||||
{
|
||||
// This intentionally doesn't prune any existing backup files. We just assume the user doesn't want any new ones created.
|
||||
@@ -593,7 +603,8 @@ namespace mRemoteNG.App
|
||||
connectionInfo.Protocol = url.StartsWith("https:") ? ProtocolType.HTTPS : ProtocolType.HTTP;
|
||||
connectionInfo.SetDefaultPort();
|
||||
connectionInfo.IsQuickConnect = true;
|
||||
ConnectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump);
|
||||
var connectionInitiator = new ConnectionInitiator();
|
||||
connectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump);
|
||||
}
|
||||
|
||||
public static void GoToWebsite()
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.App.Update;
|
||||
using mRemoteNG.Config.Connections;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using System;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
@@ -14,22 +7,26 @@ using System.IO;
|
||||
using System.Management;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.App.Update;
|
||||
using mRemoteNG.Config.Connections;
|
||||
using mRemoteNG.Config.Connections.Multiuser;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.UI;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using mRemoteNG.UI.Forms;
|
||||
|
||||
namespace mRemoteNG.App
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
private CompatibilityChecker _compatibilityChecker;
|
||||
private AppUpdater _appUpdate;
|
||||
|
||||
public static Startup Instance { get; } = new Startup();
|
||||
|
||||
private Startup()
|
||||
{
|
||||
_compatibilityChecker = new CompatibilityChecker();
|
||||
_appUpdate = new AppUpdater();
|
||||
}
|
||||
|
||||
@@ -41,49 +38,31 @@ namespace mRemoteNG.App
|
||||
{
|
||||
Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture));
|
||||
LogStartupData();
|
||||
_compatibilityChecker.CheckCompatibility();
|
||||
CompatibilityChecker.CheckCompatibility();
|
||||
ParseCommandLineArgs();
|
||||
IeBrowserEmulation.Register();
|
||||
GetConnectionIcons();
|
||||
DefaultConnectionInfo.Instance.LoadFrom(Settings.Default, (a)=>"ConDefault"+a);
|
||||
DefaultConnectionInheritance.Instance.LoadFrom(Settings.Default, (a)=>"InhDefault"+a);
|
||||
DefaultConnectionInfo.Instance.LoadFrom(Settings.Default, a=>"ConDefault"+a);
|
||||
DefaultConnectionInheritance.Instance.LoadFrom(Settings.Default, a=>"InhDefault"+a);
|
||||
}
|
||||
|
||||
public void SetDefaultLayout()
|
||||
private static void GetConnectionIcons()
|
||||
{
|
||||
frmMain.Default.pnlDock.Visible = false;
|
||||
|
||||
frmMain.Default.pnlDock.DockLeftPortion = frmMain.Default.pnlDock.Width * 0.2;
|
||||
frmMain.Default.pnlDock.DockRightPortion = frmMain.Default.pnlDock.Width * 0.2;
|
||||
frmMain.Default.pnlDock.DockTopPortion = frmMain.Default.pnlDock.Height * 0.25;
|
||||
frmMain.Default.pnlDock.DockBottomPortion = frmMain.Default.pnlDock.Height * 0.25;
|
||||
|
||||
Windows.TreePanel.Show(frmMain.Default.pnlDock, DockState.DockLeft);
|
||||
Windows.ConfigPanel.Show(frmMain.Default.pnlDock);
|
||||
Windows.ConfigPanel.DockTo(Windows.TreePanel.Pane, DockStyle.Bottom, -1);
|
||||
|
||||
Windows.ScreenshotForm.Hide();
|
||||
|
||||
frmMain.Default.pnlDock.Visible = true;
|
||||
}
|
||||
|
||||
private void GetConnectionIcons()
|
||||
{
|
||||
string iPath = GeneralAppInfo.HomePath + "\\Icons\\";
|
||||
var iPath = GeneralAppInfo.HomePath + "\\Icons\\";
|
||||
if (Directory.Exists(iPath) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string f in Directory.GetFiles(iPath, "*.ico", SearchOption.AllDirectories))
|
||||
foreach (var f in Directory.GetFiles(iPath, "*.ico", SearchOption.AllDirectories))
|
||||
{
|
||||
FileInfo fInfo = new FileInfo(f);
|
||||
var fInfo = new FileInfo(f);
|
||||
Array.Resize(ref ConnectionIcon.Icons, ConnectionIcon.Icons.Length + 1);
|
||||
ConnectionIcon.Icons.SetValue(fInfo.Name.Replace(".ico", ""), ConnectionIcon.Icons.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void LogStartupData()
|
||||
private static void LogStartupData()
|
||||
{
|
||||
if (!Settings.Default.WriteLogFile) return;
|
||||
LogApplicationData();
|
||||
@@ -93,17 +72,17 @@ namespace mRemoteNG.App
|
||||
LogCultureData();
|
||||
}
|
||||
|
||||
private void LogSystemData()
|
||||
private static void LogSystemData()
|
||||
{
|
||||
string osData = GetOperatingSystemData();
|
||||
string architecture = GetArchitectureData();
|
||||
var osData = GetOperatingSystemData();
|
||||
var architecture = GetArchitectureData();
|
||||
Logger.Instance.InfoFormat(string.Join(" ", Array.FindAll(new[] { osData, architecture }, s => !string.IsNullOrEmpty(Convert.ToString(s)))));
|
||||
}
|
||||
|
||||
private string GetOperatingSystemData()
|
||||
private static string GetOperatingSystemData()
|
||||
{
|
||||
string osVersion = string.Empty;
|
||||
string servicePack = string.Empty;
|
||||
var osVersion = string.Empty;
|
||||
var servicePack = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -118,13 +97,13 @@ namespace mRemoteNG.App
|
||||
{
|
||||
Logger.Instance.WarnFormat($"Error retrieving operating system information from WMI. {ex.Message}");
|
||||
}
|
||||
string osData = string.Join(" ", new string[] { osVersion, servicePack });
|
||||
var osData = string.Join(" ", osVersion, servicePack);
|
||||
return osData;
|
||||
}
|
||||
|
||||
private string GetOSServicePack(string servicePack, ManagementObject managementObject)
|
||||
private static string GetOSServicePack(string servicePack, ManagementObject managementObject)
|
||||
{
|
||||
int servicePackNumber = Convert.ToInt32(managementObject.GetPropertyValue("ServicePackMajorVersion"));
|
||||
var servicePackNumber = Convert.ToInt32(managementObject.GetPropertyValue("ServicePackMajorVersion"));
|
||||
if (servicePackNumber != 0)
|
||||
{
|
||||
servicePack = $"Service Pack {servicePackNumber}";
|
||||
@@ -132,15 +111,15 @@ namespace mRemoteNG.App
|
||||
return servicePack;
|
||||
}
|
||||
|
||||
private string GetArchitectureData()
|
||||
private static string GetArchitectureData()
|
||||
{
|
||||
string architecture = string.Empty;
|
||||
var architecture = string.Empty;
|
||||
try
|
||||
{
|
||||
foreach (var o in new ManagementObjectSearcher("SELECT * FROM Win32_Processor WHERE DeviceID=\'CPU0\'").Get())
|
||||
{
|
||||
var managementObject = (ManagementObject) o;
|
||||
int addressWidth = Convert.ToInt32(managementObject.GetPropertyValue("AddressWidth"));
|
||||
var addressWidth = Convert.ToInt32(managementObject.GetPropertyValue("AddressWidth"));
|
||||
architecture = $"{addressWidth}-bit";
|
||||
}
|
||||
}
|
||||
@@ -151,7 +130,7 @@ namespace mRemoteNG.App
|
||||
return architecture;
|
||||
}
|
||||
|
||||
private void LogApplicationData()
|
||||
private static void LogApplicationData()
|
||||
{
|
||||
#if !PORTABLE
|
||||
Logger.Instance.InfoFormat($"{Application.ProductName} {Application.ProductVersion} starting.");
|
||||
@@ -161,17 +140,17 @@ namespace mRemoteNG.App
|
||||
#endif
|
||||
}
|
||||
|
||||
private void LogCmdLineArgs()
|
||||
private static void LogCmdLineArgs()
|
||||
{
|
||||
Logger.Instance.InfoFormat($"Command Line: {Environment.GetCommandLineArgs()}");
|
||||
}
|
||||
|
||||
private void LogCLRData()
|
||||
private static void LogCLRData()
|
||||
{
|
||||
Logger.Instance.InfoFormat($"Microsoft .NET CLR {Environment.Version}");
|
||||
}
|
||||
|
||||
private void LogCultureData()
|
||||
private static void LogCultureData()
|
||||
{
|
||||
Logger.Instance.InfoFormat(
|
||||
$"System Culture: {Thread.CurrentThread.CurrentUICulture.Name}/{Thread.CurrentThread.CurrentUICulture.NativeName}");
|
||||
@@ -197,7 +176,7 @@ namespace mRemoteNG.App
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime nextUpdateCheck = Convert.ToDateTime(Settings.Default.CheckForUpdatesLastCheck.Add(TimeSpan.FromDays(Convert.ToDouble(Settings.Default.CheckForUpdatesFrequencyDays))));
|
||||
var nextUpdateCheck = Convert.ToDateTime(Settings.Default.CheckForUpdatesLastCheck.Add(TimeSpan.FromDays(Convert.ToDouble(Settings.Default.CheckForUpdatesFrequencyDays))));
|
||||
if (!Settings.Default.UpdatePending && DateTime.UtcNow < nextUpdateCheck)
|
||||
{
|
||||
return;
|
||||
@@ -211,7 +190,7 @@ namespace mRemoteNG.App
|
||||
{
|
||||
if (frmMain.Default.InvokeRequired)
|
||||
{
|
||||
frmMain.Default.Invoke(new AsyncCompletedEventHandler(GetUpdateInfoCompleted), new object[] { sender, e });
|
||||
frmMain.Default.Invoke(new AsyncCompletedEventHandler(GetUpdateInfoCompleted), sender, e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -225,7 +204,7 @@ namespace mRemoteNG.App
|
||||
}
|
||||
if (e.Error != null)
|
||||
{
|
||||
throw (e.Error);
|
||||
throw e.Error;
|
||||
}
|
||||
|
||||
if (_appUpdate.IsUpdateAvailable())
|
||||
@@ -240,13 +219,13 @@ namespace mRemoteNG.App
|
||||
}
|
||||
|
||||
|
||||
private void ParseCommandLineArgs()
|
||||
private static void ParseCommandLineArgs()
|
||||
{
|
||||
try
|
||||
{
|
||||
CmdArgumentsInterpreter cmd = new CmdArgumentsInterpreter(Environment.GetCommandLineArgs());
|
||||
var cmd = new CmdArgumentsInterpreter(Environment.GetCommandLineArgs());
|
||||
|
||||
string ConsParam = "";
|
||||
var ConsParam = "";
|
||||
if (cmd["cons"] != null)
|
||||
{
|
||||
ConsParam = "cons";
|
||||
@@ -256,7 +235,7 @@ namespace mRemoteNG.App
|
||||
ConsParam = "c";
|
||||
}
|
||||
|
||||
string ResetPosParam = "";
|
||||
var ResetPosParam = "";
|
||||
if (cmd["resetpos"] != null)
|
||||
{
|
||||
ResetPosParam = "resetpos";
|
||||
@@ -266,7 +245,7 @@ namespace mRemoteNG.App
|
||||
ResetPosParam = "rp";
|
||||
}
|
||||
|
||||
string ResetPanelsParam = "";
|
||||
var ResetPanelsParam = "";
|
||||
if (cmd["resetpanels"] != null)
|
||||
{
|
||||
ResetPanelsParam = "resetpanels";
|
||||
@@ -276,7 +255,7 @@ namespace mRemoteNG.App
|
||||
ResetPanelsParam = "rpnl";
|
||||
}
|
||||
|
||||
string ResetToolbarsParam = "";
|
||||
var ResetToolbarsParam = "";
|
||||
if (cmd["resettoolbar"] != null)
|
||||
{
|
||||
ResetToolbarsParam = "resettoolbar";
|
||||
@@ -293,7 +272,7 @@ namespace mRemoteNG.App
|
||||
ResetToolbarsParam = "rtbr";
|
||||
}
|
||||
|
||||
string NoReconnectParam = "";
|
||||
var NoReconnectParam = "";
|
||||
if (cmd["noreconnect"] != null)
|
||||
{
|
||||
NoReconnectParam = "noreconnect";
|
||||
@@ -313,7 +292,7 @@ namespace mRemoteNG.App
|
||||
Settings.Default.CustomConsPath = GeneralAppInfo.HomePath + "\\" + cmd[ConsParam];
|
||||
return;
|
||||
}
|
||||
else if (File.Exists(ConnectionsFileInfo.DefaultConnectionsPath + "\\" + cmd[ConsParam]))
|
||||
if (File.Exists(ConnectionsFileInfo.DefaultConnectionsPath + "\\" + cmd[ConsParam]))
|
||||
{
|
||||
Settings.Default.LoadConsFromCustomLocation = true;
|
||||
Settings.Default.CustomConsPath = ConnectionsFileInfo.DefaultConnectionsPath + "\\" + cmd[ConsParam];
|
||||
|
||||
@@ -9,118 +9,122 @@ using mRemoteNG.Security.SymmetricEncryption;
|
||||
using System.Security.Cryptography;
|
||||
#if !PORTABLE
|
||||
using mRemoteNG.Tools;
|
||||
|
||||
#else
|
||||
using System.Windows.Forms;
|
||||
#endif
|
||||
|
||||
namespace mRemoteNG.App.Update
|
||||
{
|
||||
public class AppUpdater
|
||||
{
|
||||
private WebProxy _webProxy;
|
||||
public class AppUpdater
|
||||
{
|
||||
private WebProxy _webProxy;
|
||||
private Thread _getUpdateInfoThread;
|
||||
private Thread _getChangeLogThread;
|
||||
|
||||
#region Public Properties
|
||||
#region Public Properties
|
||||
|
||||
public UpdateInfo CurrentUpdateInfo { get; private set; }
|
||||
|
||||
public string ChangeLog { get; private set; }
|
||||
public string ChangeLog { get; private set; }
|
||||
|
||||
public bool IsGetUpdateInfoRunning => _getUpdateInfoThread != null && _getUpdateInfoThread.IsAlive;
|
||||
public bool IsGetUpdateInfoRunning => _getUpdateInfoThread != null && _getUpdateInfoThread.IsAlive;
|
||||
|
||||
private bool IsGetChangeLogRunning => _getChangeLogThread != null && _getChangeLogThread.IsAlive;
|
||||
private bool IsGetChangeLogRunning => _getChangeLogThread != null && _getChangeLogThread.IsAlive;
|
||||
|
||||
public bool IsDownloadUpdateRunning => _downloadUpdateWebClient != null;
|
||||
public bool IsDownloadUpdateRunning => _downloadUpdateWebClient != null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
public AppUpdater()
|
||||
{
|
||||
SetProxySettings();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void SetProxySettings()
|
||||
{
|
||||
var shouldWeUseProxy = Settings.Default.UpdateUseProxy;
|
||||
var proxyAddress = Settings.Default.UpdateProxyAddress;
|
||||
var port = Settings.Default.UpdateProxyPort;
|
||||
var useAuthentication = Settings.Default.UpdateProxyUseAuthentication;
|
||||
var username = Settings.Default.UpdateProxyAuthUser;
|
||||
#region Public Methods
|
||||
|
||||
public AppUpdater()
|
||||
{
|
||||
SetProxySettings();
|
||||
}
|
||||
|
||||
private void SetProxySettings()
|
||||
{
|
||||
var shouldWeUseProxy = Settings.Default.UpdateUseProxy;
|
||||
var proxyAddress = Settings.Default.UpdateProxyAddress;
|
||||
var port = Settings.Default.UpdateProxyPort;
|
||||
var useAuthentication = Settings.Default.UpdateProxyUseAuthentication;
|
||||
var username = Settings.Default.UpdateProxyAuthUser;
|
||||
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
|
||||
var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey);
|
||||
var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey);
|
||||
|
||||
SetProxySettings(shouldWeUseProxy, proxyAddress, port, useAuthentication, username, password);
|
||||
}
|
||||
|
||||
public void SetProxySettings(bool useProxy, string address, int port, bool useAuthentication, string username, string password)
|
||||
{
|
||||
if (useProxy && !string.IsNullOrEmpty(address))
|
||||
{
|
||||
_webProxy = port != 0 ? new WebProxy(address, port) : new WebProxy(address);
|
||||
}
|
||||
|
||||
_webProxy.Credentials = useAuthentication ? new NetworkCredential(username, password) : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_webProxy = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUpdateAvailable()
|
||||
{
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return CurrentUpdateInfo.Version > GeneralAppInfo.GetApplicationVersion();
|
||||
}
|
||||
|
||||
public void GetUpdateInfoAsync()
|
||||
{
|
||||
if (IsGetUpdateInfoRunning)
|
||||
{
|
||||
_getUpdateInfoThread.Abort();
|
||||
}
|
||||
|
||||
_getUpdateInfoThread = new Thread(GetUpdateInfo);
|
||||
_getUpdateInfoThread.SetApartmentState(ApartmentState.STA);
|
||||
_getUpdateInfoThread.IsBackground = true;
|
||||
_getUpdateInfoThread.Start();
|
||||
}
|
||||
|
||||
public void GetChangeLogAsync()
|
||||
{
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling GetChangeLogAsync().");
|
||||
}
|
||||
|
||||
if (IsGetChangeLogRunning)
|
||||
{
|
||||
_getChangeLogThread.Abort();
|
||||
}
|
||||
|
||||
_getChangeLogThread = new Thread(GetChangeLog);
|
||||
_getChangeLogThread.SetApartmentState(ApartmentState.STA);
|
||||
_getChangeLogThread.IsBackground = true;
|
||||
_getChangeLogThread.Start();
|
||||
}
|
||||
|
||||
public void DownloadUpdateAsync()
|
||||
{
|
||||
if (_downloadUpdateWebClient != null)
|
||||
{
|
||||
throw new InvalidOperationException("A previous call to DownloadUpdateAsync() is still in progress.");
|
||||
}
|
||||
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync().");
|
||||
}
|
||||
public void SetProxySettings(bool useProxy, string address, int port, bool useAuthentication, string username, string password)
|
||||
{
|
||||
if (useProxy && !string.IsNullOrEmpty(address))
|
||||
{
|
||||
_webProxy = port != 0 ? new WebProxy(address, port) : new WebProxy(address);
|
||||
|
||||
_webProxy.Credentials = useAuthentication ? new NetworkCredential(username, password) : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_webProxy = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUpdateAvailable()
|
||||
{
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return CurrentUpdateInfo.Version > GeneralAppInfo.GetApplicationVersion();
|
||||
}
|
||||
|
||||
public void GetUpdateInfoAsync()
|
||||
{
|
||||
if (IsGetUpdateInfoRunning)
|
||||
{
|
||||
_getUpdateInfoThread.Abort();
|
||||
}
|
||||
|
||||
_getUpdateInfoThread = new Thread(GetUpdateInfo);
|
||||
_getUpdateInfoThread.SetApartmentState(ApartmentState.STA);
|
||||
_getUpdateInfoThread.IsBackground = true;
|
||||
_getUpdateInfoThread.Start();
|
||||
}
|
||||
|
||||
public void GetChangeLogAsync()
|
||||
{
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling GetChangeLogAsync().");
|
||||
}
|
||||
|
||||
if (IsGetChangeLogRunning)
|
||||
{
|
||||
_getChangeLogThread.Abort();
|
||||
}
|
||||
|
||||
_getChangeLogThread = new Thread(GetChangeLog);
|
||||
_getChangeLogThread.SetApartmentState(ApartmentState.STA);
|
||||
_getChangeLogThread.IsBackground = true;
|
||||
_getChangeLogThread.Start();
|
||||
}
|
||||
|
||||
public void DownloadUpdateAsync()
|
||||
{
|
||||
if (_downloadUpdateWebClient != null)
|
||||
{
|
||||
throw new InvalidOperationException("A previous call to DownloadUpdateAsync() is still in progress.");
|
||||
}
|
||||
|
||||
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync().");
|
||||
}
|
||||
#if !PORTABLE
|
||||
CurrentUpdateInfo.UpdateFilePath = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "exe"));
|
||||
CurrentUpdateInfo.UpdateFilePath = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi"));
|
||||
#else
|
||||
var sfd = new SaveFileDialog
|
||||
{
|
||||
@@ -138,166 +142,174 @@ namespace mRemoteNG.App.Update
|
||||
}
|
||||
#endif
|
||||
DownloadUpdateWebClient.DownloadFileAsync(CurrentUpdateInfo.DownloadAddress, CurrentUpdateInfo.UpdateFilePath);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Properties
|
||||
private WebClient _downloadUpdateWebClient;
|
||||
private WebClient DownloadUpdateWebClient
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_downloadUpdateWebClient != null)
|
||||
{
|
||||
return _downloadUpdateWebClient;
|
||||
}
|
||||
|
||||
_downloadUpdateWebClient = CreateWebClient();
|
||||
|
||||
_downloadUpdateWebClient.DownloadProgressChanged += DownloadUpdateProgressChanged;
|
||||
_downloadUpdateWebClient.DownloadFileCompleted += DownloadUpdateCompleted;
|
||||
|
||||
return _downloadUpdateWebClient;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
private WebClient CreateWebClient()
|
||||
{
|
||||
var webClient = new WebClient();
|
||||
webClient.Headers.Add("user-agent", GeneralAppInfo.UserAgent);
|
||||
webClient.Proxy = _webProxy;
|
||||
return webClient;
|
||||
}
|
||||
|
||||
private static DownloadStringCompletedEventArgs NewDownloadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken)
|
||||
{
|
||||
var type = typeof(DownloadStringCompletedEventArgs);
|
||||
const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
Type[] argumentTypes = {typeof(string), typeof(Exception), typeof(bool), typeof(object)};
|
||||
var constructor = type.GetConstructor(bindingFlags, null, argumentTypes, null);
|
||||
object[] arguments = {result, exception, cancelled, userToken};
|
||||
}
|
||||
|
||||
return (DownloadStringCompletedEventArgs)constructor.Invoke(arguments);
|
||||
}
|
||||
|
||||
private DownloadStringCompletedEventArgs DownloadString(Uri address)
|
||||
{
|
||||
var webClient = CreateWebClient();
|
||||
var result = string.Empty;
|
||||
Exception exception = null;
|
||||
var cancelled = false;
|
||||
|
||||
try
|
||||
{
|
||||
result = webClient.DownloadString(address);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
cancelled = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
|
||||
return NewDownloadStringCompletedEventArgs(result, exception, cancelled, null);
|
||||
}
|
||||
|
||||
private void GetUpdateInfo()
|
||||
{
|
||||
var updateFileUri = new Uri(new Uri(Convert.ToString(Settings.Default.UpdateAddress)), new Uri(UpdateChannelInfo.FileName, UriKind.Relative));
|
||||
var e = DownloadString(updateFileUri);
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
CurrentUpdateInfo = UpdateInfo.FromString(e.Result);
|
||||
#endregion
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private WebClient _downloadUpdateWebClient;
|
||||
|
||||
private WebClient DownloadUpdateWebClient
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_downloadUpdateWebClient != null)
|
||||
{
|
||||
return _downloadUpdateWebClient;
|
||||
}
|
||||
|
||||
_downloadUpdateWebClient = CreateWebClient();
|
||||
|
||||
_downloadUpdateWebClient.DownloadProgressChanged += DownloadUpdateProgressChanged;
|
||||
_downloadUpdateWebClient.DownloadFileCompleted += DownloadUpdateCompleted;
|
||||
|
||||
return _downloadUpdateWebClient;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private WebClient CreateWebClient()
|
||||
{
|
||||
var webClient = new WebClient();
|
||||
webClient.Headers.Add("user-agent", GeneralAppInfo.UserAgent);
|
||||
webClient.Proxy = _webProxy;
|
||||
return webClient;
|
||||
}
|
||||
|
||||
private static DownloadStringCompletedEventArgs NewDownloadStringCompletedEventArgs(string result,
|
||||
Exception exception, bool cancelled, object userToken)
|
||||
{
|
||||
var type = typeof(DownloadStringCompletedEventArgs);
|
||||
const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
Type[] argumentTypes = {typeof(string), typeof(Exception), typeof(bool), typeof(object)};
|
||||
var constructor = type.GetConstructor(bindingFlags, null, argumentTypes, null);
|
||||
object[] arguments = {result, exception, cancelled, userToken};
|
||||
|
||||
return (DownloadStringCompletedEventArgs) constructor.Invoke(arguments);
|
||||
}
|
||||
|
||||
public DownloadStringCompletedEventArgs DownloadString(Uri address)
|
||||
{
|
||||
var webClient = CreateWebClient();
|
||||
var result = string.Empty;
|
||||
Exception exception = null;
|
||||
var cancelled = false;
|
||||
|
||||
try
|
||||
{
|
||||
result = webClient.DownloadString(address);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
cancelled = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
|
||||
return NewDownloadStringCompletedEventArgs(result, exception, cancelled, null);
|
||||
}
|
||||
|
||||
private void GetUpdateInfo()
|
||||
{
|
||||
var e = DownloadString(UpdateChannelInfo.GetUpdateChannelInfo());
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
CurrentUpdateInfo = UpdateInfo.FromString(e.Result);
|
||||
|
||||
Settings.Default.CheckForUpdatesLastCheck = DateTime.UtcNow;
|
||||
if (!Settings.Default.UpdatePending)
|
||||
{
|
||||
if (!Settings.Default.UpdatePending)
|
||||
{
|
||||
Settings.Default.UpdatePending = IsUpdateAvailable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetUpdateInfoCompletedEventEvent?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void GetChangeLog()
|
||||
{
|
||||
var e = DownloadString(CurrentUpdateInfo.ChangeLogAddress);
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
ChangeLog = e.Result;
|
||||
}
|
||||
|
||||
private void GetChangeLog()
|
||||
{
|
||||
var e = DownloadString(CurrentUpdateInfo.ChangeLogAddress);
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
ChangeLog = e.Result;
|
||||
}
|
||||
|
||||
GetChangeLogCompletedEventEvent?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void DownloadUpdateProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||
{
|
||||
|
||||
private void DownloadUpdateProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||
{
|
||||
DownloadUpdateProgressChangedEventEvent?.Invoke(sender, e);
|
||||
}
|
||||
|
||||
private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
var raiseEventArgs = e;
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
var raiseEventArgs = e;
|
||||
|
||||
if (!e.Cancelled && e.Error == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
#if !PORTABLE
|
||||
var updateAuthenticode = new Authenticode(CurrentUpdateInfo.UpdateFilePath)
|
||||
{
|
||||
RequireThumbprintMatch = true,
|
||||
ThumbprintToMatch = CurrentUpdateInfo.CertificateThumbprint
|
||||
};
|
||||
{
|
||||
RequireThumbprintMatch = true,
|
||||
ThumbprintToMatch = CurrentUpdateInfo.CertificateThumbprint
|
||||
};
|
||||
|
||||
if (updateAuthenticode.Verify() != Authenticode.StatusValue.Verified)
|
||||
{
|
||||
if (updateAuthenticode.Status == Authenticode.StatusValue.UnhandledException)
|
||||
{
|
||||
throw (updateAuthenticode.Exception);
|
||||
}
|
||||
if (updateAuthenticode.Verify() != Authenticode.StatusValue.Verified)
|
||||
{
|
||||
if (updateAuthenticode.Status == Authenticode.StatusValue.UnhandledException)
|
||||
{
|
||||
throw updateAuthenticode.Exception;
|
||||
}
|
||||
|
||||
throw (new Exception(updateAuthenticode.StatusMessage));
|
||||
}
|
||||
throw new Exception(updateAuthenticode.StatusMessage);
|
||||
}
|
||||
#endif
|
||||
|
||||
using (var md5 = MD5.Create())
|
||||
using (var cksum = SHA512.Create())
|
||||
{
|
||||
using (var stream = File.OpenRead(CurrentUpdateInfo.UpdateFilePath))
|
||||
{
|
||||
var hash = md5.ComputeHash(stream);
|
||||
var hash = cksum.ComputeHash(stream);
|
||||
var hashString = BitConverter.ToString(hash).Replace("-", "").ToUpperInvariant();
|
||||
if (!hashString.Equals(CurrentUpdateInfo.Checksum))
|
||||
throw new Exception("MD5 Hashes didn't match!");
|
||||
throw new Exception("SHA512 Hashes didn't match!");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
raiseEventArgs = new AsyncCompletedEventArgs(ex, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEventArgs.Cancelled || raiseEventArgs.Error != null)
|
||||
{
|
||||
File.Delete(CurrentUpdateInfo.UpdateFilePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
raiseEventArgs = new AsyncCompletedEventArgs(ex, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEventArgs.Cancelled || raiseEventArgs.Error != null)
|
||||
{
|
||||
File.Delete(CurrentUpdateInfo.UpdateFilePath);
|
||||
}
|
||||
|
||||
DownloadUpdateCompletedEventEvent?.Invoke(this, raiseEventArgs);
|
||||
|
||||
_downloadUpdateWebClient.Dispose();
|
||||
_downloadUpdateWebClient = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
_downloadUpdateWebClient = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
private AsyncCompletedEventHandler GetUpdateInfoCompletedEventEvent;
|
||||
|
||||
public event AsyncCompletedEventHandler GetUpdateInfoCompletedEvent
|
||||
{
|
||||
add
|
||||
@@ -311,6 +323,7 @@ namespace mRemoteNG.App.Update
|
||||
}
|
||||
|
||||
private AsyncCompletedEventHandler GetChangeLogCompletedEventEvent;
|
||||
|
||||
public event AsyncCompletedEventHandler GetChangeLogCompletedEvent
|
||||
{
|
||||
add
|
||||
@@ -323,7 +336,8 @@ namespace mRemoteNG.App.Update
|
||||
}
|
||||
}
|
||||
|
||||
private DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEventEvent;
|
||||
private DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEventEvent;
|
||||
|
||||
public event DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEvent
|
||||
{
|
||||
add
|
||||
@@ -337,6 +351,7 @@ namespace mRemoteNG.App.Update
|
||||
}
|
||||
|
||||
private AsyncCompletedEventHandler DownloadUpdateCompletedEventEvent;
|
||||
|
||||
public event AsyncCompletedEventHandler DownloadUpdateCompletedEvent
|
||||
{
|
||||
add
|
||||
@@ -348,6 +363,7 @@ namespace mRemoteNG.App.Update
|
||||
DownloadUpdateCompletedEventEvent = (AsyncCompletedEventHandler)Delegate.Remove(DownloadUpdateCompletedEventEvent, value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Local
|
||||
|
||||
namespace mRemoteNG.App.Update
|
||||
{
|
||||
@@ -14,7 +15,8 @@ namespace mRemoteNG.App.Update
|
||||
#if !PORTABLE
|
||||
public string CertificateThumbprint { get; private set; }
|
||||
#endif
|
||||
public string FileName { get; private set; }
|
||||
// ReSharper disable once MemberCanBePrivate.Global
|
||||
public string FileName { get; set; }
|
||||
public string Checksum { get; private set; }
|
||||
|
||||
public static UpdateInfo FromString(string input)
|
||||
@@ -30,16 +32,45 @@ namespace mRemoteNG.App.Update
|
||||
newInfo.Version = updateFile.GetVersion();
|
||||
newInfo.DownloadAddress = updateFile.GetUri("dURL");
|
||||
newInfo.ChangeLogAddress = updateFile.GetUri("clURL");
|
||||
#if false
|
||||
newInfo.ImageAddress = updateFile.GetUri("imgURL");
|
||||
newInfo.ImageLinkAddress = updateFile.GetUri("imgURLLink");
|
||||
#endif
|
||||
#if !PORTABLE
|
||||
newInfo.CertificateThumbprint = updateFile.GetThumbprint();
|
||||
#endif
|
||||
newInfo.FileName = updateFile.GetFileName();
|
||||
newInfo.Checksum = updateFile.GetChecksum();
|
||||
newInfo.IsValid = true;
|
||||
newInfo.IsValid = newInfo.CheckIfValid();
|
||||
}
|
||||
return newInfo;
|
||||
}
|
||||
|
||||
public bool CheckIfValid()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Version.ToString()))
|
||||
return false;
|
||||
if(string.IsNullOrEmpty(DownloadAddress.AbsoluteUri))
|
||||
return false;
|
||||
if (string.IsNullOrEmpty(ChangeLogAddress.AbsoluteUri))
|
||||
return false;
|
||||
#if false
|
||||
if (string.IsNullOrEmpty(ImageAddress.AbsoluteUri))
|
||||
return false;
|
||||
if (string.IsNullOrEmpty(ImageLinkAddress.AbsoluteUri))
|
||||
return false;
|
||||
#endif
|
||||
#if !PORTABLE
|
||||
if (string.IsNullOrEmpty(CertificateThumbprint))
|
||||
return false;
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
return false;
|
||||
// ReSharper disable once ConvertIfStatementToReturnStatement
|
||||
if (string.IsNullOrEmpty(Checksum))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,9 @@ namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
var connector = new SqlDatabaseConnector();
|
||||
var dataProvider = new SqlDataProvider(connector);
|
||||
var dataTable = dataProvider.Load();
|
||||
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector);
|
||||
databaseVersionVerifier.VerifyDatabaseVersion();
|
||||
var dataTable = dataProvider.Load();
|
||||
deserializer = new DataTableDeserializer(dataTable);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -85,11 +85,12 @@ namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
var sqlConnector = new SqlDatabaseConnector();
|
||||
sqlConnector.Connect();
|
||||
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(sqlConnector);
|
||||
|
||||
if (!VerifyDatabaseVersion(sqlConnector))
|
||||
if (!databaseVersionVerifier.VerifyDatabaseVersion())
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strErrorConnectionListSaveFailed);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
var rootTreeNode = Runtime.ConnectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
|
||||
@@ -102,83 +103,6 @@ namespace mRemoteNG.Config.Connections
|
||||
sqlConnector.Dispose();
|
||||
}
|
||||
|
||||
private bool VerifyDatabaseVersion(SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var isVerified = false;
|
||||
try
|
||||
{
|
||||
var databaseVersion = GetDatabaseVersion(sqlDatabaseConnector);
|
||||
SqlCommand sqlCommand;
|
||||
|
||||
if (databaseVersion.Equals(new Version()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 2)) == 0) // 2.2
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Upgrading database from version {databaseVersion} to version 2.3.");
|
||||
sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD EnableFontSmoothing bit NOT NULL DEFAULT 0, EnableDesktopComposition bit NOT NULL DEFAULT 0, InheritEnableFontSmoothing bit NOT NULL DEFAULT 0, InheritEnableDesktopComposition bit NOT NULL DEFAULT 0;", sqlDatabaseConnector.SqlConnection);
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
databaseVersion = new Version(2, 3);
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 3)) == 0) // 2.3
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Upgrading database from version {databaseVersion} to version 2.4.");
|
||||
sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD UseCredSsp bit NOT NULL DEFAULT 1, InheritUseCredSsp bit NOT NULL DEFAULT 0;", sqlDatabaseConnector.SqlConnection);
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
databaseVersion = new Version(2, 4);
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 4)) == 0) // 2.4
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Upgrading database from version {databaseVersion} to version 2.5.");
|
||||
sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD LoadBalanceInfo varchar (1024) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, AutomaticResize bit NOT NULL DEFAULT 1, InheritLoadBalanceInfo bit NOT NULL DEFAULT 0, InheritAutomaticResize bit NOT NULL DEFAULT 0;", sqlDatabaseConnector.SqlConnection);
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
databaseVersion = new Version(2, 5);
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 5)) == 0) // 2.5
|
||||
isVerified = true;
|
||||
|
||||
if (isVerified == false)
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, string.Format(Language.strErrorBadDatabaseVersion, databaseVersion, GeneralAppInfo.ProductName));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strErrorVerifyDatabaseVersionFailed, ex.Message));
|
||||
}
|
||||
return isVerified;
|
||||
}
|
||||
|
||||
private Version GetDatabaseVersion(SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
Version databaseVersion;
|
||||
SqlDataReader sqlDataReader = null;
|
||||
try
|
||||
{
|
||||
var sqlCommand = new SqlCommand("SELECT * FROM tblRoot", sqlDatabaseConnector.SqlConnection);
|
||||
sqlDataReader = sqlCommand.ExecuteReader();
|
||||
if (!sqlDataReader.HasRows)
|
||||
return new Version(); // assume new empty database
|
||||
else
|
||||
sqlDataReader.Read();
|
||||
databaseVersion = new Version(Convert.ToString(sqlDataReader["confVersion"], CultureInfo.InvariantCulture));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, $"Retrieving database version failed. {ex}");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (sqlDataReader != null && !sqlDataReader.IsClosed)
|
||||
sqlDataReader.Close();
|
||||
}
|
||||
return databaseVersion;
|
||||
}
|
||||
|
||||
private void UpdateRootNodeTable(RootNodeInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace mRemoteNG.Config.Putty
|
||||
|
||||
if (_eventWatcher != null)
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -158,7 +158,7 @@ namespace mRemoteNG.Config.Putty
|
||||
|
||||
if (_eventWatcher == null)
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
_eventWatcher.EnableRaisingEvents = false;
|
||||
_eventWatcher.Dispose();
|
||||
@@ -231,7 +231,7 @@ namespace mRemoteNG.Config.Putty
|
||||
{
|
||||
if (!File.Exists(_puttyConfFile))
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
using (var streamReader = new StreamReader(_puttyConfFile))
|
||||
{
|
||||
@@ -299,7 +299,7 @@ namespace mRemoteNG.Config.Putty
|
||||
{
|
||||
if (!File.Exists(_sessionFile))
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
using (var streamReader = new StreamReader(_sessionFile))
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
// check/continue here so we don't create empty connection objects
|
||||
if(!_importSubOU) continue;
|
||||
|
||||
ActiveDirectoryImporter.Import(ldapResult.Path, parentContainer);
|
||||
ActiveDirectoryImporter.Import(ldapResult.Path, parentContainer, _importSubOU);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Connection.Protocol.Http;
|
||||
@@ -33,6 +34,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
{
|
||||
var connectionList = CreateNodesFromTable();
|
||||
var connectionTreeModel = CreateNodeHierarchy(connectionList);
|
||||
Runtime.IsConnectionsFileLoaded = true;
|
||||
return connectionTreeModel;
|
||||
}
|
||||
|
||||
@@ -84,6 +86,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), (string)dataRow["RenderingEngine"]);
|
||||
connectionInfo.ICAEncryptionStrength = (ProtocolICA.EncryptionStrength)Enum.Parse(typeof(ProtocolICA.EncryptionStrength), (string)dataRow["ICAEncryptionStrength"]);
|
||||
connectionInfo.RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel)Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), (string)dataRow["RDPAuthenticationLevel"]);
|
||||
connectionInfo.RDPMinutesToIdleTimeout = (int)dataRow["RDPMinutesToIdleTimeout"];
|
||||
connectionInfo.RDPAlertIdleTimeout = (bool)dataRow["RDPAlertIdleTimeout"];
|
||||
connectionInfo.LoadBalanceInfo = (string)dataRow["LoadBalanceInfo"];
|
||||
connectionInfo.Colors = (ProtocolRDP.RDPColors)Enum.Parse(typeof(ProtocolRDP.RDPColors) ,(string)dataRow["Colors"]);
|
||||
connectionInfo.Resolution = (ProtocolRDP.RDPResolutions)Enum.Parse(typeof(ProtocolRDP.RDPResolutions), (string)dataRow["Resolution"]);
|
||||
@@ -153,6 +157,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
connectionInfo.Inheritance.Username = (bool)dataRow["InheritUsername"];
|
||||
connectionInfo.Inheritance.ICAEncryptionStrength = (bool)dataRow["InheritICAEncryptionStrength"];
|
||||
connectionInfo.Inheritance.RDPAuthenticationLevel = (bool)dataRow["InheritRDPAuthenticationLevel"];
|
||||
connectionInfo.Inheritance.RDPAlertIdleTimeout = (bool)dataRow["InheritRDPAlertIdleTimeout"];
|
||||
connectionInfo.Inheritance.RDPMinutesToIdleTimeout = (bool)dataRow["InheritRDPMinutesToIdleTimeout"];
|
||||
connectionInfo.Inheritance.LoadBalanceInfo = (bool)dataRow["InheritLoadBalanceInfo"];
|
||||
connectionInfo.Inheritance.PreExtApp = (bool)dataRow["InheritPreExtApp"];
|
||||
connectionInfo.Inheritance.PostExtApp = (bool)dataRow["InheritPostExtApp"];
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
|
||||
private void CreateSchema()
|
||||
{
|
||||
// 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));
|
||||
@@ -121,7 +122,6 @@ namespace mRemoteNG.Config.Serializers
|
||||
_dataTable.Columns.Add("InheritRedirectPrinters", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectSmartCards", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritRedirectSound", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritSoundQuality", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritResolution", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritUseConsoleSession", typeof(bool));
|
||||
_dataTable.Columns.Add("InheritUseCredSsp", typeof(bool));
|
||||
@@ -155,6 +155,12 @@ namespace mRemoteNG.Config.Serializers
|
||||
_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()
|
||||
@@ -200,6 +206,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
dataRow["RenderingEngine"] = connectionInfo.RenderingEngine;
|
||||
dataRow["ICAEncryptionStrength"] = connectionInfo.ICAEncryptionStrength;
|
||||
dataRow["RDPAuthenticationLevel"] = connectionInfo.RDPAuthenticationLevel;
|
||||
dataRow["RDPMinutesToIdleTimeout"] = connectionInfo.RDPMinutesToIdleTimeout;
|
||||
dataRow["RDPAlertIdleTimeout"] = connectionInfo.RDPAlertIdleTimeout;
|
||||
dataRow["LoadBalanceInfo"] = connectionInfo.LoadBalanceInfo;
|
||||
dataRow["Colors"] = connectionInfo.Colors;
|
||||
dataRow["Resolution"] = connectionInfo.Resolution;
|
||||
@@ -214,7 +222,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
dataRow["RedirectPrinters"] = connectionInfo.RedirectPrinters;
|
||||
dataRow["RedirectSmartCards"] = connectionInfo.RedirectSmartCards;
|
||||
dataRow["RedirectSound"] = connectionInfo.RedirectSound;
|
||||
//dataRow["SoundQuality"] = connectionInfo.SoundQuality;
|
||||
dataRow["SoundQuality"] = connectionInfo.SoundQuality;
|
||||
dataRow["RedirectKeys"] = connectionInfo.RedirectKeys;
|
||||
dataRow["Connected"] = connectionInfo.OpenConnections.Count > 0;
|
||||
dataRow["PreExtApp"] = connectionInfo.PreExtApp;
|
||||
@@ -261,7 +269,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
dataRow["InheritRedirectPrinters"] = connectionInfo.Inheritance.RedirectPrinters;
|
||||
dataRow["InheritRedirectSmartCards"] = connectionInfo.Inheritance.RedirectSmartCards;
|
||||
dataRow["InheritRedirectSound"] = connectionInfo.Inheritance.RedirectSound;
|
||||
//dataRow["InheritSoundQuality"] = connectionInfo.Inheritance.SoundQuality;
|
||||
dataRow["InheritSoundQuality"] = connectionInfo.Inheritance.SoundQuality;
|
||||
dataRow["InheritResolution"] = connectionInfo.Inheritance.Resolution;
|
||||
dataRow["InheritAutomaticResize"] = connectionInfo.Inheritance.AutomaticResize;
|
||||
dataRow["InheritUseConsoleSession"] = connectionInfo.Inheritance.UseConsoleSession;
|
||||
@@ -270,6 +278,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
dataRow["InheritUsername"] = connectionInfo.Inheritance.Username;
|
||||
dataRow["InheritICAEncryptionStrength"] = connectionInfo.Inheritance.ICAEncryptionStrength;
|
||||
dataRow["InheritRDPAuthenticationLevel"] = connectionInfo.Inheritance.RDPAuthenticationLevel;
|
||||
dataRow["InheritRDPMinutesToIdleTimeout"] = connectionInfo.Inheritance.RDPMinutesToIdleTimeout;
|
||||
dataRow["InheritRDPAlertIdleTimeout"] = connectionInfo.Inheritance.RDPAlertIdleTimeout;
|
||||
dataRow["InheritLoadBalanceInfo"] = connectionInfo.Inheritance.LoadBalanceInfo;
|
||||
dataRow["InheritPreExtApp"] = connectionInfo.Inheritance.PreExtApp;
|
||||
dataRow["InheritPostExtApp"] = connectionInfo.Inheritance.PostExtApp;
|
||||
@@ -316,7 +326,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
dataRow["InheritRedirectPrinters"] = false;
|
||||
dataRow["InheritRedirectSmartCards"] = false;
|
||||
dataRow["InheritRedirectSound"] = false;
|
||||
//dataRow["InheritSoundQuality"] = false;
|
||||
dataRow["InheritSoundQuality"] = false;
|
||||
dataRow["InheritResolution"] = false;
|
||||
dataRow["InheritAutomaticResize"] = false;
|
||||
dataRow["InheritUseConsoleSession"] = false;
|
||||
@@ -325,6 +335,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
dataRow["InheritUsername"] = false;
|
||||
dataRow["InheritICAEncryptionStrength"] = false;
|
||||
dataRow["InheritRDPAuthenticationLevel"] = false;
|
||||
dataRow["InheritRDPMinutesToIdleTimeout"] = false;
|
||||
dataRow["InheritRDPAlertIdleTimeout"] = false;
|
||||
dataRow["InheritLoadBalanceInfo"] = false;
|
||||
dataRow["InheritPreExtApp"] = false;
|
||||
dataRow["InheritPostExtApp"] = false;
|
||||
|
||||
158
mRemoteV1/Config/Serializers/SqlDatabaseVersionVerifier.cs
Normal file
158
mRemoteV1/Config/Serializers/SqlDatabaseVersionVerifier.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Config.DatabaseConnectors;
|
||||
using mRemoteNG.Messages;
|
||||
|
||||
namespace mRemoteNG.Config.Serializers
|
||||
{
|
||||
public class SqlDatabaseVersionVerifier
|
||||
{
|
||||
private readonly SqlDatabaseConnector _sqlDatabaseConnector;
|
||||
|
||||
public SqlDatabaseVersionVerifier(SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
if (sqlDatabaseConnector == null)
|
||||
throw new ArgumentNullException(nameof(sqlDatabaseConnector));
|
||||
|
||||
_sqlDatabaseConnector = sqlDatabaseConnector;
|
||||
}
|
||||
|
||||
public bool VerifyDatabaseVersion()
|
||||
{
|
||||
var isVerified = false;
|
||||
try
|
||||
{
|
||||
var databaseVersion = GetDatabaseVersion(_sqlDatabaseConnector);
|
||||
|
||||
if (databaseVersion.Equals(new Version()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 2)) == 0) // 2.2
|
||||
{
|
||||
UpgradeFrom2_2();
|
||||
databaseVersion = new Version(2, 3);
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 3)) == 0) // 2.3
|
||||
{
|
||||
UpgradeFrom2_3();
|
||||
databaseVersion = new Version(2, 4);
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 4)) == 0) // 2.4
|
||||
{
|
||||
UpgradeFrom2_4();
|
||||
databaseVersion = new Version(2, 5);
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 5)) == 0) // 2.5
|
||||
{
|
||||
UpgradeFrom2_5();
|
||||
databaseVersion = new Version(2, 6);
|
||||
}
|
||||
|
||||
if (databaseVersion.CompareTo(new Version(2, 6)) == 0) // 2.6
|
||||
isVerified = true;
|
||||
|
||||
if (isVerified == false)
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg,
|
||||
string.Format(Language.strErrorBadDatabaseVersion, databaseVersion, GeneralAppInfo.ProductName));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg,
|
||||
string.Format(Language.strErrorVerifyDatabaseVersionFailed, ex.Message));
|
||||
}
|
||||
return isVerified;
|
||||
}
|
||||
|
||||
private Version GetDatabaseVersion(SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
Version databaseVersion;
|
||||
SqlDataReader sqlDataReader = null;
|
||||
try
|
||||
{
|
||||
var sqlCommand = new SqlCommand("SELECT * FROM tblRoot", sqlDatabaseConnector.SqlConnection);
|
||||
if (!sqlDatabaseConnector.IsConnected)
|
||||
sqlDatabaseConnector.Connect();
|
||||
sqlDataReader = sqlCommand.ExecuteReader();
|
||||
if (!sqlDataReader.HasRows)
|
||||
return new Version(); // assume new empty database
|
||||
else
|
||||
sqlDataReader.Read();
|
||||
databaseVersion =
|
||||
new Version(Convert.ToString(sqlDataReader["confVersion"], CultureInfo.InvariantCulture));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, $"Retrieving database version failed. {ex}");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (sqlDataReader != null && !sqlDataReader.IsClosed)
|
||||
sqlDataReader.Close();
|
||||
}
|
||||
return databaseVersion;
|
||||
}
|
||||
|
||||
private void UpgradeFrom2_2()
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Upgrading database from version 2.2 to version 2.3.");
|
||||
const string sqlText = @"
|
||||
ALTER TABLE tblCons
|
||||
ADD EnableFontSmoothing bit NOT NULL DEFAULT 0,
|
||||
EnableDesktopComposition bit NOT NULL DEFAULT 0,
|
||||
InheritEnableFontSmoothing bit NOT NULL DEFAULT 0,
|
||||
InheritEnableDesktopComposition bit NOT NULL DEFAULT 0;";
|
||||
var sqlCommand = new SqlCommand(sqlText, _sqlDatabaseConnector.SqlConnection);
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
private void UpgradeFrom2_3()
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Upgrading database from version 2.3 to version 2.4.");
|
||||
const string sqlText = @"
|
||||
ALTER TABLE tblCons
|
||||
ADD UseCredSsp bit NOT NULL DEFAULT 1,
|
||||
InheritUseCredSsp bit NOT NULL DEFAULT 0;";
|
||||
var sqlCommand = new SqlCommand(sqlText, _sqlDatabaseConnector.SqlConnection);
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
private void UpgradeFrom2_4()
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Upgrading database from version 2.4 to version 2.5.");
|
||||
const string sqlText = @"
|
||||
ALTER TABLE tblCons
|
||||
ADD LoadBalanceInfo varchar (1024) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||
AutomaticResize bit NOT NULL DEFAULT 1,
|
||||
InheritLoadBalanceInfo bit NOT NULL DEFAULT 0,
|
||||
InheritAutomaticResize bit NOT NULL DEFAULT 0;";
|
||||
var sqlCommand = new SqlCommand(sqlText, _sqlDatabaseConnector.SqlConnection);
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
private void UpgradeFrom2_5()
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Upgrading database from version 2.5 to version 2.6.");
|
||||
const string sqlText = @"
|
||||
ALTER TABLE tblCons
|
||||
ADD RDPMinutesToIdleTimeout int NOT NULL DEFAULT 0,
|
||||
RDPAlertIdleTimeout bit NOT NULL DEFAULT 0,
|
||||
SoundQuality varchar (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL DEFAULT 'Dynamic',
|
||||
InheritRDPMinutesToIdleTimeout bit NOT NULL DEFAULT 0,
|
||||
InheritRDPAlertIdleTimeout bit NOT NULL DEFAULT 0,
|
||||
InheritSoundQuality bit NOT NULL DEFAULT 0;
|
||||
UPDATE tblRoot
|
||||
SET ConfVersion='2.6'";
|
||||
var sqlCommand = new SqlCommand(sqlText, _sqlDatabaseConnector.SqlConnection);
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Security;
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Xml.Linq;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
@@ -13,14 +14,15 @@ namespace mRemoteNG.Config.Serializers
|
||||
private readonly SecureString _encryptionKey;
|
||||
private readonly SaveFilter _saveFilter = new SaveFilter();
|
||||
|
||||
public XmlConnectionNodeSerializer(ICryptographyProvider cryptographyProvider, SecureString encryptionKey)
|
||||
{
|
||||
_cryptographyProvider = cryptographyProvider;
|
||||
_encryptionKey = encryptionKey;
|
||||
}
|
||||
|
||||
public XmlConnectionNodeSerializer(ICryptographyProvider cryptographyProvider, SecureString encryptionKey, SaveFilter saveFilter)
|
||||
{
|
||||
if (cryptographyProvider == null)
|
||||
throw new ArgumentNullException(nameof(cryptographyProvider));
|
||||
if (encryptionKey == null)
|
||||
throw new ArgumentNullException(nameof(encryptionKey));
|
||||
if (saveFilter == null)
|
||||
throw new ArgumentNullException(nameof(saveFilter));
|
||||
|
||||
_cryptographyProvider = cryptographyProvider;
|
||||
_encryptionKey = encryptionKey;
|
||||
_saveFilter = saveFilter;
|
||||
@@ -44,6 +46,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
element.Add(new XAttribute("Descr", connectionInfo.Description));
|
||||
element.Add(new XAttribute("Icon", connectionInfo.Icon));
|
||||
element.Add(new XAttribute("Panel", connectionInfo.Panel));
|
||||
element.Add(new XAttribute("Id", connectionInfo.ConstantID));
|
||||
|
||||
element.Add(_saveFilter.SaveUsername
|
||||
? new XAttribute("Username", connectionInfo.Username)
|
||||
@@ -67,6 +70,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
element.Add(new XAttribute("RenderingEngine", connectionInfo.RenderingEngine));
|
||||
element.Add(new XAttribute("ICAEncryptionStrength", connectionInfo.ICAEncryptionStrength));
|
||||
element.Add(new XAttribute("RDPAuthenticationLevel", connectionInfo.RDPAuthenticationLevel));
|
||||
element.Add(new XAttribute("RDPMinutesToIdleTimeout", connectionInfo.RDPMinutesToIdleTimeout));
|
||||
element.Add(new XAttribute("RDPAlertIdleTimeout", connectionInfo.RDPAlertIdleTimeout));
|
||||
element.Add(new XAttribute("LoadBalanceInfo", connectionInfo.LoadBalanceInfo));
|
||||
element.Add(new XAttribute("Colors", connectionInfo.Colors));
|
||||
element.Add(new XAttribute("Resolution", connectionInfo.Resolution));
|
||||
@@ -159,6 +164,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
element.Add(new XAttribute("InheritUsername", connectionInfo.Inheritance.Username.ToString()));
|
||||
element.Add(new XAttribute("InheritICAEncryptionStrength", connectionInfo.Inheritance.ICAEncryptionStrength.ToString()));
|
||||
element.Add(new XAttribute("InheritRDPAuthenticationLevel", connectionInfo.Inheritance.RDPAuthenticationLevel.ToString()));
|
||||
element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", connectionInfo.Inheritance.RDPMinutesToIdleTimeout.ToString()));
|
||||
element.Add(new XAttribute("InheritRDPAlertIdleTimeout", connectionInfo.Inheritance.RDPAlertIdleTimeout.ToString()));
|
||||
element.Add(new XAttribute("InheritLoadBalanceInfo", connectionInfo.Inheritance.LoadBalanceInfo.ToString()));
|
||||
element.Add(new XAttribute("InheritPreExtApp", connectionInfo.Inheritance.PreExtApp.ToString()));
|
||||
element.Add(new XAttribute("InheritPostExtApp", connectionInfo.Inheritance.PostExtApp.ToString()));
|
||||
@@ -214,6 +221,8 @@ namespace mRemoteNG.Config.Serializers
|
||||
element.Add(new XAttribute("InheritUsername", false.ToString()));
|
||||
element.Add(new XAttribute("InheritICAEncryptionStrength", false.ToString()));
|
||||
element.Add(new XAttribute("InheritRDPAuthenticationLevel", false.ToString()));
|
||||
element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", false.ToString()));
|
||||
element.Add(new XAttribute("InheritRDPAlertIdleTimeout", false.ToString()));
|
||||
element.Add(new XAttribute("InheritLoadBalanceInfo", false.ToString()));
|
||||
element.Add(new XAttribute("InheritPreExtApp", false.ToString()));
|
||||
element.Add(new XAttribute("InheritPostExtApp", false.ToString()));
|
||||
|
||||
@@ -485,8 +485,13 @@ namespace mRemoteNG.Config.Serializers
|
||||
|
||||
if (_confVersion >= 2.6)
|
||||
{
|
||||
connectionInfo.ConstantID = xmlnode.Attributes["Id"]?.Value ?? connectionInfo.ConstantID;
|
||||
connectionInfo.SoundQuality = (ProtocolRDP.RDPSoundQuality)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPSoundQuality), Convert.ToString(xmlnode.Attributes["SoundQuality"].Value));
|
||||
connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value);
|
||||
connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0");
|
||||
connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"]?.Value ?? "False");
|
||||
connectionInfo.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["RDPAlertIdleTimeout"]?.Value ?? "False");
|
||||
connectionInfo.Inheritance.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPAlertIdleTimeout"]?.Value ?? "False");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Xml.Linq;
|
||||
using mRemoteNG.Connection;
|
||||
@@ -14,10 +15,17 @@ namespace mRemoteNG.Config.Serializers
|
||||
{
|
||||
private readonly ICryptographyProvider _cryptographyProvider;
|
||||
private SecureString _encryptionKey;
|
||||
private readonly SaveFilter _saveFilter;
|
||||
|
||||
public XmlConnectionsDocumentCompiler(ICryptographyProvider cryptographyProvider)
|
||||
public XmlConnectionsDocumentCompiler(ICryptographyProvider cryptographyProvider, SaveFilter saveFilter)
|
||||
{
|
||||
if (cryptographyProvider == null)
|
||||
throw new ArgumentNullException(nameof(cryptographyProvider));
|
||||
if (saveFilter == null)
|
||||
throw new ArgumentNullException(nameof(saveFilter));
|
||||
|
||||
_cryptographyProvider = cryptographyProvider;
|
||||
_saveFilter = saveFilter;
|
||||
}
|
||||
|
||||
public XDocument CompileDocument(ConnectionTreeModel connectionTreeModel, bool fullFileEncryption, bool export)
|
||||
@@ -77,7 +85,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
|
||||
private XElement CompileConnectionInfoNode(ConnectionInfo connectionInfo)
|
||||
{
|
||||
var connectionSerializer = new XmlConnectionNodeSerializer(_cryptographyProvider, _encryptionKey);
|
||||
var connectionSerializer = new XmlConnectionNodeSerializer(_cryptographyProvider, _encryptionKey, _saveFilter);
|
||||
return connectionSerializer.SerializeConnectionInfo(connectionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace mRemoteNG.Config.Serializers
|
||||
var xml = "";
|
||||
try
|
||||
{
|
||||
var documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider);
|
||||
var documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider, SaveFilter);
|
||||
var xmlDocument = documentCompiler.CompileDocument(serializationTarget, UseFullEncryption, Export);
|
||||
xml = WriteXmlToString(xmlDocument);
|
||||
}
|
||||
|
||||
@@ -20,47 +20,59 @@ namespace mRemoteNG.Config.Settings
|
||||
|
||||
public void LoadExternalAppsFromXML()
|
||||
{
|
||||
var oldPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\" + GeneralAppInfo.ProductName + "\\" + SettingsFileInfo.ExtAppsFilesName;
|
||||
var newPath = SettingsFileInfo.SettingsPath + "\\" + SettingsFileInfo.ExtAppsFilesName;
|
||||
#if !PORTABLE
|
||||
var oldPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), GeneralAppInfo.ProductName, SettingsFileInfo.ExtAppsFilesName);
|
||||
#endif
|
||||
var newPath = Path.Combine(SettingsFileInfo.SettingsPath, SettingsFileInfo.ExtAppsFilesName);
|
||||
var xDom = new XmlDocument();
|
||||
if (File.Exists(newPath))
|
||||
{
|
||||
Logger.Instance.Info($"Loading External Apps from: {newPath}");
|
||||
xDom.Load(newPath);
|
||||
}
|
||||
#if !PORTABLE
|
||||
}
|
||||
else if (File.Exists(oldPath))
|
||||
{
|
||||
xDom.Load(oldPath);
|
||||
Logger.Instance.Info($"Loading External Apps from: {oldPath}");
|
||||
xDom.Load(oldPath);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Instance.Warn("Loading External Apps failed: Could not FIND file!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (xDom.DocumentElement != null)
|
||||
foreach (XmlElement xEl in xDom.DocumentElement.ChildNodes)
|
||||
if (xDom.DocumentElement == null)
|
||||
{
|
||||
Logger.Instance.Warn("Loading External Apps failed: Could not LOAD file!");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (XmlElement xEl in xDom.DocumentElement.ChildNodes)
|
||||
{
|
||||
var extA = new ExternalTool
|
||||
{
|
||||
var extA = new ExternalTool
|
||||
{
|
||||
DisplayName = xEl.Attributes["DisplayName"].Value,
|
||||
FileName = xEl.Attributes["FileName"].Value,
|
||||
Arguments = xEl.Attributes["Arguments"].Value
|
||||
};
|
||||
DisplayName = xEl.Attributes["DisplayName"].Value,
|
||||
FileName = xEl.Attributes["FileName"].Value,
|
||||
Arguments = xEl.Attributes["Arguments"].Value
|
||||
};
|
||||
|
||||
if (xEl.HasAttribute("WaitForExit"))
|
||||
{
|
||||
extA.WaitForExit = bool.Parse(xEl.Attributes["WaitForExit"].Value);
|
||||
}
|
||||
|
||||
if (xEl.HasAttribute("TryToIntegrate"))
|
||||
{
|
||||
extA.TryIntegrate = bool.Parse(xEl.Attributes["TryToIntegrate"].Value);
|
||||
}
|
||||
|
||||
Runtime.ExternalTools.Add(extA);
|
||||
if (xEl.HasAttribute("WaitForExit"))
|
||||
{
|
||||
extA.WaitForExit = bool.Parse(xEl.Attributes["WaitForExit"].Value);
|
||||
}
|
||||
|
||||
if (xEl.HasAttribute("TryToIntegrate"))
|
||||
{
|
||||
extA.TryIntegrate = bool.Parse(xEl.Attributes["TryToIntegrate"].Value);
|
||||
}
|
||||
|
||||
Logger.Instance.Info($"Adding External App: {extA.DisplayName} {extA.FileName} {extA.Arguments}");
|
||||
Runtime.ExternalTools.Add(extA);
|
||||
}
|
||||
|
||||
_MainForm.SwitchToolBarText(Convert.ToBoolean(mRemoteNG.Settings.Default.ExtAppsTBShowText));
|
||||
|
||||
frmMain.Default.AddExternalToolsToToolBar();
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace mRemoteNG.Config.Settings
|
||||
}
|
||||
else
|
||||
{
|
||||
Startup.Instance.SetDefaultLayout();
|
||||
frmMain.Default.SetDefaultLayout();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -9,6 +9,7 @@ using mRemoteNG.Themes;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.UI.Forms;
|
||||
|
||||
|
||||
@@ -137,14 +138,14 @@ namespace mRemoteNG.Config.Settings
|
||||
private void SetKioskMode()
|
||||
{
|
||||
if (!mRemoteNG.Settings.Default.MainFormKiosk) return;
|
||||
MainForm.Fullscreen.Value = true;
|
||||
MainForm._fullscreen.Value = true;
|
||||
MainForm.mMenViewFullscreen.Checked = true;
|
||||
}
|
||||
|
||||
private static void SetShowSystemTrayIcon()
|
||||
{
|
||||
if (mRemoteNG.Settings.Default.ShowSystemTrayIcon)
|
||||
Runtime.NotificationAreaIcon = new Tools.Controls.NotificationAreaIcon();
|
||||
Runtime.NotificationAreaIcon = new NotificationAreaIcon();
|
||||
}
|
||||
|
||||
private static void SetPuttyPath()
|
||||
|
||||
@@ -36,9 +36,9 @@ namespace mRemoteNG.Config.Settings
|
||||
|
||||
mRemoteNG.Settings.Default.MainFormState = with1.WindowState;
|
||||
|
||||
if (with1.Fullscreen != null)
|
||||
if (with1._fullscreen != null)
|
||||
{
|
||||
mRemoteNG.Settings.Default.MainFormKiosk = with1.Fullscreen.Value;
|
||||
mRemoteNG.Settings.Default.MainFormKiosk = with1._fullscreen.Value;
|
||||
}
|
||||
|
||||
mRemoteNG.Settings.Default.FirstStart = false;
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace mRemoteNG.Connection
|
||||
private ProtocolICA.EncryptionStrength _icaEncryption;
|
||||
private bool _useConsoleSession;
|
||||
private ProtocolRDP.AuthenticationLevel _rdpAuthenticationLevel;
|
||||
private int _rdpMinutesToIdleTimeout;
|
||||
private bool _rdpAlertIdleTimeout;
|
||||
private string _loadBalanceInfo;
|
||||
private HTTPBase.RenderingEngine _renderingEngine;
|
||||
private bool _useCredSsp;
|
||||
@@ -225,6 +227,30 @@ namespace mRemoteNG.Connection
|
||||
set { SetField(ref _rdpAuthenticationLevel, value, "RDPAuthenticationLevel"); }
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDPMinutesToIdleTimeout"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPMinutesToIdleTimeout")]
|
||||
public virtual int RDPMinutesToIdleTimeout
|
||||
{
|
||||
get { return GetPropertyValue("RDPMinutesToIdleTimeout", _rdpMinutesToIdleTimeout); }
|
||||
set {
|
||||
if(value < 0) {
|
||||
value = 0;
|
||||
} else if(value > 240) {
|
||||
value = 240;
|
||||
}
|
||||
SetField(ref _rdpMinutesToIdleTimeout, value, "RDPMinutesToIdleTimeout");
|
||||
}
|
||||
}
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDPAlertIdleTimeout"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPAlertIdleTimeout")]
|
||||
public bool RDPAlertIdleTimeout
|
||||
{
|
||||
get { return GetPropertyValue("RDPAlertIdleTimeout", _rdpAlertIdleTimeout); }
|
||||
set { SetField(ref _rdpAlertIdleTimeout, value, "RDPAlertIdleTimeout"); }
|
||||
}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3),
|
||||
LocalizedAttributes.LocalizedDisplayName("strPropertyNameLoadBalanceInfo"),
|
||||
LocalizedAttributes.LocalizedDescription("strPropertyDescriptionLoadBalanceInfo")]
|
||||
|
||||
@@ -248,6 +248,8 @@ namespace mRemoteNG.Connection
|
||||
ICAEncryptionStrength = (ProtocolICA.EncryptionStrength) Enum.Parse(typeof(ProtocolICA.EncryptionStrength), Settings.Default.ConDefaultICAEncryptionStrength);
|
||||
UseConsoleSession = Settings.Default.ConDefaultUseConsoleSession;
|
||||
RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel) Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), Settings.Default.ConDefaultRDPAuthenticationLevel);
|
||||
RDPMinutesToIdleTimeout = Settings.Default.ConDefaultRDPMinutesToIdleTimeout;
|
||||
RDPAlertIdleTimeout = Settings.Default.ConDefaultRDPAlertIdleTimeout;
|
||||
LoadBalanceInfo = Settings.Default.ConDefaultLoadBalanceInfo;
|
||||
RenderingEngine = (HTTPBase.RenderingEngine) Enum.Parse(typeof(HTTPBase.RenderingEngine), Settings.Default.ConDefaultRenderingEngine);
|
||||
UseCredSsp = Settings.Default.ConDefaultUseCredSsp;
|
||||
|
||||
@@ -83,9 +83,19 @@ namespace mRemoteNG.Connection
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4),
|
||||
LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameAuthenticationLevel"),
|
||||
LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionAuthenticationLevel"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPAuthenticationLevel {get; set;}
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPAuthenticationLevel {get; set; }
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4),
|
||||
LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameRDPMinutesToIdleTimeout"),
|
||||
LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionRDPMinutesToIdleTimeout"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPMinutesToIdleTimeout { get; set; }
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4),
|
||||
LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameRDPAlertIdleTimeout"),
|
||||
LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionRDPAlertIdleTimeout"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))] public bool RDPAlertIdleTimeout { get; set; }
|
||||
|
||||
[LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4),
|
||||
LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameLoadBalanceInfo"),
|
||||
LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionLoadBalanceInfo"),
|
||||
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool LoadBalanceInfo {get; set;}
|
||||
|
||||
@@ -12,14 +12,52 @@ using TabPage = Crownwood.Magic.Controls.TabPage;
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
{
|
||||
public static class ConnectionInitiator
|
||||
public class ConnectionInitiator : IConnectionInitiator
|
||||
{
|
||||
public static void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None)
|
||||
public void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None)
|
||||
{
|
||||
OpenConnection(containerInfo, force, null);
|
||||
}
|
||||
|
||||
private static void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force, Form conForm)
|
||||
public void OpenConnection(ConnectionInfo connectionInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenConnection(connectionInfo, ConnectionInfo.Force.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionOpenFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force)
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenConnection(connectionInfo, force, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionOpenFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public bool SwitchToOpenConnection(ConnectionInfo connectionInfo)
|
||||
{
|
||||
var interfaceControl = FindConnectionContainer(connectionInfo);
|
||||
if (interfaceControl == null) return false;
|
||||
var connectionWindow = (ConnectionWindow)interfaceControl.FindForm();
|
||||
connectionWindow?.Focus();
|
||||
var findForm = (ConnectionWindow)interfaceControl.FindForm();
|
||||
findForm?.Show(frmMain.Default.pnlDock);
|
||||
var tabPage = (TabPage)interfaceControl.Parent;
|
||||
tabPage.Selected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Private
|
||||
private void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force, Form conForm)
|
||||
{
|
||||
var children = containerInfo.Children;
|
||||
if (children.Count == 0) return;
|
||||
@@ -33,31 +71,7 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenConnection(ConnectionInfo connectionInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenConnection(connectionInfo, ConnectionInfo.Force.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force)
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenConnection(connectionInfo, force, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force, Form conForm)
|
||||
private void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force, Form conForm)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -104,7 +118,7 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionOpenFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,19 +129,6 @@ namespace mRemoteNG.Connection
|
||||
extA?.Start(connectionInfo);
|
||||
}
|
||||
|
||||
public static bool SwitchToOpenConnection(ConnectionInfo nCi)
|
||||
{
|
||||
var IC = FindConnectionContainer(nCi);
|
||||
if (IC == null) return false;
|
||||
var connectionWindow = (ConnectionWindow)IC.FindForm();
|
||||
connectionWindow?.Focus();
|
||||
var findForm = (ConnectionWindow)IC.FindForm();
|
||||
findForm?.Show(frmMain.Default.pnlDock);
|
||||
var tabPage = (TabPage)IC.Parent;
|
||||
tabPage.Selected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static InterfaceControl FindConnectionContainer(ConnectionInfo connectionInfo)
|
||||
{
|
||||
if (connectionInfo.OpenConnections.Count <= 0) return null;
|
||||
@@ -185,11 +186,15 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
Control connectionContainer = ((ConnectionWindow)connectionForm).AddConnectionTab(connectionInfo);
|
||||
|
||||
if (connectionInfo.Protocol == ProtocolType.IntApp)
|
||||
{
|
||||
if (Runtime.GetExtAppByName(connectionInfo.ExtApp).Icon != null)
|
||||
((TabPage)connectionContainer).Icon = Runtime.GetExtAppByName(connectionInfo.ExtApp).Icon;
|
||||
}
|
||||
if (connectionInfo.Protocol != ProtocolType.IntApp) return connectionContainer;
|
||||
|
||||
var extT = Runtime.GetExtAppByName(connectionInfo.ExtApp);
|
||||
|
||||
if(extT == null) return connectionContainer;
|
||||
|
||||
if (extT.Icon != null)
|
||||
((TabPage)connectionContainer).Icon = extT.Icon;
|
||||
|
||||
return connectionContainer;
|
||||
}
|
||||
|
||||
@@ -210,10 +215,9 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
newProtocol.InterfaceControl = new InterfaceControl(connectionContainer, newProtocol, connectionInfo);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
#region Event handlers
|
||||
private static void Prot_Event_Disconnected(object sender, string disconnectedMessage)
|
||||
{
|
||||
try
|
||||
@@ -230,7 +234,7 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strProtocolEventDisconnectFailed, ex.Message), true);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strProtocolEventDisconnectFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +244,15 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
var Prot = (ProtocolBase)sender;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnenctionCloseEvent, true);
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnenctionClosedByUser, Prot.InterfaceControl.Info.Hostname, Prot.InterfaceControl.Info.Protocol.ToString(), Environment.UserName));
|
||||
string connDetail;
|
||||
if (Prot.InterfaceControl.Info.Hostname == "" && Prot.InterfaceControl.Info.Protocol == ProtocolType.IntApp)
|
||||
connDetail = Prot.InterfaceControl.Info.ExtApp;
|
||||
else if (Prot.InterfaceControl.Info.Hostname != "")
|
||||
connDetail = Prot.InterfaceControl.Info.Hostname;
|
||||
else
|
||||
connDetail = "UNKNOWN";
|
||||
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnenctionClosedByUser, connDetail, Prot.InterfaceControl.Info.Protocol, Environment.UserName));
|
||||
Prot.InterfaceControl.Info.OpenConnections.Remove(Prot);
|
||||
|
||||
if (Prot.InterfaceControl.Info.PostExtApp == "") return;
|
||||
@@ -249,7 +261,7 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnenctionCloseEventFailed + Environment.NewLine + ex.Message, true);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnenctionCloseEventFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,8 +285,9 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionEventConnectionFailed + Environment.NewLine + ex.Message, true);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionEventConnectionFailed, ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using mRemoteNG.App;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
@@ -39,15 +40,17 @@ namespace mRemoteNG.Connection
|
||||
var inheritanceProperties = GetProperties(_excludedProperties);
|
||||
foreach (var property in inheritanceProperties)
|
||||
{
|
||||
var propertyFromDestination = typeof(TDestination).GetProperty(propertyNameMutator(property.Name));
|
||||
var localValue = property.GetValue(Instance, null);
|
||||
|
||||
var descriptor = TypeDescriptor.GetProperties(Instance)[property.Name];
|
||||
var converter = descriptor.Converter;
|
||||
if (converter != null && converter.CanConvertFrom(localValue.GetType()))
|
||||
propertyFromDestination.SetValue(destinationInstance, converter.ConvertFrom(localValue), null);
|
||||
else
|
||||
propertyFromDestination.SetValue(destinationInstance, localValue, null);
|
||||
try
|
||||
{
|
||||
var propertyFromDestination = typeof(TDestination).GetProperty(propertyNameMutator(property.Name));
|
||||
var localValue = property.GetValue(Instance, null);
|
||||
var convertedValue = Convert.ChangeType(localValue, propertyFromDestination.PropertyType);
|
||||
propertyFromDestination.SetValue(destinationInstance, convertedValue, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector?.AddExceptionStackTrace($"Error saving default connectioninfo property {property.Name}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
mRemoteV1/Connection/IConnectionInitiator.cs
Normal file
15
mRemoteV1/Connection/IConnectionInitiator.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using mRemoteNG.Container;
|
||||
|
||||
namespace mRemoteNG.Connection
|
||||
{
|
||||
public interface IConnectionInitiator
|
||||
{
|
||||
void OpenConnection(ConnectionInfo connectionInfo);
|
||||
|
||||
void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None);
|
||||
|
||||
void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force);
|
||||
|
||||
bool SwitchToOpenConnection(ConnectionInfo connectionInfo);
|
||||
}
|
||||
}
|
||||
@@ -172,7 +172,7 @@ namespace mRemoteNG.Connection.Protocol.Http
|
||||
WebBrowser objWebBrowser = wBrowser as WebBrowser;
|
||||
if (objWebBrowser == null)
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
// This can only be set once the WebBrowser control is shown, it will throw a COM exception otherwise.
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace mRemoteNG.Connection.Protocol.ICA
|
||||
{
|
||||
if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) == (int)ConnectionInfo.Force.NoCredentials)
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
string _user = _Info.Username;
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Messages;
|
||||
|
||||
|
||||
namespace mRemoteNG.Connection.Protocol
|
||||
@@ -20,41 +21,52 @@ namespace mRemoteNG.Connection.Protocol
|
||||
#region Public Methods
|
||||
public override bool Initialize()
|
||||
{
|
||||
if (InterfaceControl.Info != null)
|
||||
{
|
||||
_externalTool = Runtime.GetExtAppByName(Convert.ToString(InterfaceControl.Info.ExtApp));
|
||||
_externalTool.ConnectionInfo = InterfaceControl.Info;
|
||||
}
|
||||
|
||||
return base.Initialize();
|
||||
if (InterfaceControl.Info == null) return base.Initialize();
|
||||
|
||||
_externalTool = Runtime.GetExtAppByName(InterfaceControl.Info.ExtApp);
|
||||
_externalTool.ConnectionInfo = InterfaceControl.Info;
|
||||
|
||||
return base.Initialize();
|
||||
}
|
||||
|
||||
public override bool Connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_externalTool.TryIntegrate == false)
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Attempting to start: {_externalTool.DisplayName}", true);
|
||||
|
||||
if (_externalTool.TryIntegrate == false)
|
||||
{
|
||||
_externalTool.Start(InterfaceControl.Info);
|
||||
Close();
|
||||
return false;
|
||||
/* Don't call close here... There's nothing for the override to do in this case since
|
||||
* _process is not created in this scenario. When returning false, ProtocolBase.Close()
|
||||
* will be called - which is just going to call IntegratedProgram.Close() again anyway...
|
||||
* Close();
|
||||
*/
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Assuming no other errors/exceptions occurred immediately before this message regarding {_externalTool.DisplayName}, the next \"closed by user\" message can be ignored", true);
|
||||
return false;
|
||||
}
|
||||
|
||||
ExternalToolArgumentParser argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo);
|
||||
_process = new Process();
|
||||
|
||||
_process.StartInfo.UseShellExecute = true;
|
||||
_process.StartInfo.FileName = argParser.ParseArguments(_externalTool.FileName);
|
||||
_process.StartInfo.Arguments = argParser.ParseArguments(_externalTool.Arguments);
|
||||
|
||||
_process.EnableRaisingEvents = true;
|
||||
_process.Exited += ProcessExited;
|
||||
var argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo);
|
||||
_process = new Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
UseShellExecute = true,
|
||||
FileName = argParser.ParseArguments(_externalTool.FileName),
|
||||
Arguments = argParser.ParseArguments(_externalTool.Arguments)
|
||||
},
|
||||
EnableRaisingEvents = true
|
||||
};
|
||||
|
||||
|
||||
_process.Exited += ProcessExited;
|
||||
|
||||
_process.Start();
|
||||
_process.WaitForInputIdle(Convert.ToInt32(Settings.Default.MaxPuttyWaitTime * 1000));
|
||||
_process.WaitForInputIdle(Settings.Default.MaxPuttyWaitTime * 1000);
|
||||
|
||||
int startTicks = Environment.TickCount;
|
||||
while (_handle.ToInt32() == 0 & Environment.TickCount < startTicks + (Settings.Default.MaxPuttyWaitTime * 1000))
|
||||
var startTicks = Environment.TickCount;
|
||||
while (_handle.ToInt32() == 0 & Environment.TickCount < startTicks + Settings.Default.MaxPuttyWaitTime * 1000)
|
||||
{
|
||||
_process.Refresh();
|
||||
if (_process.MainWindowTitle != "Default IME")
|
||||
@@ -68,10 +80,10 @@ namespace mRemoteNG.Connection.Protocol
|
||||
}
|
||||
|
||||
NativeMethods.SetParent(_handle, InterfaceControl.Handle);
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, Language.strIntAppStuff, true);
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppHandle, _handle.ToString()), true);
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppTitle, _process.MainWindowTitle), true);
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppParentHandle, InterfaceControl.Parent.Handle.ToString()), true);
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strIntAppStuff, true);
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strIntAppHandle, _handle), true);
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strIntAppTitle, _process.MainWindowTitle), true);
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strIntAppParentHandle, InterfaceControl.Parent.Handle), true);
|
||||
|
||||
Resize(this, new EventArgs());
|
||||
base.Connect();
|
||||
@@ -88,15 +100,12 @@ namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ConnectionWindow.InTabDrag)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if (ConnectionWindow.InTabDrag) return;
|
||||
NativeMethods.SetForegroundWindow(_handle);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppFocusFailed, ex: ex, logOnly: true);
|
||||
Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppFocusFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,45 +113,49 @@ namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
try
|
||||
{
|
||||
if (InterfaceControl.Size == Size.Empty)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
NativeMethods.MoveWindow(_handle, Convert.ToInt32(-SystemInformation.FrameBorderSize.Width), Convert.ToInt32(-(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height)), InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width * 2), InterfaceControl.Height + SystemInformation.CaptionHeight + (SystemInformation.FrameBorderSize.Height * 2), true);
|
||||
if (InterfaceControl.Size == Size.Empty) return;
|
||||
NativeMethods.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 (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppResizeFailed, ex: ex, logOnly: true);
|
||||
Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppResizeFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_process.HasExited)
|
||||
{
|
||||
_process.Kill();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppKillFailed, ex: ex, logOnly: true);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!_process.HasExited)
|
||||
{
|
||||
_process.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppDisposeFailed, ex: ex, logOnly: true);
|
||||
}
|
||||
|
||||
base.Close();
|
||||
/* only attempt this if we have a valid process object
|
||||
* Non-integated tools will still call base.Close() and don't have a valid process object.
|
||||
* See Connect() above... This just muddies up the log.
|
||||
*/
|
||||
if (_process != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_process.HasExited)
|
||||
{
|
||||
_process.Kill();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppKillFailed, ex);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!_process.HasExited)
|
||||
{
|
||||
_process.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppDisposeFailed, ex);
|
||||
}
|
||||
}
|
||||
|
||||
base.Close();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@ namespace mRemoteNG.Connection.Protocol
|
||||
|
||||
#region Public Properties
|
||||
#region Control
|
||||
public string Name { get; set; }
|
||||
private string Name { get; }
|
||||
|
||||
protected UI.Window.ConnectionWindow ConnectionWindow
|
||||
{
|
||||
get { return _connectionWindow; }
|
||||
set
|
||||
private set
|
||||
{
|
||||
_connectionWindow = value;
|
||||
_connectionWindow.ResizeBegin += ResizeBegin;
|
||||
@@ -61,7 +61,7 @@ namespace mRemoteNG.Connection.Protocol
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public ProtocolBase()
|
||||
protected ProtocolBase()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace mRemoteNG.Connection.Protocol
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t focus Control (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace("Couldn't focus Control (Connection.Protocol.Base)", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace mRemoteNG.Connection.Protocol
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t SetProps (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace("Couldn't SetProps (Connection.Protocol.Base)", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ namespace mRemoteNG.Connection.Protocol
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
Thread t = new Thread(CloseBG);
|
||||
var t = new Thread(CloseBG);
|
||||
t.SetApartmentState(ApartmentState.STA);
|
||||
t.IsBackground = true;
|
||||
t.Start();
|
||||
@@ -153,31 +153,31 @@ namespace mRemoteNG.Connection.Protocol
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.WarningMsg, "Could not dispose control, probably form is already closed (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace("Couldn't dispose control, probably form is already closed (Connection.Protocol.Base)", ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (_interfaceControl != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_interfaceControl.Parent == null) return;
|
||||
if (_interfaceControl.Parent.Tag != null)
|
||||
{
|
||||
SetTagToNothing();
|
||||
}
|
||||
|
||||
if (_interfaceControl == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_interfaceControl.Parent == null) return;
|
||||
|
||||
if (_interfaceControl.Parent.Tag != null)
|
||||
{
|
||||
SetTagToNothing();
|
||||
}
|
||||
|
||||
DisposeInterface();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.WarningMsg, "Could not set InterfaceControl.Parent.Tag or Dispose Interface, probably form is already closed (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true);
|
||||
}
|
||||
}
|
||||
DisposeInterface();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace("Couldn't set InterfaceControl.Parent.Tag or Dispose Interface, probably form is already closed (Connection.Protocol.Base)", ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t Close InterfaceControl BG (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true);
|
||||
Runtime.MessageCollector.AddExceptionStackTrace("Couldn't Close InterfaceControl BG (Connection.Protocol.Base)", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
if (_interfaceControl.InvokeRequired)
|
||||
{
|
||||
DisposeInterfaceCB s = new DisposeInterfaceCB(DisposeInterface);
|
||||
var s = new DisposeInterfaceCB(DisposeInterface);
|
||||
_interfaceControl.Invoke(s);
|
||||
}
|
||||
else
|
||||
@@ -200,7 +200,7 @@ namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
if (_interfaceControl.Parent.InvokeRequired)
|
||||
{
|
||||
SetTagToNothingCB s = new SetTagToNothingCB(SetTagToNothing);
|
||||
var s = new SetTagToNothingCB(SetTagToNothing);
|
||||
_interfaceControl.Parent.Invoke(s);
|
||||
}
|
||||
else
|
||||
@@ -214,7 +214,7 @@ namespace mRemoteNG.Connection.Protocol
|
||||
{
|
||||
if (Control.InvokeRequired)
|
||||
{
|
||||
DisposeControlCB s = new DisposeControlCB(DisposeControl);
|
||||
var s = new DisposeControlCB(DisposeControl);
|
||||
Control.Invoke(s);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
|
||||
private ConnectionInfo _connectionInfo;
|
||||
private bool _loginComplete;
|
||||
private bool _redirectKeys;
|
||||
private bool _alertOnIdleDisconnect;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
@@ -129,9 +130,12 @@ namespace mRemoteNG.Connection.Protocol.RDP
|
||||
SetCredentials();
|
||||
SetResolution();
|
||||
_rdpClient.FullScreenTitle = _connectionInfo.Name;
|
||||
|
||||
//not user changeable
|
||||
_rdpClient.AdvancedSettings2.GrabFocusOnConnect = true;
|
||||
|
||||
_alertOnIdleDisconnect = _connectionInfo.RDPAlertIdleTimeout;
|
||||
_rdpClient.AdvancedSettings2.MinutesToIdleTimeout = _connectionInfo.RDPMinutesToIdleTimeout;
|
||||
|
||||
//not user changeable
|
||||
_rdpClient.AdvancedSettings2.GrabFocusOnConnect = true;
|
||||
_rdpClient.AdvancedSettings3.EnableAutoReconnect = true;
|
||||
_rdpClient.AdvancedSettings3.MaxReconnectAttempts = Settings.Default.RdpReconnectionCount;
|
||||
_rdpClient.AdvancedSettings2.keepAliveInterval = 60000; //in milliseconds (10,000 = 10 seconds)
|
||||
@@ -176,8 +180,8 @@ namespace mRemoteNG.Connection.Protocol.RDP
|
||||
{
|
||||
_loginComplete = false;
|
||||
SetEventHandlers();
|
||||
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
_rdpClient.Connect();
|
||||
base.Connect();
|
||||
@@ -616,7 +620,8 @@ namespace mRemoteNG.Connection.Protocol.RDP
|
||||
_rdpClient.OnFatalError += RDPEvent_OnFatalError;
|
||||
_rdpClient.OnDisconnected += RDPEvent_OnDisconnected;
|
||||
_rdpClient.OnLeaveFullScreenMode += RDPEvent_OnLeaveFullscreenMode;
|
||||
}
|
||||
_rdpClient.OnIdleTimeoutNotification += RDPEvent_OnIdleTimeoutNotification;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace(Language.strRdpSetEventHandlersFailed, ex);
|
||||
@@ -625,7 +630,20 @@ namespace mRemoteNG.Connection.Protocol.RDP
|
||||
#endregion
|
||||
|
||||
#region Private Events & Handlers
|
||||
private void RDPEvent_OnFatalError(int errorCode)
|
||||
private void RDPEvent_OnIdleTimeoutNotification()
|
||||
{
|
||||
Close(); //Simply close the RDP Session if the idle timeout has been triggered.
|
||||
|
||||
if (_alertOnIdleDisconnect)
|
||||
{
|
||||
string message = "The " + _connectionInfo.Name + " session was disconnected due to inactivity";
|
||||
const string caption = "Session Disconnected";
|
||||
MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void RDPEvent_OnFatalError(int errorCode)
|
||||
{
|
||||
Event_ErrorOccured(this, Convert.ToString(errorCode));
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace mRemoteNG.Connection
|
||||
var puttyProcess = new PuttyProcessController();
|
||||
if (!puttyProcess.Start())
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
if (puttyProcess.SelectListBoxItem(PuttySession))
|
||||
{
|
||||
|
||||
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.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user