Compare commits

...

441 Commits

Author SHA1 Message Date
Dimitrij
8f26d57f40 NB release 2025-10-08 00:01:23 +01:00
Dimitrij
3bd2fe889a upd to for check x64 vc++ 2025-10-07 23:56:48 +01:00
Dimitrij
492a2629c2 Replace to x64 version 2025-10-07 23:32:21 +01:00
Dimitrij
b64ddf32ff fix 2025-10-07 23:31:28 +01:00
Dimitrij
e86a550985 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-10-07 23:31:12 +01:00
Dimitrij
fcccdacb99 Remove to update 2025-10-07 23:31:05 +01:00
Dimitrij
487de4c29b Merge pull request #2871 from simonai1254/v1.78.2-dev
Update README.md featuring Icon Project
2025-10-07 22:36:13 +01:00
Dimitrij
d36c6cb067 Merge pull request #2869 from mRemoteNG/copilot/fix-color-selection-for-panel-tabs
Fix Color property converter and add missing Display category attributes for TabColor
2025-10-07 22:31:30 +01:00
Simon Monai
a4b704252b Update README.md
Include Link to Fancy Icon Collection of @bearlikelion
2025-10-07 23:29:12 +02:00
Dimitrij
93e8d26a75 Merge branch 'v1.78.2-dev' into copilot/fix-color-selection-for-panel-tabs 2025-10-07 22:26:04 +01:00
copilot-swe-agent[bot]
0a3ecaac64 Fix Color property converter and add missing category attributes
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 21:17:26 +00:00
Simon Monai
ea6b762021 Update README.md
Add Visual C++ Dependency back in
2025-10-07 23:16:12 +02:00
Dimitrij
265a43e31c fix 2025-10-07 22:12:15 +01:00
copilot-swe-agent[bot]
6d156586ac Initial plan 2025-10-07 21:11:51 +00:00
Simon Monai
68e3f607a3 Update README.md
Fix Formatting Issue with Dependency Link
2025-10-07 22:40:48 +02:00
Dimitrij
0b240a3902 Merge pull request #2864 from mRemoteNG/copilot/add-color-support-for-connection-folders
Add Color property to connections and folders with inheritance support
2025-10-07 21:25:20 +01:00
Dimitrij
4082761606 Merge branch 'v1.78.2-dev' into copilot/add-color-support-for-connection-folders 2025-10-07 21:24:50 +01:00
Dimitrij
e68c42ba64 Merge pull request #2867 from mRemoteNG/copilot/fix-tab-color-selection-error
[WIP] Fix tab color dropdown selection error
2025-10-07 21:17:04 +01:00
copilot-swe-agent[bot]
347546ee0e Add TabColorConverter to fix Color to String conversion issue
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 20:15:32 +00:00
Dimitrij
ca717d6b80 Merge pull request #2863 from mRemoteNG/copilot/add-ard-connection-support
Add ARD (Apple Remote Desktop) protocol support for macOS connections
2025-10-07 21:12:17 +01:00
copilot-swe-agent[bot]
5d623d80eb Initial plan 2025-10-07 20:10:54 +00:00
Dimitrij
a2edbd9934 Merge pull request #2865 from mRemoteNG/copilot/add-connection-tab-colors
Add configurable connection tab colors to distinguish environments
2025-10-07 21:02:05 +01:00
copilot-swe-agent[bot]
5830f39d50 Add documentation for Tab Color feature
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:51:26 +00:00
copilot-swe-agent[bot]
0aa0b59635 Add documentation for Color property in folders and inheritance
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:50:10 +00:00
copilot-swe-agent[bot]
3c6a485647 Add TabColor property to connection info and implement tab coloring
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:49:32 +00:00
copilot-swe-agent[bot]
bbe1fa8416 Add Color property to Language.Designer.cs and add inheritance tests
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:49:21 +00:00
copilot-swe-agent[bot]
ac4469bb4a Add ARD protocol support to UI, port scanning, and tests
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:48:57 +00:00
copilot-swe-agent[bot]
9e61e8eafa Add Color property to connections and folders with inheritance support
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:47:07 +00:00
copilot-swe-agent[bot]
b193199268 Add ARD protocol to VNC property attributes and default port handling
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:45:38 +00:00
copilot-swe-agent[bot]
f8b7d37af1 Add ARD (Apple Remote Desktop) protocol support
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:42:31 +00:00
Dimitrij
b3e9202d72 Merge pull request #2862 from mRemoteNG/copilot/fix-unhandled-exception-panel-closure
Fix unhandled exception when closing panel with active connections
2025-10-07 20:40:35 +01:00
copilot-swe-agent[bot]
0f819ade56 Initial plan 2025-10-07 19:39:14 +00:00
copilot-swe-agent[bot]
d682afcde2 Initial plan 2025-10-07 19:39:03 +00:00
copilot-swe-agent[bot]
e67754ee9f Fix unhandled exception when closing panel with connections
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:35:18 +00:00
copilot-swe-agent[bot]
4897771fbf Initial plan 2025-10-07 19:35:06 +00:00
copilot-swe-agent[bot]
4128f3404a Initial plan 2025-10-07 19:31:35 +00:00
Dimitrij
7bc25ceb38 Merge pull request #2861 from mRemoteNG/copilot/add-autofocus-to-password-field
[WIP] Add autofocus to password field on startup
2025-10-07 20:29:40 +01:00
Dimitrij
f77f0f5e04 Merge pull request #2859 from mRemoteNG/copilot/fix-username-field-visibility
Fix Username field visibility for External Tool protocol
2025-10-07 20:28:48 +01:00
copilot-swe-agent[bot]
0e666efaad Add autofocus to password field in FrmPassword form
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:26:14 +00:00
copilot-swe-agent[bot]
e2893b9516 Add IntApp to Username property supported protocols
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 19:24:01 +00:00
copilot-swe-agent[bot]
fb86b13948 Initial plan 2025-10-07 19:22:15 +00:00
copilot-swe-agent[bot]
e22cc6921d Initial plan 2025-10-07 19:19:17 +00:00
Dimitrij
42fdd91206 Merge pull request #2857 from mRemoteNG/copilot/fix-default-panel-opening
Fix Update panel auto-loading on startup
2025-10-07 20:14:21 +01:00
copilot-swe-agent[bot]
2329d95002 Remove automatic Update panel display at startup
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 16:49:36 +00:00
copilot-swe-agent[bot]
8dda6ba13f Fix Update panel auto-checking on load
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 16:47:29 +00:00
copilot-swe-agent[bot]
156e2b8056 Initial plan 2025-10-07 16:41:34 +00:00
Dimitrij
aa48324b6d NB release 2025-10-07 17:10:32 +01:00
Dimitrij
d2b05ef7c3 renaming of folder to better represent its purpose 2025-10-07 17:01:48 +01:00
Dimitrij
75545e60b3 Merge pull request #2855 from mRemoteNG/copilot/fix-login-name-display-issue
Fix missing Username field for HTTP and HTTPS protocols
2025-10-07 17:00:27 +01:00
Dimitrij
b3d0b30b56 Merge pull request #2854 from mRemoteNG/copilot/refactor-settings-popup-to-panel
Refactor settings dialog to dockable panel for consistency
2025-10-07 16:54:54 +01:00
Dimitrij
3ed3729fc2 Merge pull request #2852 from mRemoteNG/copilot/fix-object-deserialization-vulnerability
Fix XML External Entity (XXE) vulnerability in XML deserialization
2025-10-07 16:51:36 +01:00
copilot-swe-agent[bot]
cb7ba46be6 Add comprehensive security tests for SecureXmlHelper
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 15:24:35 +00:00
copilot-swe-agent[bot]
933b21598e Add Username field support for HTTP and HTTPS protocols
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 15:23:46 +00:00
copilot-swe-agent[bot]
7a8442d9ea Handle FrmOptions visibility and window lifecycle
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 15:23:39 +00:00
copilot-swe-agent[bot]
c405186533 Update test files to use SecureXmlHelper for consistency
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 15:23:39 +00:00
copilot-swe-agent[bot]
5d150115a8 Create OptionsWindow for docked settings panel
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 15:22:20 +00:00
copilot-swe-agent[bot]
26bc38cf8c Add SecureXmlHelper and update all XML deserialization to prevent XXE attacks
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 15:20:14 +00:00
copilot-swe-agent[bot]
8f769cdda3 Initial plan 2025-10-07 15:16:42 +00:00
copilot-swe-agent[bot]
6b35cd3aee Initial plan 2025-10-07 15:16:03 +00:00
copilot-swe-agent[bot]
4ae1281a3a Initial plan 2025-10-07 15:06:32 +00:00
Dimitrij
9984d4bc8f Merge pull request #2850 from mRemoteNG/copilot/fix-d3d20276-2cee-4d8f-af65-24f3320db36a
Fix password dialog appearing behind splash screen on startup
2025-10-07 16:05:53 +01:00
Dimitrij
c987ee9fd3 Merge pull request #2851 from mRemoteNG/copilot/fix-3efd67f4-15e3-43e9-9b58-50941b183621
Fix path traversal vulnerability in file operations
2025-10-07 16:04:10 +01:00
copilot-swe-agent[bot]
a031e6f5f7 Add path validation to prevent path traversal attacks
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 14:04:00 +00:00
copilot-swe-agent[bot]
da386c3119 Close splash screen before loading connections to fix password dialog z-order
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-10-07 14:02:00 +00:00
copilot-swe-agent[bot]
bfd29fc0fc Initial plan 2025-10-07 13:57:18 +00:00
copilot-swe-agent[bot]
9617776be1 Initial plan 2025-10-07 13:55:19 +00:00
Dimitrij
765f2abc40 Merge pull request #2848 from mRemoteNG/renovate/softprops-action-gh-release-digest
chore(deps): update softprops/action-gh-release digest to aec2ec5
2025-10-07 08:12:44 +01:00
Dimitrij
519bc42e0a Merge pull request #2847 from mRemoteNG/renovate/nunit3testadapter-5.x
chore(deps): update dependency nunit3testadapter to 5.2.0
2025-10-07 08:12:03 +01:00
Dimitrij
6537e6bce6 Merge pull request #2846 from mRemoteNG/renovate/reportgenerator-5.x
chore(deps): update dependency reportgenerator to 5.4.17
2025-10-07 08:11:47 +01:00
renovate[bot]
494aff1bd3 chore(deps): update softprops/action-gh-release digest to aec2ec5 2025-10-07 04:37:18 +00:00
renovate[bot]
927527b888 chore(deps): update dependency nunit3testadapter to 5.2.0 2025-10-06 22:40:49 +00:00
renovate[bot]
08054e4873 chore(deps): update dependency reportgenerator to 5.4.17 2025-10-06 22:40:43 +00:00
Dimitrij
a092fef575 Merge pull request #2845 from mRemoteNG/renovate/microsoft.web.webview2-1.x
chore(deps): update dependency microsoft.web.webview2 to 1.0.3537.50
2025-10-06 17:35:02 +01:00
renovate[bot]
2808b3d3da chore(deps): update dependency microsoft.web.webview2 to 1.0.3537.50 2025-10-06 16:28:54 +00:00
Dimitrij
ef3b236d73 fix element placement for #2842 2025-10-06 17:27:25 +01:00
Dimitrij
26f0365026 Upd translation 2025-10-06 13:51:34 +01:00
Dimitrij
25ebfee6e2 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-10-06 13:51:16 +01:00
Dimitrij
c1ada03db1 Fix for #2841 - verify if vc++ distributed x86 installed 2025-10-06 13:51:08 +01:00
Dimitrij
0b17360346 Update README.md
upd
2025-10-06 11:54:40 +01:00
Dimitrij
da18b37a54 Fix markdown formatting for Nightly release badge
upd
2025-10-06 11:52:36 +01:00
Dimitrij
4cf040c01e Update README.md
upd
2025-10-06 11:50:38 +01:00
Dimitrij
95b77515dc Update Nightly build link and download badge
upd
2025-10-06 11:47:59 +01:00
Dimitrij
65bbd8ca05 Update README.md
upd
2025-10-06 11:44:36 +01:00
Dimitrij
dbba954522 small fixes 2025-10-03 22:19:39 +01:00
Dimitrij
26d46be243 dependencies are deprecated 2025-10-03 22:18:08 +01:00
Dimitrij
135f8290ec Merge pull request #2839 from mRemoteNG/fix/aikido-security-sast-8173389-4nsd
[Aikido] AI Fix for Possible command injection via Process.Start
2025-10-03 22:00:36 +01:00
Dimitrij
a8b4e1178d Merge pull request #2837 from mRemoteNG/renovate/cucumber.messages-30.x
chore(deps): update dependency cucumber.messages to v30
2025-10-03 22:00:14 +01:00
Dimitrij
8bdf66ef02 Merge pull request #2838 from mRemoteNG/fix/aikido-security-sast-8173368-kjEd
[Aikido] AI Fix for Potential SQL injection via string-based query concatenation
2025-10-03 21:59:48 +01:00
aikido-autofix[bot]
5209b08709 fix(security): autofix Possible command injection via Process.Start 2025-10-03 20:58:27 +00:00
aikido-autofix[bot]
933247dc2f fix(security): autofix Potential SQL injection via string-based query concatenation 2025-10-03 20:57:07 +00:00
renovate[bot]
4e43bf9d8f chore(deps): update dependency cucumber.messages to v30 2025-10-03 16:58:47 +00:00
Dimitrij
0f6a5816db Merge pull request #2835 from mRemoteNG/renovate/aws-sdk-net-monorepo
chore(deps): update aws-sdk-net monorepo
2025-10-02 22:31:54 +01:00
Dimitrij
8021678995 Merge pull request #2836 from mRemoteNG/renovate/major-vstest-monorepo
chore(deps): update dependency microsoft.net.test.sdk to v18
2025-10-02 22:24:41 +01:00
renovate[bot]
147b5edec4 chore(deps): update dependency microsoft.net.test.sdk to v18 2025-10-02 11:24:09 +00:00
renovate[bot]
2edbf3222e chore(deps): update aws-sdk-net monorepo 2025-10-01 22:05:23 +00:00
Dimitrij
f6bf8c229c Merge pull request #2834 from mRemoteNG/renovate/aws-sdk-net-monorepo
chore(deps): update aws-sdk-net monorepo
2025-09-30 10:16:42 +01:00
renovate[bot]
c30b90af44 chore(deps): update aws-sdk-net monorepo 2025-09-29 21:07:53 +00:00
Dimitrij
3b72e7af3d Merge pull request #2832 from mRemoteNG/renovate/aws-sdk-net-monorepo
chore(deps): update dependency awssdk.ec2 to 4.0.40.1
2025-09-29 22:07:17 +01:00
renovate[bot]
37004647eb chore(deps): update dependency awssdk.ec2 to 4.0.40.1 2025-09-29 16:46:13 +00:00
Dimitrij
c85cb84e31 Merge pull request #2829 from mRemoteNG/renovate/configure
chore: Configure Renovate
2025-09-29 17:45:28 +01:00
renovate[bot]
d504143d7e Add renovate.json 2025-09-26 18:08:44 +00:00
Dimitrij
db1c7b9708 Merge pull request #2827 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-arm64-140.x
chore(deps): update dependency chromiumembeddedframework.runtime.win-arm64 to v140
2025-09-25 09:36:29 +01:00
Dimitrij
064cb34705 Merge pull request #2828 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-x64-140.x
chore(deps): update dependency chromiumembeddedframework.runtime.win-x64 to v140
2025-09-25 09:36:09 +01:00
Dimitrij
02c442ef99 Merge pull request #2825 from mRemoteNG/renovate/reportgenerator-5.x
chore(deps): update dependency reportgenerator to 5.4.16
2025-09-25 09:35:54 +01:00
renovate[bot]
e358cafb3f chore(deps): update dependency reportgenerator to 5.4.16 2025-09-24 20:44:07 +00:00
renovate[bot]
40e447bc05 chore(deps): update dependency chromiumembeddedframework.runtime.win-x64 to v140 2025-09-24 15:31:30 +00:00
renovate[bot]
f0bac9ee78 chore(deps): update dependency chromiumembeddedframework.runtime.win-arm64 to v140 2025-09-24 15:31:22 +00:00
Dimitrij
a75fbad0ea Merge pull request #2823 from mRemoteNG/renovate/awssdk.core-4.x
chore(deps): update dependency awssdk.core to 4.0.0.29
2025-09-23 23:57:32 +01:00
renovate[bot]
ae5a919421 chore(deps): update dependency awssdk.core to 4.0.0.29 2025-09-23 22:57:10 +00:00
Dimitrij
749cb7578a Merge pull request #2824 from mRemoteNG/renovate/awssdk.ec2-4.x
chore(deps): update dependency awssdk.ec2 to 4.0.40
2025-09-23 23:56:38 +01:00
renovate[bot]
622ea20819 chore(deps): update dependency awssdk.ec2 to 4.0.40 2025-09-23 22:08:58 +00:00
Dimitrij
a9374a5eb1 Merge pull request #2822 from mRemoteNG/copilot/fix-3abc8ac6-985e-4856-8afb-a91a0dca6d12
Remove insecure pull_request_target trigger from add_PR_2_chlog.yml workflow
2025-09-23 16:25:10 +01:00
copilot-swe-agent[bot]
1b78b68e33 Remove insecure pull_request_target trigger from workflow
Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2025-09-23 09:30:17 +00:00
copilot-swe-agent[bot]
3e97fe0490 Initial plan 2025-09-23 09:26:03 +00:00
Dimitrij
2bb34607cc Merge pull request #2813 from mRemoteNG/renovate/gherkin-35.x
chore(deps): update dependency gherkin to 35.1.0
2025-09-21 22:08:02 +01:00
Dimitrij
fe7fca180e Merge pull request #2814 from mRemoteNG/renovate/reportgenerator-5.x
chore(deps): update dependency reportgenerator to 5.4.14
2025-09-21 22:07:49 +01:00
renovate[bot]
0a86b45d59 chore(deps): update dependency reportgenerator to 5.4.14 2025-09-21 13:56:20 +00:00
Dimitrij
62e0dd365b Merge pull request #2788 from mRemoteNG/renovate/reportgenerator-5.x
chore(deps): update dependency reportgenerator to 5.4.14
2025-09-21 14:55:49 +01:00
renovate[bot]
b39c561b72 chore(deps): update dependency gherkin to 35.1.0 2025-09-20 13:43:33 +00:00
Dimitrij
02d099629f Merge pull request #2812 from ciis0/cschulz/fix-refocus
Fix RDP refocus issues
2025-09-19 18:12:15 +01:00
Dimitrij
0f55cd2395 Update mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-19 11:39:23 +01:00
Christoph Schulz
119451e4f6 Fix RDP refocus issues
Fixes #1535
2025-09-19 09:25:40 +02:00
Dimitrij
0f6d4e5760 Merge pull request #2811 from mRemoteNG/renovate/awssdk.ec2-4.x
chore(deps): update dependency awssdk.ec2 to 4.0.39
2025-09-18 23:43:55 +01:00
renovate[bot]
452ed6a754 chore(deps): update dependency awssdk.ec2 to 4.0.39 2025-09-18 22:07:33 +00:00
Dimitrij
40928b8ab0 Merge pull request #2808 from mRemoteNG/renovate/awssdk.ec2-4.x
chore(deps): update dependency awssdk.ec2 to 4.0.38
2025-09-17 21:46:43 +01:00
renovate[bot]
f1ed380b42 chore(deps): update dependency awssdk.ec2 to 4.0.38 2025-09-17 20:34:27 +00:00
Dimitrij
e28ae8f2ba Merge pull request #2805 from mRemoteNG/renovate/awssdk.core-4.x
chore(deps): update dependency awssdk.core to 4.0.0.28
2025-09-17 10:57:26 +01:00
renovate[bot]
d8c6d9d558 chore(deps): update dependency awssdk.core to 4.0.0.28 2025-09-17 09:56:31 +00:00
Dimitrij
607123f0be Merge pull request #2806 from mRemoteNG/renovate/awssdk.ec2-4.x
chore(deps): update dependency awssdk.ec2 to 4.0.37.1
2025-09-17 10:56:00 +01:00
Dimitrij
0ff72ae665 Merge pull request #2807 from Greenie0701/arm64_dotnet
Add ARM64 support for .NET runtime detection
2025-09-17 10:55:37 +01:00
Dimitrij
552cee1c24 Update mRemoteNG/App/Update/DotNetRuntimeCheck.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-17 10:55:28 +01:00
MS-GITS
44f05a2968 Add ARM64 support for .NET runtime detection 2025-09-17 14:52:54 +05:30
MS-GITS
244fbf56d1 Add ARM64 support for .NET runtime detection 2025-09-17 14:50:41 +05:30
renovate[bot]
24845039f1 chore(deps): update dependency awssdk.ec2 to 4.0.37.1 2025-09-16 21:07:05 +00:00
Dimitrij
2e5be847ce Merge pull request #2804 from mRemoteNG/fix/aikido-security-sast--7464421-c51u
[Aikido] AI Fix for Path traversal attack possible
2025-09-16 20:44:12 +01:00
Dimitrij
9e947f7a36 Merge pull request #2803 from mRemoteNG/fix/aikido-security-sast--7464399-kZ9j
[Aikido] AI Fix for Path traversal attack possible
2025-09-16 20:43:59 +01:00
Dimitrij
87a3c60330 Merge pull request #2802 from mRemoteNG/fix/aikido-security-sast--7464375-mF7U
[Aikido] AI Fix for Path traversal attack possible
2025-09-16 20:43:47 +01:00
Dimitrij
0d460d543b Merge pull request #2801 from mRemoteNG/fix/aikido-security-sast--7464275-6ovw
[Aikido] AI Fix for Path traversal attack possible
2025-09-16 20:43:33 +01:00
Dimitrij
eb535cad2c Merge pull request #2800 from mRemoteNG/fix/aikido-security-sast--7464234-hobo
[Aikido] AI Fix for Path traversal attack possible
2025-09-16 20:43:01 +01:00
Dimitrij
eff00033b0 Merge pull request #2799 from mRemoteNG/fix/aikido-security-sast--7464163-cUFL
[Aikido] AI Fix for 3rd party Github Actions should be pinned
2025-09-16 20:42:19 +01:00
aikido-autofix[bot]
b591f97297 fix(security): autofix Path traversal attack possible 2025-09-16 16:09:27 +00:00
aikido-autofix[bot]
9501bb4428 fix(security): autofix Path traversal attack possible 2025-09-16 16:09:01 +00:00
aikido-autofix[bot]
4e9757c743 fix(security): autofix Path traversal attack possible 2025-09-16 16:08:34 +00:00
aikido-autofix[bot]
8f35b2ef71 fix(security): autofix Path traversal attack possible 2025-09-16 16:05:48 +00:00
aikido-autofix[bot]
3782eeeaf1 fix(security): autofix Path traversal attack possible 2025-09-16 16:04:39 +00:00
aikido-autofix[bot]
ec78de7a74 fix(security): autofix 3rd party Github Actions should be pinned 2025-09-16 16:02:43 +00:00
Dimitrij
bd1f311d09 CET compatibility
NB release
2025-09-16 12:03:15 +01:00
Dimitrij
31bf36db89 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-09-16 11:09:45 +01:00
Dimitrij
a96d344c22 adding missed தமிழ் (ta) Translation update #2690 from 1.77.3 branch 2025-09-16 11:09:37 +01:00
Dimitrij
dac4988514 Merge pull request #2797 from mRemoteNG/renovate/newtonsoft.json-13.x
chore(deps): update dependency newtonsoft.json to 13.0.4
2025-09-16 10:33:04 +01:00
renovate[bot]
a1f50f152c chore(deps): update dependency newtonsoft.json to 13.0.4 2025-09-16 08:54:55 +00:00
Dimitrij
06a47f4a06 Merge pull request #2795 from simonai1254/patch-1
Update minimum requirements
2025-09-16 09:40:32 +01:00
Simon Monai
f7aa9f7b92 Update README.md - Minimum Requirements
Update minimum Requirements to properly show .Net 9.0 and clarify Terminal Service Client requirements
2025-09-16 02:11:41 +02:00
Simon Monai
894b11704c Update README.md
Update .NET Runtime Requirements (9.0) for new version and remove Visual C++ Redistributables as the appear to no longer be necessary
2025-09-16 02:04:51 +02:00
Dimitrij
5b1b6ddc73 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-09-15 23:40:21 +01:00
Dimitrij
baa5abab2e clenup 2025-09-15 23:40:13 +01:00
Dimitrij
1b2ae29f4a Merge pull request #2793 from mRemoteNG/renovate/gherkin-35.x
chore(deps): update dependency gherkin to v35
2025-09-15 23:34:18 +01:00
Dimitrij
99a2b968d5 Merge pull request #2792 from mRemoteNG/renovate/actions-checkout-5.x
chore(deps): update actions/checkout action to v5
2025-09-15 23:34:04 +01:00
Dimitrij
029672a907 lib update, NB release 2025-09-15 23:32:42 +01:00
Dimitrij
31ecbaa977 .Net version detection fix
optimization
2025-09-15 23:32:06 +01:00
Dimitrij
6580e1b6db Enhance Build_mR-NB.yml with workflow_dispatch
Add manual dispatch option with release flag to workflow
2025-09-15 21:14:20 +01:00
renovate[bot]
16bbe4ccc0 chore(deps): update dependency gherkin to v35 2025-09-14 09:57:40 +00:00
renovate[bot]
6ea3642700 chore(deps): update actions/checkout action to v5 2025-09-14 09:57:36 +00:00
renovate[bot]
b8270d2264 chore(deps): update dependency reportgenerator to 5.4.13 2025-09-13 21:15:42 +00:00
Dimitrij
7b7fe1b062 Merge pull request #2787 from mRemoteNG/renovate/google.protobuf-3.x
chore(deps): update dependency google.protobuf to 3.32.1
2025-09-13 21:44:52 +01:00
Dimitrij
e67c97cc21 Update workflow to trigger on specific branch 2025-09-13 21:40:37 +01:00
Dimitrij
1033214658 Merge pull request #2786 from mRemoteNG/renovate/awssdk.core-4.x
chore(deps): update dependency awssdk.core to 4.0.0.27
2025-09-13 21:38:16 +01:00
Dimitrij
55552ad118 Update workflow to handle default branch and PR merges 2025-09-13 21:32:40 +01:00
renovate[bot]
552c53b15d chore(deps): update dependency google.protobuf to 3.32.1 2025-09-13 19:30:23 +00:00
renovate[bot]
278fc30ae8 chore(deps): update dependency awssdk.core to 4.0.0.27 2025-09-13 19:30:19 +00:00
Dimitrij
80fb676763 Merge pull request #2779 from mRemoteNG/renovate/system.io.pipelines-9.x
chore(deps): update dependency system.io.pipelines to 9.0.9
2025-09-13 15:31:41 +01:00
Dimitrij
c511fd1895 Merge branch 'v1.78.2-dev' into renovate/system.io.pipelines-9.x 2025-09-13 15:31:35 +01:00
Dimitrij
e43a644eb0 Merge pull request #2777 from mRemoteNG/renovate/system.drawing.common-9.x
chore(deps): update dependency system.drawing.common to 9.0.9
2025-09-13 15:30:57 +01:00
Dimitrij
70c16caf6b Merge branch 'v1.78.2-dev' into renovate/system.drawing.common-9.x 2025-09-13 15:30:50 +01:00
Dimitrij
21dcfc9435 Merge pull request #2775 from mRemoteNG/renovate/system.diagnostics.eventlog-9.x
chore(deps): update dependency system.diagnostics.eventlog to 9.0.9
2025-09-13 15:29:45 +01:00
Dimitrij
56ff019185 Merge branch 'v1.78.2-dev' into renovate/system.diagnostics.eventlog-9.x 2025-09-13 15:29:39 +01:00
Dimitrij
44a6cb31aa Merge pull request #2780 from mRemoteNG/renovate/system.management-9.x
chore(deps): update dependency system.management to 9.0.9
2025-09-13 15:28:14 +01:00
Dimitrij
a01ebdaa9d Merge pull request #2781 from mRemoteNG/renovate/system.reflection.metadata-9.x
chore(deps): update dependency system.reflection.metadata to 9.0.9
2025-09-13 15:27:57 +01:00
Dimitrij
651b742cc2 Merge pull request #2778 from mRemoteNG/renovate/system.formats.asn1-9.x
chore(deps): update dependency system.formats.asn1 to 9.0.9
2025-09-13 15:27:46 +01:00
Dimitrij
e2b1eb6e4a Merge pull request #2783 from mRemoteNG/renovate/system.security.cryptography.protecteddata-9.x
chore(deps): update dependency system.security.cryptography.protecteddata to 9.0.9
2025-09-13 15:27:25 +01:00
Dimitrij
2546620c8d Merge pull request #2784 from mRemoteNG/renovate/system.security.permissions-9.x
chore(deps): update dependency system.security.permissions to 9.0.9
2025-09-13 15:26:46 +01:00
Dimitrij
826f75348c Merge pull request #2776 from mRemoteNG/renovate/system.directoryservices-9.x
chore(deps): update dependency system.directoryservices to 9.0.9
2025-09-13 15:26:33 +01:00
Dimitrij
b27462da05 Merge pull request #2774 from mRemoteNG/renovate/system.diagnostics.diagnosticsource-9.x
chore(deps): update dependency system.diagnostics.diagnosticsource to 9.0.9
2025-09-13 15:26:04 +01:00
renovate[bot]
ad0ade5dd4 chore(deps): update dependency system.security.permissions to 9.0.9 2025-09-10 12:52:32 +00:00
renovate[bot]
6e3cf4630e chore(deps): update dependency system.security.cryptography.protecteddata to 9.0.9 2025-09-10 12:52:28 +00:00
renovate[bot]
6f3768db4b chore(deps): update dependency system.reflection.metadata to 9.0.9 2025-09-10 09:01:05 +00:00
renovate[bot]
98220ccf93 chore(deps): update dependency system.management to 9.0.9 2025-09-10 09:01:01 +00:00
renovate[bot]
52688d7145 chore(deps): update dependency system.io.pipelines to 9.0.9 2025-09-10 06:31:41 +00:00
renovate[bot]
b24edae66b chore(deps): update dependency system.formats.asn1 to 9.0.9 2025-09-10 06:31:37 +00:00
renovate[bot]
ac39ce26ee chore(deps): update dependency system.drawing.common to 9.0.9 2025-09-10 03:14:02 +00:00
renovate[bot]
cf041c661b chore(deps): update dependency system.directoryservices to 9.0.9 2025-09-10 03:13:59 +00:00
Dimitrij
9d173d0bdc Refactor GitHub Actions workflow for changelog updates 2025-09-10 00:07:43 +01:00
Dimitrij
aafb608149 Update GitHub Actions workflow for Renovate PRs 2025-09-09 23:27:09 +01:00
renovate[bot]
04dd125ee6 chore(deps): update dependency system.diagnostics.eventlog to 9.0.9 2025-09-09 22:25:19 +00:00
renovate[bot]
e501235b2e chore(deps): update dependency system.diagnostics.diagnosticsource to 9.0.9 2025-09-09 22:25:15 +00:00
Dimitrij
7c6a322787 Refactor GitHub Actions workflow for changelog updates 2025-09-09 23:16:32 +01:00
Dimitrij
eed729181b Update workflow for changelog generation 2025-09-09 22:48:02 +01:00
Dimitrij
ce9d42d304 Merge pull request #2773 from mRemoteNG/renovate/system.configuration.configurationmanager-9.x
chore(deps): update dependency system.configuration.configurationmanager to 9.0.9
2025-09-09 22:30:13 +01:00
Dimitrij
733e31e54b Merge branch 'v1.78.2-dev' into renovate/system.configuration.configurationmanager-9.x 2025-09-09 22:30:02 +01:00
Dimitrij
f1714f3228 Update workflow to modify changelog after PR merge 2025-09-09 21:17:05 +01:00
Dimitrij
44c90f0de4 Fix variable interpolation in changelog update
upd
2025-09-09 21:01:48 +01:00
Dimitrij
8268310685 added new section 2025-09-09 20:58:56 +01:00
Dimitrij
d64eaf6234 Refactor PR title extraction and changelog update
upd
2025-09-09 20:57:26 +01:00
Dimitrij
4d0b848676 Update workflow to handle Renovate PRs on push
upd
2025-09-09 20:53:23 +01:00
Dimitrij
d508ca33c8 Merge pull request #2772 from mRemoteNG/renovate/system.collections.immutable-9.x
chore(deps): update dependency system.collections.immutable to 9.0.9
2025-09-09 20:29:34 +01:00
renovate[bot]
86fdea129b chore(deps): update dependency system.configuration.configurationmanager to 9.0.9 2025-09-09 18:30:04 +00:00
renovate[bot]
79af98845a chore(deps): update dependency system.collections.immutable to 9.0.9 2025-09-09 18:29:59 +00:00
Dimitrij
2c15c6b0ed Merge pull request #2771 from mRemoteNG/renovate/microsoft.extensions.dependencymodel-9.x
chore(deps): update dependency microsoft.extensions.dependencymodel to 9.0.9
2025-09-09 18:18:31 +01:00
Dimitrij
52ee10efda Merge branch 'v1.78.2-dev' into renovate/microsoft.extensions.dependencymodel-9.x 2025-09-09 18:18:19 +01:00
Dimitrij
2da7d02a2c Update GitHub Actions workflow for PRs
update
2025-09-09 17:50:38 +01:00
Dimitrij
7af4ba27f3 Merge pull request #2770 from mRemoteNG/renovate/microsoft.extensions.configuration.usersecrets-9.x
chore(deps): update dependency microsoft.extensions.configuration.usersecrets to 9.0.9
2025-09-09 17:42:16 +01:00
Dimitrij
46cd974a58 Update changelog update workflow
Fix sed command to append entries in CHANGELOG.md
2025-09-09 17:35:32 +01:00
renovate[bot]
3d791b7f78 chore(deps): update dependency microsoft.extensions.dependencymodel to 9.0.9 2025-09-09 14:33:54 +00:00
renovate[bot]
29e27c1283 chore(deps): update dependency microsoft.extensions.configuration.usersecrets to 9.0.9 2025-09-09 14:33:49 +00:00
Dimitrij
8434ab460c Merge pull request #2768 from mRemoteNG/renovate/cucumber.messages-29.x
chore(deps): update dependency cucumber.messages to v29
2025-09-08 18:02:21 +01:00
Dimitrij
561d073bba Merge pull request #2767 from mRemoteNG/renovate/microsoft.web.webview2-1.x
chore(deps): update dependency microsoft.web.webview2 to 1.0.3485.44
2025-09-08 18:02:09 +01:00
renovate[bot]
d46d37acb9 chore(deps): update dependency cucumber.messages to v29 2025-09-08 14:50:37 +00:00
renovate[bot]
4f4d841137 chore(deps): update dependency microsoft.web.webview2 to 1.0.3485.44 2025-09-08 14:50:33 +00:00
Dimitrij
b7e80ceee9 Merge pull request #2766 from Greenie0701/fix_win_ci
ci: fix T4 template transform by adding EnvDTE & Interop references
2025-09-08 09:20:00 +01:00
Wise Man
8a3112c71f ci: fix T4 template transform by adding EnvDTE & Interop references 2025-09-07 09:28:45 +05:30
Dimitrij
4276b1439b Merge pull request #2765 from mRemoteNG/renovate/awssdk.ec2-4.x
Update dependency AWSSDK.EC2 to 4.0.37
2025-09-05 10:38:42 +01:00
renovate[bot]
3f626149f4 Update dependency AWSSDK.EC2 to 4.0.37 2025-09-04 20:57:09 +00:00
Dimitrij
30b674f8f5 .net check 2025-08-31 01:12:03 +01:00
Dimitrij
fe3fb46e94 undo 2025-08-28 18:15:07 +01:00
Dimitrij
99c524c7b6 fix? 2025-08-28 18:08:26 +01:00
Dimitrij
5da7a582bf Fix indentation and formatting in Build_mR-NB.yml
try to fix
2025-08-28 18:07:27 +01:00
Dimitrij
229c46a0c1 temporary disable Platform variable 2025-08-28 17:17:15 +01:00
Dimitrij
78d347889b Merge pull request #2762 from mRemoteNG/renovate/awssdk.ec2-4.x
Update dependency AWSSDK.EC2 to 4.0.33
2025-08-27 10:01:59 +01:00
renovate[bot]
244741ba15 Update dependency AWSSDK.EC2 to 4.0.33 2025-08-26 22:45:48 +00:00
Dimitrij
015fa601a3 Merge pull request #2761 from mRemoteNG/renovate/awssdk.ec2-4.x
Update dependency AWSSDK.EC2 to 4.0.32
2025-08-26 08:48:27 +01:00
renovate[bot]
1bd9e44ecb Update dependency AWSSDK.EC2 to 4.0.32 2025-08-25 22:33:55 +00:00
Dimitrij
dc7cfdb762 Merge pull request #2759 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-arm64-139.x
Update dependency chromiumembeddedframework.runtime.win-arm64 to v139
2025-08-25 00:09:27 +01:00
Dimitrij
36afbae5af Merge pull request #2760 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-x64-139.x
Update dependency chromiumembeddedframework.runtime.win-x64 to v139
2025-08-25 00:09:05 +01:00
Dimitrij
89d56a10f0 Merge pull request #2758 from mRemoteNG/renovate/log4net-3.x
Update dependency log4net to 3.2.0
2025-08-25 00:08:51 +01:00
Dimitrij
8dcc6031e6 Merge pull request #2757 from mRemoteNG/renovate/awssdk.core-4.x
Update dependency AWSSDK.Core to 4.0.0.25
2025-08-25 00:08:37 +01:00
renovate[bot]
b524a5424a Update dependency chromiumembeddedframework.runtime.win-x64 to v139 2025-08-23 08:58:53 +00:00
renovate[bot]
f06ad99658 Update dependency chromiumembeddedframework.runtime.win-arm64 to v139 2025-08-23 08:58:48 +00:00
renovate[bot]
f4ad61a41b Update dependency log4net to 3.2.0 2025-08-22 23:46:53 +00:00
renovate[bot]
3c948aca96 Update dependency AWSSDK.Core to 4.0.0.25 2025-08-22 23:46:49 +00:00
Dimitrij
57ee792198 Merge pull request #2755 from mRemoteNG/renovate/awssdk.ec2-4.x
Update dependency AWSSDK.EC2 to 4.0.31.1
2025-08-22 00:51:18 +01:00
renovate[bot]
6d84364cec Update dependency AWSSDK.EC2 to 4.0.31.1 2025-08-21 23:51:10 +00:00
Dimitrij
d74fc16cfd Merge pull request #2754 from mRemoteNG/renovate/awssdk.core-4.x
Update dependency AWSSDK.Core to 4.0.0.24
2025-08-22 00:50:48 +01:00
renovate[bot]
56d72cb30b Update dependency AWSSDK.Core to 4.0.0.24 2025-08-21 23:40:29 +00:00
Dimitrij
2f6f03ce8f Merge pull request #2740 from mRemoteNG/renovate/nunit.console-3.x
Update dependency NUnit.Console to 3.20.1
2025-08-21 13:10:46 +01:00
renovate[bot]
b437ff3dcc Update dependency NUnit.Console to 3.20.1 2025-08-21 12:09:49 +00:00
Dimitrij
93d17c2c35 Merge pull request #2741 from mRemoteNG/renovate/nunit.consolerunner-3.x
Update dependency NUnit.ConsoleRunner to 3.20.1
2025-08-21 13:09:37 +01:00
Dimitrij
b70ea04f02 Merge pull request #2749 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-x64-138.x
Update dependency chromiumembeddedframework.runtime.win-x64 to v138
2025-08-21 13:09:23 +01:00
Dimitrij
89cde8b518 Merge pull request #2748 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-arm64-138.x
Update dependency chromiumembeddedframework.runtime.win-arm64 to v138
2025-08-21 13:09:07 +01:00
Dimitrij
8d78623730 Merge pull request #2747 from mRemoteNG/renovate/actions-checkout-5.x
Update actions/checkout action to v5
2025-08-21 13:08:54 +01:00
Dimitrij
4a5b05f669 Merge pull request #2751 from mRemoteNG/renovate/softprops-action-gh-release-2.x
Update softprops/action-gh-release action to v2
2025-08-21 13:08:40 +01:00
Dimitrij
c4f2b7ed2e Merge pull request #2745 from mRemoteNG/renovate/nunit3testadapter-5.x
Update dependency NUnit3TestAdapter to 5.1.0
2025-08-21 13:08:21 +01:00
renovate[bot]
e296c77b14 Update dependency chromiumembeddedframework.runtime.win-x64 to v138 2025-08-21 12:06:56 +00:00
Dimitrij
56611c6e41 Merge pull request #2752 from mRemoteNG/renovate/microsoft.extensions.dependencymodel-9.x
Update dependency Microsoft.Extensions.DependencyModel to 9.0.8
2025-08-21 13:06:56 +01:00
renovate[bot]
1e216b8cb3 Update dependency chromiumembeddedframework.runtime.win-arm64 to v138 2025-08-21 12:06:52 +00:00
renovate[bot]
302700ac80 Update dependency Microsoft.Extensions.DependencyModel to 9.0.8 2025-08-21 12:06:45 +00:00
Dimitrij
cc5d943a86 Merge pull request #2753 from mRemoteNG/renovate/microsoft.net.test.sdk-17.x
Update dependency Microsoft.NET.Test.Sdk to 17.14.1
2025-08-21 13:06:32 +01:00
Dimitrij
7942f93649 Merge pull request #2744 from mRemoteNG/renovate/nunit-4.x
Update dependency NUnit to 4.4.0
2025-08-21 13:05:51 +01:00
Dimitrij
270c6dd64b Merge pull request #2750 from mRemoteNG/renovate/gherkin-34.x
Update dependency Gherkin to v34
2025-08-21 13:05:33 +01:00
Dimitrij
9f1633bc63 Merge pull request #2746 from mRemoteNG/renovate/actions-cache-4.x
Update actions/cache action to v4
2025-08-21 13:05:20 +01:00
Dimitrij
8953ec0e1f Merge pull request #2738 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-x64-92.x
Update dependency chromiumembeddedframework.runtime.win-x64 to 92.0.26
2025-08-21 13:05:03 +01:00
Dimitrij
8f5dd3bc93 Merge pull request #2737 from mRemoteNG/renovate/chromiumembeddedframework.runtime.win-arm64-92.x
Update dependency chromiumembeddedframework.runtime.win-arm64 to 92.0.26
2025-08-21 13:04:45 +01:00
renovate[bot]
97ee6e6ee0 Update dependency Microsoft.NET.Test.Sdk to 17.14.1 2025-08-21 12:04:12 +00:00
renovate[bot]
ae626294f3 Update softprops/action-gh-release action to v2 2025-08-21 11:39:30 +00:00
renovate[bot]
842a45aa17 Update dependency Gherkin to v34 2025-08-21 11:39:26 +00:00
renovate[bot]
686936e7b2 Update actions/checkout action to v5 2025-08-21 11:39:15 +00:00
renovate[bot]
8ac8ad6ed9 Update actions/cache action to v4 2025-08-21 11:39:12 +00:00
renovate[bot]
e7eda49676 Update dependency NUnit3TestAdapter to 5.1.0 2025-08-21 11:39:09 +00:00
renovate[bot]
faae8c7a77 Update dependency NUnit to 4.4.0 2025-08-21 11:39:05 +00:00
renovate[bot]
5cb67a6e09 Update dependency NUnit.ConsoleRunner to 3.20.1 2025-08-21 11:38:52 +00:00
renovate[bot]
06747dc38d Update dependency chromiumembeddedframework.runtime.win-x64 to 92.0.26 2025-08-21 11:38:41 +00:00
renovate[bot]
c3813fd87b Update dependency chromiumembeddedframework.runtime.win-arm64 to 92.0.26 2025-08-21 11:38:34 +00:00
Dimitrij
901584a2e4 upd 2025-08-21 01:21:42 +01:00
Dimitrij
f9e33c7fca fix 2025-08-21 00:49:09 +01:00
Dimitrij
ea36ca37f0 Merge pull request #2736 from asherbiny/v1.78.2-dev
Change Default RDP Version to v10
2025-08-21 00:18:39 +01:00
Dimitrij
2ea06f3096 add include 2025-08-21 00:16:13 +01:00
Dimitrij
dc208973c8 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-21 00:03:44 +01:00
Dimitrij
18ddb1001b one more fix 2025-08-21 00:03:37 +01:00
Dimitrij
567bc4a112 Update Build_mR-NB.yml
fix step 1
2025-08-20 23:29:46 +01:00
Dimitrij
c5dbf5a412 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-20 23:21:00 +01:00
Dimitrij
c084e66db5 fix path attribute (finger cross) 2025-08-20 23:20:53 +01:00
Ahmed ElSherbiny
bb6d35f91f Change Default RDP Version to v10
Problem I'm solving:
When importing RDP files, mRemoteNG defaults to RDPv6 (which is extremely old, and particularly does not support Gateway access tokens). Thus I would have to manually change the config to a newer RDP protocol, so that I could initiate  the connection.

It is safe to assume that the majority of Windows PCs on the internet today are running Windows 10 or above, and by keeping the default at RDP6 we are causing more unnecessary friction to those majority users.

I've changed the default to Rdp10 (released in Windows 10).
https://en.wikipedia.org/wiki/Remote_Desktop_Protocol#Version_10.0
2025-08-20 15:05:09 -07:00
Dimitrij
ac59bc2999 Update Build_mR-NB.yml
upd
2025-08-20 23:03:30 +01:00
Dimitrij
7dfb1d395d Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-20 22:59:49 +01:00
Dimitrij
46672ca976 adjustment 2025-08-20 22:59:42 +01:00
Dimitrij
94e7e23cda Update Build_mR-NB.yml
extend t4 step
2025-08-20 22:58:08 +01:00
Dimitrij
2fa0ca41d6 adjustment 2025-08-20 22:51:50 +01:00
Dimitrij
2ebe35c6d6 amendments 2025-08-20 22:42:42 +01:00
Dimitrij
354066de0b corrections 2025-08-20 22:39:22 +01:00
Dimitrij
3d3c1f8f23 fix to local 2025-08-20 22:31:09 +01:00
Dimitrij
24448d604d fix path 2025-08-20 22:25:16 +01:00
Dimitrij
7d8e530ebf add EnvDTE 2025-08-20 22:22:29 +01:00
Dimitrij
5db88040cc lib update 2025-08-20 22:06:21 +01:00
Dimitrij
d9de6e78d7 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-20 21:54:55 +01:00
Dimitrij
da136bfebd update .tt template to include platform type 2025-08-20 21:54:47 +01:00
Dimitrij
6657063441 Update Build_mR-NB.yml
upd
2025-08-19 22:38:42 +01:00
Dimitrij
47e6d4d711 test 2025-08-19 22:32:07 +01:00
Dimitrij
32c7bd2627 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-19 22:12:06 +01:00
Dimitrij
3422d064ac change to set platform type 2025-08-19 22:11:58 +01:00
Dimitrij
0b01d40a85 Update Build_mR-NB.yml
override platform depending on build platform
2025-08-19 22:11:20 +01:00
Dimitrij
7f79dc6098 upd 2025-08-19 19:22:46 +01:00
Dimitrij
ac7590f23c Merge pull request #2734 from Mugundanmcw/fix_x64
fix native build for Windows-x64
2025-08-19 19:20:07 +01:00
Mugu~~
998bd3a1a9 fix native build for windows-x64 2025-08-19 23:43:53 +05:30
Dimitrij
0f62f1d72c update to signed version 2025-08-19 00:28:14 +01:00
Dimitrij
cb1b1a5cac lib updates 2025-08-18 08:29:03 +01:00
Dimitrij
63ccdd0a23 Merge pull request #2728 from Mugundanmcw/win_arm64
Add support for building mRemoteNG on Windows ARM64
2025-08-18 08:25:40 +01:00
Dimitrij
ead809cc90 Update mRemoteNG/mRemoteNG.csproj
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 08:23:54 +01:00
Dimitrij
dfd4851bf1 Update ObjectListView/ObjectListView.NetCore.csproj
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 08:23:44 +01:00
Mugu~~
e50f11697f Add support for building mRemoteNG on Windows ARM64 2025-08-17 20:23:35 +05:30
Dimitrij
4800ad53dc Create post_2_Reddit.yml
bump
2025-08-15 13:08:32 +01:00
Dimitrij
9349c3f055 Lib update 2025-08-15 12:19:35 +01:00
Dimitrij
d7a82ae911 Update Build_mR-NB.yml
fix
2025-08-15 11:06:28 +01:00
Dimitrij
b3354fb033 Update Build_mR-NB.yml
fix
2025-08-15 10:51:18 +01:00
Dimitrij
9b56b11c9b Update Build_mR-NB.yml
upd
2025-08-15 10:41:58 +01:00
Dimitrij
15247c3637 Update Build_mR-NB.yml
update actions
2025-08-14 22:37:37 +01:00
Dimitrij
4311d3b057 Update Build_mR-NB.yml
update action
2025-08-14 22:26:37 +01:00
Dimitrij
076db0637f Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-14 22:04:38 +01:00
Dimitrij
8a7108910d Update Change log 2025-08-14 22:04:30 +01:00
Dimitrij
be12600094 Update Build_mR-NB.yml
upd
2025-08-14 21:48:17 +01:00
Dimitrij
988305100d Update Build_mR-NB.yml
Update Action
2025-08-14 21:38:17 +01:00
Dimitrij
16ae28ee62 Update Build_mR-NB.yml
upd
2025-08-14 21:16:09 +01:00
Dimitrij
30aab57bc9 Update Build_mR-NB.yml
fix
2025-08-14 21:04:34 +01:00
Dimitrij
a573914668 Update Build_mR-NB.yml
test
2025-08-14 20:50:12 +01:00
Dimitrij
83771cc2e6 Update Build_mR-NB.yml
text
2025-08-14 20:28:09 +01:00
Dimitrij
d8eaba75d2 Update Build_mR-NB.yml
test
2025-08-14 13:06:34 +01:00
Dimitrij
96f917a1ab Update Build_mR-NB.yml
fix
2025-08-14 12:47:43 +01:00
Dimitrij
44d81a6bdf Update Build_mR-NB.yml
test
2025-08-14 12:33:12 +01:00
Dimitrij
1b0e8440ae Update Build_mR-NB.yml
test
2025-08-14 12:22:48 +01:00
Dimitrij
e236dbe661 Update Build_mR-NB.yml
test
2025-08-14 12:14:45 +01:00
Dimitrij
2ba7d09c21 Update Build_mR-NB.yml
test
2025-08-14 12:09:44 +01:00
Dimitrij
2b937689bd Update Build_mR-NB.yml
fix
2025-08-14 12:01:51 +01:00
Dimitrij
eeb7eb7ad2 Update Build_mR-NB.yml
test
2025-08-14 11:43:13 +01:00
Dimitrij
c8e29211eb Update Build_mR-NB.yml
test
2025-08-14 11:35:03 +01:00
Dimitrij
57cce7ec22 Update Build_mR-NB.yml
test
2025-08-14 11:23:18 +01:00
Dimitrij
78af721250 Update Build_mR-NB.yml
tst
2025-08-14 11:09:40 +01:00
Dimitrij
cba6c2dacc Update Build_mR-NB.yml
test
2025-08-14 11:08:56 +01:00
Dimitrij
b4b12cdbdc Update Build_mR-NB.yml
fix
2025-08-14 03:20:48 +01:00
Dimitrij
e7c86c95fe Update Build_mR-NB.yml
fix
2025-08-14 03:17:03 +01:00
Dimitrij
f28d96e91a Update Build_mR-NB.yml
fix
2025-08-14 03:09:46 +01:00
Dimitrij
b25217dd38 Update Build_mR-NB.yml
fix token
2025-08-14 02:53:55 +01:00
Dimitrij
f60da8665b Update Build_mR-NB.yml
add token
2025-08-14 02:47:39 +01:00
Dimitrij
3d8daff050 Update Build_mR-NB.yml
fix
2025-08-14 02:43:14 +01:00
Dimitrij
c41f3c21c1 Update Build_mR-NB.yml
fix
2025-08-14 02:29:19 +01:00
Dimitrij
8e7897bf76 Update Build_mR-NB.yml
fix
2025-08-14 02:17:48 +01:00
Dimitrij
050bf75fdd Update Build_mR-NB.yml
fix
2025-08-14 02:13:49 +01:00
Dimitrij
1bbfcd0a7c Update Build_mR-NB.yml
fix
2025-08-14 01:51:43 +01:00
Dimitrij
30106d0006 Update Build_mR-NB.yml
fix
2025-08-14 01:46:26 +01:00
Dimitrij
16974068d7 Update Build_mR-NB.yml
fix
2025-08-14 01:41:53 +01:00
Dimitrij
08d0f67062 Update Build_mR-NB.yml
fix
2025-08-14 01:23:26 +01:00
Dimitrij
2edcb5863c Update Build_mR-NB.yml
fix
2025-08-14 01:19:57 +01:00
Dimitrij
44b9e49a54 Update Build_mR-NB.yml
fix
2025-08-14 01:13:33 +01:00
Dimitrij
0175903f51 Update Build_mR-NB.yml
fix date
2025-08-14 00:52:28 +01:00
Dimitrij
0ef282f89c Update Build_mR-NB.yml
fix
2025-08-14 00:51:48 +01:00
Dimitrij
b4eec7d44c Update Build_mR-NB.yml
fix and upd
2025-08-14 00:39:41 +01:00
Dimitrij
2e040a39db Update Build_mR-NB.yml
upd
2025-08-14 00:30:37 +01:00
Dimitrij
7e0ee705ff Update Build_mR-NB.yml
upd
2025-08-14 00:28:37 +01:00
Dimitrij
361005e242 Update Build_mR-NB.yml
fix
2025-08-14 00:17:37 +01:00
Dimitrij
2ea26f7319 Update Build_mR-NB.yml
fix
2025-08-14 00:04:56 +01:00
Dimitrij
44c4ca232f Update Build_mR-NB.yml
fix 11
2025-08-13 23:57:16 +01:00
Dimitrij
f7bb45288e Update Build_mR-NB.yml
fix10
2025-08-13 23:50:46 +01:00
Dimitrij
c99aa41744 Update Build_mR-NB.yml
fix 9
2025-08-13 23:43:09 +01:00
Dimitrij
4eb1cc939c Update Build_mR-NB.yml
remove raw
2025-08-13 23:32:33 +01:00
Dimitrij
d4c51f18f5 Update Build_mR-NB.yml
fix8
2025-08-13 22:14:35 +01:00
Dimitrij
af89c8bba7 Update Build_mR-NB.yml
fix 6
2025-08-13 22:12:02 +01:00
Dimitrij
2e951ef0db Update Build_mR-NB.yml
fix5
2025-08-13 22:06:33 +01:00
Dimitrij
80b82366c4 Update Build_mR-NB.yml
fix4
2025-08-13 22:00:23 +01:00
Dimitrij
3d75eae9c0 Update Build_mR-NB.yml
fix3
2025-08-13 21:52:19 +01:00
Dimitrij
0bd8d9c4ca Update Build_mR-NB.yml
fix2
2025-08-13 19:55:06 +01:00
Dimitrij
b3c1132a25 Update Build_mR-NB.yml
fix
2025-08-13 19:07:42 +01:00
Dimitrij
bddcb16e8a Update Build_mR-NB.yml
fix folder path
2025-08-13 18:57:49 +01:00
Dimitrij
3cb2ba6fa3 Update Build_mR-NB.yml
correct path
2025-08-13 18:47:50 +01:00
Dimitrij
205c8914ed Update Build_mR-NB.yml
upd
2025-08-13 18:38:50 +01:00
Dimitrij
76e0b67599 Update Build_mR-NB.yml
removed !!!
2025-08-13 18:26:51 +01:00
Dimitrij
2c617b230a Update and rename Build mR-NB.yml to Build_mR-NB.yml
update a name
2025-08-13 18:23:26 +01:00
Dimitrij
72d3268d39 lib update 2025-08-13 18:19:40 +01:00
Dimitrij
a093a77610 Merge pull request #2723 from asherbiny/v1.78.2-dev
Read keyboardhook, gatewayaccesstoken and gatewaycredentialssource from RDP File
2025-08-12 10:03:24 +01:00
asherbiny
a9c6443c18 Merge branch 'v1.78.2-dev' into v1.78.2-dev 2025-08-08 11:45:29 -05:00
Ahmed ElSherbiny
757932ed4a Add comment for duplicate cases
Cases 3 & 4 both require the user to manually enter Gateway credentials. Comment added for code readability.
2025-08-08 09:43:03 -07:00
Dimitrij
55aad85bdd Update Build mR-NB.yml
debug
2025-08-08 03:24:14 +01:00
Dimitrij
952d87f858 Update Build mR-NB.yml
add debug
2025-08-08 03:11:46 +01:00
Dimitrij
81fbe68e3b Update Build mR-NB.yml
fix
2025-08-08 02:58:11 +01:00
Dimitrij
c82cd15f24 Update Build mR-NB.yml
fix
2025-08-08 02:56:06 +01:00
Dimitrij
9991f7015f Update Build mR-NB.yml
fix
2025-08-08 02:53:39 +01:00
Dimitrij
e94fac0459 Update Build mR-NB.yml
fix permission
2025-08-08 02:52:00 +01:00
Dimitrij
816833c9f3 Update Build mR-NB.yml
fix 403
2025-08-08 02:51:17 +01:00
Dimitrij
a202d72cd6 Update Build mR-NB.yml
release fix
2025-08-08 02:44:53 +01:00
Dimitrij
0558b0621a Update Build mR-NB.yml
fix
2025-08-08 02:31:05 +01:00
Dimitrij
6e12b398d4 Update Build mR-NB.yml
fix
2025-08-08 02:24:21 +01:00
Dimitrij
cce9aa5e97 Update Build mR-NB.yml
fix
2025-08-08 02:19:47 +01:00
Dimitrij
6020122297 Update Build mR-NB.yml
another fix
2025-08-08 02:13:00 +01:00
Dimitrij
bed11116fe Update Build mR-NB.yml
zip name
2025-08-08 02:01:23 +01:00
Dimitrij
66cf93ffdd Update Build mR-NB.yml
upd
2025-08-08 01:45:09 +01:00
Dimitrij
8f1ca7dee2 Update Build mR-NB.yml
upd
2025-08-08 01:40:01 +01:00
Dimitrij
b24eac52ae Update Build mR-NB.yml
upd
2025-08-08 01:31:12 +01:00
Dimitrij
5aaa3a00b4 upd 2025-08-08 01:22:03 +01:00
Dimitrij
0d737228b0 upd tt 2025-08-08 01:18:15 +01:00
Dimitrij
f57c862c3c Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-08 01:15:40 +01:00
Dimitrij
ba476533ed upd template 2025-08-08 01:15:33 +01:00
Dimitrij
28b39688ec Update Build mR-NB.yml
fix
2025-08-08 01:10:31 +01:00
Dimitrij
fd8b1a8807 Update Build mR-NB.yml
fix prj name
2025-08-08 01:07:37 +01:00
Dimitrij
bff44b5d74 Update Build mR-NB.yml
upd
2025-08-08 01:06:02 +01:00
Dimitrij
a9ee32d020 Update and rename mR-NB.yml to Build mR-NB.yml
upd env
2025-08-08 01:03:26 +01:00
Dimitrij
4fd1864eef Update mR-NB.yml
replace texttransform wiht dotnet-t4
2025-08-08 01:01:14 +01:00
Dimitrij
3775279659 upd prj 2025-08-08 00:55:21 +01:00
Dimitrij
5bba633ab1 Merge branch 'v1.78.2-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.78.2-dev 2025-08-08 00:54:27 +01:00
Dimitrij
900cc0afe3 lib update 2025-08-08 00:54:19 +01:00
Dimitrij
29fa64825e Update mR-NB.yml
add TextTransform
2025-08-08 00:13:21 +01:00
Dimitrij
1c59404299 Update mR-NB.yml
fix
2025-08-07 23:59:25 +01:00
Dimitrij
563613be6b Update mR-NB.yml
upd to new build structure
2025-08-07 23:52:46 +01:00
Dimitrij
5ae2296400 Update mR-NB.yml
upd to latest VS
2025-08-07 23:31:44 +01:00
Dimitrij
9534ceccd9 Update and rename build-x86_64.yml to mR-NB.yml
update to latest and switch to new branch
2025-08-07 23:30:51 +01:00
asherbiny
878845941d Merge branch 'v1.78.2-dev' into v1.78.2-dev 2025-08-06 16:29:34 -05:00
Ahmed ElSherbiny
a5be2bb5b5 Read keyboardhook, gatewayaccesstoken and gatewaycredentialssource from RDP File
With this commit mRemoteNG, upon importing an RDP file, will read and apply those fields to the connection being imported.

Tested by verifying that the properties are reflected correctly in the UI (Config panel) and influence the behavior of the connection as expected.
2025-08-06 14:11:10 -07:00
Dimitrij
19c954f972 lib update 2025-08-05 15:33:16 +01:00
Dimitrij
576f9db387 lib upgrade 2025-07-29 22:33:30 +01:00
Dimitrij
28ff02f8cb Merge pull request #2715 from jcefoli/FixObjectListViewSerializerWarnings
Disable WinForms analyzers and suppress WFO1000 build errors for ObjectListView
2025-07-02 09:51:52 +01:00
Joe Cefoli
d4a590d292 Disable WinForms analyzers and suppress WFO1000 build errors 2025-07-01 15:01:44 -04:00
Dimitrij
25f928fc8a Merge pull request #2712 from caspChristian/imp2321
VNCEvent_Disconnected send the ProtocolBase based object reference
2025-06-26 13:31:53 +01:00
Christian Iwata Nilsson
5dd3d927d6 VNCEvent_Disconnected send the ProtocolBase based object reference
Fixes the exception mostly mentioned in #2321, but not the actual connection issues
2025-06-26 09:08:07 +02:00
Dimitrij
77950632f8 lib update 2025-06-23 14:08:48 +01:00
Dimitrij
e85cee752d few more 2025-06-11 23:38:36 +01:00
Dimitrij
5c48f13a27 fix warnings about null-able 2025-06-11 23:34:35 +01:00
Dimitrij
18b283db0a Lib updates 2025-06-11 20:14:52 +01:00
Dimitrij
ca7888a537 Lib update 2025-06-04 23:55:33 +01:00
Dimitrij
246e90acd1 lib update 2025-05-29 18:49:41 +01:00
Dimitrij
e58e33974a cosmetic changes 2025-05-29 18:49:20 +01:00
Dimitrij
5cb07d003c UI changes for DB Setup 2025-05-29 18:48:10 +01:00
Dimitrij
3ecedc8fcf Lib updates 2025-05-13 19:34:57 +01:00
Dimitrij
a88ed5d3a9 UI Changes related SQL server 2022 configuration
(partially done)
2025-04-10 01:03:56 +01:00
Dimitrij
37fead2076 Lib updates
(temporary removed test projects from solution)
2025-04-10 01:01:53 +01:00
Dimitrij
2770c761b2 fix for current version and released version comparison
small fixes in Language
amazon lib update
2025-04-02 13:19:10 +01:00
Dimitrij
4b28eb6758 patch to remove secure-string implementation (will need to be implemented differently)
what will temporary allow to type-in and edit passwords
2025-03-30 13:56:38 +01:00
Dimitrij
ba45b44f45 lib update 2025-03-30 13:04:24 +01:00
Dimitrij
f5186cbadd lib updates 2025-03-19 12:09:39 +00:00
Dimitrij
807924c51e fix for NETSDK1137 (https://learn.microsoft.com/en-us/dotnet/core/tools/sdk-errors/netsdk1137) 2025-03-10 10:59:11 +00:00
Dimitrij
155d849201 Lib update 2025-03-10 09:55:11 +00:00
Dimitrij
e9efd2705c Lib update 2025-03-01 15:24:00 +00:00
Dimitrij
204e0d041c fix to make _mRIdentifier class-level 2025-02-18 02:45:07 +00:00
Dimitrij
227d75d956 Add new method to generate a unique identifier for the machine 2025-02-18 02:20:37 +00:00
Dimitrij
d2706c8748 Switch to use central package version management 2025-02-18 01:58:43 +00:00
Dimitrij
2518b8600f System.Data.SqlClient package is now deprecated, migrated to Microsoft.Data.SqlClient. 2025-02-17 15:23:38 +00:00
Dimitrij
9300839d59 switch to .net9 2025-02-17 14:43:51 +00:00
211 changed files with 11972 additions and 6650 deletions

157
.github/workflows/Build_mR-NB.yml vendored Normal file
View File

@@ -0,0 +1,157 @@
name: Build_and_Release_mR-NB
on:
push:
branches:
- v1.78.2-dev
workflow_dispatch:
inputs:
release_flag:
description: 'Run NB release'
required: false
default: 'true'
permissions:
contents: write
jobs:
NB-Build-and-Release:
strategy:
matrix:
include:
- runner: windows-latest
platform: x64
arch: x64
- runner: windows-11-arm
platform: ARM64
arch: arm64
runs-on: ${{ matrix.runner }}
# Only run if:
# - manual dispatch, OR
# - push event AND commit message contains "NB release"
if: >
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'push' && contains(github.event.head_commit.message, 'NB release'))
steps:
- name: (01) Checkout Repository
uses: actions/checkout@v5
- name: (02) Setup MSBuild
uses: microsoft/setup-msbuild@v2
with:
vs-version: '17.14.12'
- name: (03) Install and run dotnet-t4 to transform T4 templates
shell: pwsh
run: |
dotnet tool install --global dotnet-t4
# Refresh PATH to include global tools
$env:PATH += ";$env:USERPROFILE\.dotnet\tools"
$ttFile = "$env:GITHUB_WORKSPACE\mRemoteNG\Properties\AssemblyInfo.tt"
# VS Enterprise 2022 assemblies
$vsPath = "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\PublicAssemblies"
Write-Host "Transforming T4 template"
t4 $ttFile -P platformType=${{ matrix.platform }} -r:"$vsPath\EnvDTE.dll" -r:"$vsPath\Microsoft.VisualStudio.Interop.dll"
env:
PLATFORM: '${{ matrix.platform }}'
- name: (04) Cache NuGet Packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-${{ matrix.arch }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-nuget-
- name: (05) Restore NuGet Packages
shell: pwsh
run: dotnet restore
- name: (06) Build Release
shell: pwsh
run: |
msbuild "$Env:GITHUB_WORKSPACE\mRemoteNG.sln" -p:Configuration="Release" -p:Platform=${{ matrix.platform }} /verbosity:minimal
- name: (07) Release Information
id: version
shell: pwsh
run: |
$assemblyInfoPath = "${{ github.workspace }}\mRemoteNG\Properties\AssemblyInfo.cs"
$line = Get-Content $assemblyInfoPath | Where-Object { $_ -match 'AssemblyVersion\("(.+?)"\)' }
if ($line -match 'AssemblyVersion\("(?<ver>\d+\.\d+\.\d+)\.(?<build>\d+)"\)') {
$version = $matches['ver']
$build = $matches['build']
} else {
throw "Could not extract version and build number"
}
$date = Get-Date -Format "yyyyMMdd"
$zipName = "mRemoteNG-$date-v$version-NB-$build-${{ matrix.arch }}.zip"
$tag = "$date-v$version-NB-($build)"
$message = git log -1 --pretty=%B
echo "message=$message" >> $env:GITHUB_OUTPUT
echo "zipname=$zipName" >> $env:GITHUB_OUTPUT
echo "version=$version" >> $env:GITHUB_OUTPUT
echo "build=$build" >> $env:GITHUB_OUTPUT
echo "tag=$tag" >> $env:GITHUB_OUTPUT
$version = "${{ steps.version.outputs.version }}"
- name: (08) Extract Changelog Section
id: changelog
shell: pwsh
run: |
$changelogPath = "$env:GITHUB_WORKSPACE\CHANGELOG.md"
$lines = Get-Content $changelogPath
$startIndex = -1
for ($i = 0; $i -lt $lines.Count; $i++) {
if ($lines[$i] -match '^## \[') {
$startIndex = $i
break
}
}
if ($startIndex -eq -1) {
throw "No version header found in CHANGELOG.md"
}
$section = @()
for ($i = $startIndex + 1; $i -lt $lines.Count; $i++) {
if ($lines[$i] -match '^## ') {
break
}
$section += $lines[$i]
}
$joined = $section -join "`n"
echo "log<<EOF" >> $env:GITHUB_OUTPUT
echo $joined >> $env:GITHUB_OUTPUT
echo "EOF" >> $env:GITHUB_OUTPUT
echo "log=$escaped"
- name: (09) Create Zip File
shell: pwsh
run: |
$sourceDir = "$Env:GITHUB_WORKSPACE\mRemoteNG\bin\${{ matrix.platform }}\Release"
Compress-Archive -Path "$sourceDir\*" -DestinationPath ${{ steps.version.outputs.zipname }}
echo "File: ${{ steps.version.outputs.zipname }}"
- name: (10) Create release
id: create_release
uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
tag_name: ${{ steps.version.outputs.tag }}
name: "mRemoteNG ${{ steps.version.outputs.version }} NB ${{ steps.version.outputs.build }}"
files: ${{ steps.version.outputs.zipname }}
body: |
Changes in this Release:
${{ steps.changelog.outputs.log }}
Last Commit Message:
${{ steps.version.outputs.message }}
draft: false
prerelease: true

126
.github/workflows/add_PR_2_chlog.yml vendored Normal file
View File

@@ -0,0 +1,126 @@
name: Update Changelog After Renovate PR Merge
on:
# 1) Auto on pushes to your repos default branch (merge commits included)
push:
branches:
- v1.78.2-dev
# 2) Manual trigger
workflow_dispatch:
inputs:
dryRun:
description: 'Run without committing changes'
required: false
default: 'true'
jobs:
update-changelog:
runs-on: ubuntu-latest
# Only proceed if…
# - manual dispatch
# - OR a push to default branch
if: |
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Check for Renovate dependency update
id: check-renovate
shell: bash
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "isRenovate=true" >> $GITHUB_OUTPUT
exit 0
fi
msg="$(git log -1 --pretty=%B)"
if echo "$msg" | grep -q 'chore(deps): update dependency'; then
echo "isRenovate=true" >> $GITHUB_OUTPUT
else
echo "isRenovate=false" >> $GITHUB_OUTPUT
fi
- name: Abort if not a Renovate PR
if: steps.check-renovate.outputs.isRenovate == 'false'
run: |
echo " Last commit is not a Renovate dependency update—skipping."
- name: Parse Renovate PR info
if: steps.check-renovate.outputs.isRenovate == 'true'
id: extract
shell: pwsh
run: |
# 1) Determine dryRun
$dryRun = '${{ github.event.inputs.dryRun }}'
if (-not $dryRun) { $dryRun = 'false' }
Write-Host "🔍 dryRun = $dryRun"
# 2) Read full commit message
$fullMsg = git log -1 --pretty=%B
Write-Host "📝 Commit message:"; Write-Host $fullMsg
# 3) Extract PR number
if ($fullMsg -match 'Merge pull request #(\d+)') {
$prNumber = $matches[1]
} else {
throw "❌ Could not locate PR number in merge commit"
}
# 4) Extract dependency name & version
if ($fullMsg -match 'chore\(deps\): update dependency ([\w\.\-]+) to ([\d\.]+)') {
$depName = $matches[1]
$depVersion = $matches[2]
} else {
throw "❌ Could not parse dependency name/version"
}
# 5) Export outputs
echo "pr=$prNumber" >> $env:GITHUB_OUTPUT
echo "depName=$depName" >> $env:GITHUB_OUTPUT
echo "depVersion=$depVersion" >> $env:GITHUB_OUTPUT
echo "dryRun=$dryRun" >> $env:GITHUB_OUTPUT
- name: Update CHANGELOG.md
if: steps.check-renovate.outputs.isRenovate == 'true'
shell: pwsh
run: |
$path = "$env:GITHUB_WORKSPACE/CHANGELOG.md"
if (-not (Test-Path $path)) { throw "❌ CHANGELOG.md not found" }
$lines = Get-Content $path
$pr = '${{ steps.extract.outputs.pr }}'
$dep = '${{ steps.extract.outputs.depName }}'
$ver = '${{ steps.extract.outputs.depVersion }}'
$entry = "- #$pr: update dependency $dep to $ver"
# Find latest version header: ## [x.y.z]
$vIndex = $lines.FindIndex({ $_ -match '^## \[\d+\.\d+\.\d+\]' })
if ($vIndex -lt 0) { throw "❌ No version header found" }
# Locate or create "### Dependency update"
$depIndex = -1
for ($i = $vIndex + 1; $i -lt $lines.Count; $i++) {
if ($lines[$i] -match '^### Dependency update') { $depIndex = $i; break }
if ($lines[$i] -match '^## ') { break }
}
if ($depIndex -eq -1) {
$lines.Insert($vIndex + 1, '### Dependency update')
$depIndex = $vIndex + 1
}
# Insert the changelog entry
$lines.Insert($depIndex + 1, $entry)
Set-Content -Path $path -Value $lines
Write-Host "✅ Inserted in CHANGELOG.md:"; Write-Host " $entry"
- name: Commit & push
if: steps.check-renovate.outputs.isRenovate == 'true' && steps.extract.outputs.dryRun != 'true'
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git add CHANGELOG.md
git commit -m "docs: update changelog for #${{ steps.extract.outputs.pr }}"
git push

View File

@@ -1,130 +0,0 @@
name: Build x86_64
on:
push:
branches:
- v1.77.3-dev
jobs:
Build-Debug-MSI:
runs-on: windows-2022
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1 # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
with:
vs-version: '17.12.4'
- name: 03. Restore nuget packages for solution
shell: pwsh
run: |
dotnet restore
- name: 04. Compile mRemoteNG
shell: pwsh
run: |
msbuild "$Env:GITHUB_WORKSPACE\mRemoteNG.sln" -p:Configuration="Debug Installer" -p:Platform=x64 /verbosity:normal
- name: 05. Publish MSI as Artifact
uses: actions/upload-artifact@v4
with:
name: debug-msi-x86_64
path: ${{ github.workspace }}\mRemoteNGInstaller\Installer\bin\x64\Debug\en-US\
if-no-files-found: error
Build-Debug-Portable:
runs-on: windows-2022
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1 # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
with:
vs-version: '17.8.3'
- name: 03. Restore nuget packages for solution
shell: pwsh
run: |
dotnet restore
- name: 04. Compile mRemoteNG
shell: pwsh
run: |
msbuild "$Env:GITHUB_WORKSPACE\mRemoteNG.sln" -p:Configuration="Debug Portable" -p:Platform=x64 /verbosity:normal
- name: 05. Publish Portable Binary as Artifact
uses: actions/upload-artifact@v4
with:
name: debug-portable-x86_64
path: ${{ github.workspace }}\mRemoteNG\bin\x64\Debug Portable\
if-no-files-found: error
Build-Release:
runs-on: windows-2022
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1 # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
with:
vs-version: '17.12.4'
- name: 03. Restore nuget packages for solution
shell: pwsh
run: |
dotnet restore
- name: 04. Compile mRemoteNG
shell: pwsh
run: |
msbuild "$Env:GITHUB_WORKSPACE\mRemoteNG.sln" -p:Configuration="Release Installer and Portable" -p:Platform=x64 /verbosity:normal
- name: 05. Publish MSI Binary as Artifact
uses: actions/upload-artifact@v4
with:
name: release-msi-x86_64
path: ${{ github.workspace }}\mRemoteNGInstaller\Installer\bin\x64\Release\en-US\
if-no-files-found: error
- name: 06. Publish Portable Binary as Artifact
uses: actions/upload-artifact@v4
with:
name: release-portable-x86_64
path: ${{ github.workspace }}\mRemoteNG\bin\x64\Release
if-no-files-found: error
Create-Release:
needs: [Build-Debug-MSI, Build-Debug-Portable, Build-Release]
runs-on: ubuntu-22.04
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Download Artifacts
uses: actions/download-artifact@v4
- name: 03. Create compressed archives # Needs to be done because "actions/download-artifact@v4" is extracting the zipped Artifacts
shell: bash
run: |
zip -r debug-msi-x86_64.zip debug-msi-x86_64/
zip -r debug-portable-x86_64.zip debug-portable-x86_64/
zip -r release-msi-x86_64.zip release-msi-x86_64/
zip -r release-portable-x86_64.zip release-portable-x86_64/
- name: 04. Create Release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "v1.77.3-dev-${GITHUB_RUN_NUMBER}" \
--title "v1.77.3-dev-${GITHUB_RUN_NUMBER}" \
--prerelease \
--generate-notes \
$GITHUB_WORKSPACE/debug-msi-x86_64.zip \
$GITHUB_WORKSPACE/debug-portable-x86_64.zip \
$GITHUB_WORKSPACE/release-msi-x86_64.zip \
$GITHUB_WORKSPACE/release-portable-x86_64.zip

49
.github/workflows/post_2_Reddit.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Post to Reddit via PowerShell
on:
workflow_dispatch:
jobs:
post:
runs-on: windows-latest
steps:
- name: Authenticate and post to Reddit
shell: pwsh
env:
CLIENT_ID: ${{ secrets.REDDIT_CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.REDDIT_CLIENT_SECRET }}
USERNAME: ${{ secrets.REDDIT_USERNAME }}
PASSWORD: ${{ secrets.REDDIT_PASSWORD }}
SUBREDDIT: ${{ secrets.REDDIT_SUBREDDIT }}
run: |
# Step 1: Get access token
$authHeaders = @{
Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$env:CLIENT_ID:$env:CLIENT_SECRET"))
"User-Agent" = "github-to-reddit-pwsh/0.1"
}
$authBody = @{
grant_type = "password"
username = $env:USERNAME
password = $env:PASSWORD
}
$authResponse = Invoke-RestMethod -Uri "https://www.reddit.com/api/v1/access_token" -Method Post -Headers $authHeaders -Body $authBody
$token = $authResponse.access_token
# Step 2: Post to subreddit
$postHeaders = @{
Authorization = "bearer $token"
"User-Agent" = "github-to-reddit-pwsh/0.1"
}
$postBody = @{
sr = $env:SUBREDDIT
title = "Hello from GitHub Actions (PowerShell)"
kind = "self"
text = "This post was made using PowerShell in GitHub Actions."
}
$postResponse = Invoke-RestMethod -Uri "https://oauth.reddit.com/api/submit" -Method Post -Headers $postHeaders -Body $postBody
Write-Host "Posted: $($postResponse.json.url)"

View File

@@ -2,6 +2,39 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.78.2]
### Fixed
- #2855: Fix missing Username field for HTTP and HTTPS protocols
- #2852: Fix XML External Entity (XXE) vulnerability in XML deserialization
- #2851: Fix path traversal vulnerability in file operations
- #2850: Fix password dialog appearing behind splash screen on startup
- #2842: Fix element placement in options window
- #2715: Disable WinForms analyzers and suppress WFO1000 build errors for ObjectListView
- #2712: VNCEvent_Disconnected send the ProtocolBase based object reference
- #2668: fix ssh quickconnect exception
- #2611: correct registry path
- #2496: use pwfile instead of cleartext password for putty connections
- #2734: fix native build for Windows-x64
### Added
- #2865: Add configurable connection tab colors to distinguish between different environments
- #2864: Add Color property to connections and folders with inheritance support
- #2863: Add ARD (Apple Remote Desktop) protocol support for macOS connections
- #2728: Add support for building mRemoteNG on Windows ARM64
- #2723: Read keyboardhook, gatewayaccesstoken and gatewaycredentialssource from RDP File
- #2690: தமிழ் (ta) Translation update
- #2643: Registry Settings: enhancements and new settings implementation
- #2591: add Clickstudios Passwordstate API connector
### Updated
- #2854: Refactor settings dialog to be opened in dockable panel (for consistency)
- #2597: Remember the opened connection file on relaunch
- #2502: Updated Polish translation
### Dependency update
- #3bd2fe8: puttyng updated to x64 version (and signed)
## [1.77.3.1784]
### Fixed
- #2362: Fix use of sql database

104
Directory.Packages.props Normal file
View File

@@ -0,0 +1,104 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<NoWarn>$(NoWarn);NU1507</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="AWSSDK.Core" Version="4.0.0.32" />
<PackageVersion Include="AWSSDK.EC2" Version="4.0.40.4" />
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.6.2" />
<PackageVersion Include="Castle.Core" Version="5.2.1" />
<PackageVersion Include="ConsoleControl" Version="1.3.0" />
<PackageVersion Include="ConsoleControlAPI" Version="1.3.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="Cucumber.Messages" Version="30.0.0" />
<PackageVersion Include="DockPanelSuite" Version="3.1.1" />
<PackageVersion Include="DockPanelSuite.ThemeVS2015" Version="3.1.1" />
<PackageVersion Include="envdte" Version="17.14.40260" />
<PackageVersion Include="Gherkin" Version="35.1.0" />
<PackageVersion Include="Google.Protobuf" Version="3.32.1" />
<PackageVersion Include="LiteDB" Version="5.0.21" />
<PackageVersion Include="log4net" Version="3.2.0" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="6.1.1" />
<PackageVersion Include="Microsoft.Data.SqlClient.SNI" Version="6.0.2" />
<PackageVersion Include="Microsoft.Data.SqlClient.SNI.runtime" Version="6.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="9.0.9" />
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.9" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
<PackageVersion Include="Microsoft.NETCore.Platforms" Version="7.0.4" />
<PackageVersion Include="Microsoft.NETCore.Targets" Version="5.0.0" />
<PackageVersion Include="Microsoft.VisualStudio.TextTemplating.VSHost" Version="17.14.40265" />
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.3537.50" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageVersion Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.5" />
<PackageVersion Include="MySql.Data" Version="9.4.0" />
<PackageVersion Include="NETStandard.Library" Version="2.0.3" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="Newtonsoft.Json.Schema" Version="4.0.1" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NUnit" Version="4.4.0" />
<PackageVersion Include="NUnit.Console" Version="3.20.1" />
<PackageVersion Include="NUnit.ConsoleRunner" Version="3.20.1" />
<PackageVersion Include="NUnit.Extension.TeamCityEventListener" Version="1.0.10" />
<PackageVersion Include="NUnit.Runners" Version="3.12.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="5.2.0" />
<PackageVersion Include="OpenCover" Version="4.7.1221" />
<PackageVersion Include="Renci.SshNet.Async" Version="1.4.0" />
<PackageVersion Include="ReportGenerator" Version="5.4.17" />
<PackageVersion Include="runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl" Version="4.3.3" />
<PackageVersion Include="runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl" Version="4.3.3" />
<PackageVersion Include="runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl" Version="4.3.3" />
<PackageVersion Include="runtime.native.System" Version="4.3.1" />
<PackageVersion Include="runtime.native.System.IO.Compression" Version="4.3.2" />
<PackageVersion Include="runtime.native.System.Net.Http" Version="4.3.1" />
<PackageVersion Include="runtime.native.System.Security.Cryptography.OpenSsl" Version="4.3.3" />
<PackageVersion Include="runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl" Version="4.3.3" />
<PackageVersion Include="runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl" Version="4.3.3" />
<PackageVersion Include="runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl" Version="4.3.3" />
<PackageVersion Include="SSH.NET" Version="2025.0.0" />
<PackageVersion Include="System.Buffers" Version="4.6.1" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="9.0.9" />
<PackageVersion Include="System.Collections.Immutable" Version="9.0.9" />
<PackageVersion Include="System.Console" Version="4.3.1" />
<PackageVersion Include="System.Data.Common" Version="4.3.0" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.9" />
<PackageVersion Include="System.Drawing.Common" Version="9.0.9" />
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.9" />
<PackageVersion Include="System.DirectoryServices" Version="9.0.9" />
<PackageVersion Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageVersion Include="System.IO.Pipelines" Version="9.0.9" />
<PackageVersion Include="System.Formats.Asn1" Version="9.0.9" />
<PackageVersion Include="System.Management" Version="9.0.9" />
<PackageVersion Include="System.Memory" Version="4.6.3" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Net.Primitives" Version="4.3.1" />
<PackageVersion Include="System.Net.Sockets" Version="4.3.0" />
<PackageVersion Include="System.Reflection.Emit" Version="4.7.0" />
<PackageVersion Include="System.Reflection.Emit.ILGeneration" Version="4.7.0" />
<PackageVersion Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
<PackageVersion Include="System.Reflection.Metadata" Version="9.0.9" />
<PackageVersion Include="System.Reflection.TypeExtensions" Version="4.7.0" />
<PackageVersion Include="System.Resources.ResourceManager" Version="4.3.0" />
<PackageVersion Include="System.Runtime" Version="4.3.1" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
<PackageVersion Include="System.Runtime.Extensions" Version="4.3.1" />
<PackageVersion Include="System.Security.AccessControl" Version="6.0.1" />
<PackageVersion Include="System.Security.Cryptography.Algorithms" Version="4.3.1" />
<PackageVersion Include="System.Security.Cryptography.Cng" Version="5.0.0" />
<PackageVersion Include="System.Security.Cryptography.OpenSsl" Version="5.0.0" />
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="9.0.9" />
<PackageVersion Include="System.Security.Cryptography.X509Certificates" Version="4.3.2" />
<PackageVersion Include="System.Security.Permissions" Version="9.0.9" />
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.9" />
<PackageVersion Include="System.Text.Json" Version="9.0.9" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.3" />
<PackageVersion Include="System.ValueTuple" Version="4.6.1" />
<PackageVersion Include="System.Windows.Extensions" Version="9.0.9" />
<PackageVersion Include="System.Xml.ReaderWriter" Version="4.3.1" />
<PackageVersion Include="VncSharpCore" Version="1.2.1" />
<PackageVersion Include="ZstdSharp.Port" Version="0.8.6" />
</ItemGroup>
</Project>

View File

@@ -257,15 +257,9 @@ public class PasswordstateInterface
return ""+textWriter.ToString();
}
private class PasswordFinder : IPasswordFinder
private class PasswordFinder(string password) : IPasswordFinder
{
private string password;
public PasswordFinder(string password)
{
this.password = password;
}
private string password = password;
public char[] GetPassword()
{

View File

@@ -58,10 +58,7 @@ namespace SecretServerAuthentication.DSS
/// <param name="refresh_token">The refresh token. Required when refreshing a token.</param>
/// <returns>Successful retrieval of an access token</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<TokenResponse> AuthorizeAsync(Grant_type grant_type, string username, string password, string refresh_token, string OTP)
{
return AuthorizeAsync(grant_type, username, password, refresh_token, System.Threading.CancellationToken.None, OTP);
}
public System.Threading.Tasks.Task<TokenResponse> AuthorizeAsync(Grant_type grant_type, string username, string password, string refresh_token, string OTP) => AuthorizeAsync(grant_type, username, password, refresh_token, System.Threading.CancellationToken.None, OTP);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Retrieve or Refresh Access Token</summary>
@@ -355,10 +352,7 @@ namespace SecretServerAuthentication.DSS
Headers = headers;
}
public override string ToString()
{
return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
}
public override string ToString() => string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))")]

View File

@@ -223,15 +223,9 @@ public class SecretServerInterface
return ""+textWriter.ToString();
}
private class PasswordFinder : IPasswordFinder
private class PasswordFinder(string password) : IPasswordFinder
{
private string password;
public PasswordFinder(string password)
{
this.password = password;
}
private string password = password;
public char[] GetPassword()
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<UseWindowsForms>True</UseWindowsForms>
<Platforms>x64</Platforms>
<Platforms>x64;arm64</Platforms>
<Configurations>Debug;Release;Debug Portable;Release Portable;Deploy to github</Configurations>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion>10.0.26100.0</SupportedOSPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Portable|x64'">
<Optimize>True</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Portable|arm64'">
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.7.402.1" />
<PackageReference Include="AWSSDK.EC2" Version="3.7.430.2" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="AWSSDK.Core" />
<PackageReference Include="AWSSDK.EC2" />
<PackageReference Include="BouncyCastle.Cryptography" />
<PackageReference Include="Newtonsoft.Json" />
</ItemGroup>
<ItemGroup>
<Compile Update="AWS\AWSConnectionForm.cs" />
<Compile Update="CPS\CPSConnectionForm.cs" />
<Compile Update="DSS\SSConnectionForm.cs" />
</ItemGroup>
</Project>

View File

@@ -46,18 +46,14 @@ namespace BrightIdeasSoftware
/// <summary>
/// These items allow combo boxes to remember a value and its description.
/// </summary>
public class ComboBoxItem
/// <remarks>
///
/// </remarks>
/// <param name="key"></param>
/// <param name="description"></param>
public class ComboBoxItem(Object key, String description)
{
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="description"></param>
public ComboBoxItem(Object key, String description) {
this.key = key;
this.description = description;
}
private readonly String description;
private readonly String description = description;
/// <summary>
///
@@ -65,7 +61,7 @@ namespace BrightIdeasSoftware
public Object Key {
get { return key; }
}
private readonly Object key;
private readonly Object key = key;
/// <summary>
/// Returns a string that represents the current object.

View File

@@ -158,15 +158,12 @@ namespace BrightIdeasSoftware
/// This class isn't intended to be used directly, but it is left as a public
/// class just in case someone wants to subclass it.
/// </remarks>
public class FastObjectListDataSource : AbstractVirtualListDataSource
/// <remarks>
/// Create a FastObjectListDataSource
/// </remarks>
/// <param name="listView"></param>
public class FastObjectListDataSource(FastObjectListView listView) : AbstractVirtualListDataSource(listView)
{
/// <summary>
/// Create a FastObjectListDataSource
/// </summary>
/// <param name="listView"></param>
public FastObjectListDataSource(FastObjectListView listView)
: base(listView) {
}
#region IVirtualListDataSource Members

View File

@@ -185,15 +185,11 @@ namespace BrightIdeasSoftware
/// A model object must satisfy all filters to be included.
/// If there are no filters, all model objects are included
/// </summary>
public class CompositeAllFilter : CompositeFilter {
/// <summary>
/// Create a filter
/// </summary>
/// <param name="filters"></param>
public CompositeAllFilter(List<IModelFilter> filters)
: base(filters) {
}
/// <remarks>
/// Create a filter
/// </remarks>
/// <param name="filters"></param>
public class CompositeAllFilter(List<IModelFilter> filters) : CompositeFilter(filters) {
/// <summary>
/// Decide whether or not the given model should be included by the filter
@@ -215,15 +211,11 @@ namespace BrightIdeasSoftware
/// A model object must only satisfy one of the filters to be included.
/// If there are no filters, all model objects are included
/// </summary>
public class CompositeAnyFilter : CompositeFilter {
/// <summary>
/// Create a filter from the given filters
/// </summary>
/// <param name="filters"></param>
public CompositeAnyFilter(List<IModelFilter> filters)
: base(filters) {
}
/// <remarks>
/// Create a filter from the given filters
/// </remarks>
/// <param name="filters"></param>
public class CompositeAnyFilter(List<IModelFilter> filters) : CompositeFilter(filters) {
/// <summary>
/// Decide whether or not the given model should be included by the filter

View File

@@ -50,7 +50,13 @@ namespace BrightIdeasSoftware
/// <para>This is used by normal (non-virtual) ObjectListViews. Virtual lists use
/// ModelObjectComparer</para>
/// </remarks>
public class ColumnComparer : IComparer, IComparer<OLVListItem>
/// <remarks>
/// Create a ColumnComparer that will order the rows in a list view according
/// to the values in a given column
/// </remarks>
/// <param name="col">The column whose values will be compared</param>
/// <param name="order">The ordering for column values</param>
public class ColumnComparer(OLVColumn col, SortOrder order) : IComparer, IComparer<OLVListItem>
{
/// <summary>
/// Gets or sets the method that will be used to compare two strings.
@@ -63,18 +69,6 @@ namespace BrightIdeasSoftware
}
private static StringCompareDelegate stringComparer;
/// <summary>
/// Create a ColumnComparer that will order the rows in a list view according
/// to the values in a given column
/// </summary>
/// <param name="col">The column whose values will be compared</param>
/// <param name="order">The ordering for column values</param>
public ColumnComparer(OLVColumn col, SortOrder order)
{
this.column = col;
this.sortOrder = order;
}
/// <summary>
/// Create a ColumnComparer that will order the rows in a list view according
/// to the values in a given column, and by a secondary column if the primary
@@ -165,8 +159,8 @@ namespace BrightIdeasSoftware
return StringComparer(x, y);
}
private OLVColumn column;
private SortOrder sortOrder;
private OLVColumn column = col;
private SortOrder sortOrder = order;
private ColumnComparer secondComparer;
}
@@ -175,15 +169,12 @@ namespace BrightIdeasSoftware
/// This comparer sort list view groups. OLVGroups have a "SortValue" property,
/// which is used if present. Otherwise, the titles of the groups will be compared.
/// </summary>
public class OLVGroupComparer : IComparer<OLVGroup>
/// <remarks>
/// Create a group comparer
/// </remarks>
/// <param name="order">The ordering for column values</param>
public class OLVGroupComparer(SortOrder order) : IComparer<OLVGroup>
{
/// <summary>
/// Create a group comparer
/// </summary>
/// <param name="order">The ordering for column values</param>
public OLVGroupComparer(SortOrder order) {
this.sortOrder = order;
}
/// <summary>
/// Compare the two groups. OLVGroups have a "SortValue" property,
@@ -207,7 +198,7 @@ namespace BrightIdeasSoftware
return result;
}
private SortOrder sortOrder;
private SortOrder sortOrder = order;
}
/// <summary>
@@ -217,7 +208,12 @@ namespace BrightIdeasSoftware
/// <para>This is used by virtual ObjectListViews. Non-virtual lists use
/// ColumnComparer</para>
/// </remarks>
public class ModelObjectComparer : IComparer, IComparer<object>
/// <remarks>
/// Create a model object comparer
/// </remarks>
/// <param name="col"></param>
/// <param name="order"></param>
public class ModelObjectComparer(OLVColumn col, SortOrder order) : IComparer, IComparer<object>
{
/// <summary>
/// Gets or sets the method that will be used to compare two strings.
@@ -230,17 +226,6 @@ namespace BrightIdeasSoftware
}
private static StringCompareDelegate stringComparer;
/// <summary>
/// Create a model object comparer
/// </summary>
/// <param name="col"></param>
/// <param name="order"></param>
public ModelObjectComparer(OLVColumn col, SortOrder order)
{
this.column = col;
this.sortOrder = order;
}
/// <summary>
/// Create a model object comparer with a secondary sorting column
/// </summary>
@@ -318,8 +303,8 @@ namespace BrightIdeasSoftware
return StringComparer(x, y);
}
private OLVColumn column;
private SortOrder sortOrder;
private OLVColumn column = col;
private SortOrder sortOrder = order;
private ModelObjectComparer secondComparer;
#region IComparer<object> Members

View File

@@ -878,25 +878,16 @@ namespace BrightIdeasSoftware
/// <summary>
/// Let the world know that a cell edit operation is beginning or ending
/// </summary>
public class CellEditEventArgs : EventArgs
/// <remarks>
/// Create an event args
/// </remarks>
/// <param name="column"></param>
/// <param name="control"></param>
/// <param name="cellBounds"></param>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
public class CellEditEventArgs(OLVColumn column, Control control, Rectangle cellBounds, OLVListItem item, int subItemIndex) : EventArgs
{
/// <summary>
/// Create an event args
/// </summary>
/// <param name="column"></param>
/// <param name="control"></param>
/// <param name="cellBounds"></param>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
public CellEditEventArgs(OLVColumn column, Control control, Rectangle cellBounds, OLVListItem item, int subItemIndex) {
this.Control = control;
this.column = column;
this.cellBounds = cellBounds;
this.listViewItem = item;
this.rowObject = item.RowObject;
this.subItemIndex = subItemIndex;
this.value = column.GetValue(item.RowObject);
}
/// <summary>
/// Change this to true to cancel the cell editing operation.
@@ -917,7 +908,7 @@ namespace BrightIdeasSoftware
/// entered and commit that value to the model. Changing the control during the finishing
/// event has no effect.
/// </summary>
public Control Control;
public Control Control = control;
/// <summary>
/// The column of the cell that is going to be or has been edited.
@@ -925,7 +916,7 @@ namespace BrightIdeasSoftware
public OLVColumn Column {
get { return this.column; }
}
private OLVColumn column;
private OLVColumn column = column;
/// <summary>
/// The model object of the row of the cell that is going to be or has been edited.
@@ -933,7 +924,7 @@ namespace BrightIdeasSoftware
public Object RowObject {
get { return this.rowObject; }
}
private Object rowObject;
private Object rowObject = item.RowObject;
/// <summary>
/// The listview item of the cell that is going to be or has been edited.
@@ -941,7 +932,7 @@ namespace BrightIdeasSoftware
public OLVListItem ListViewItem {
get { return this.listViewItem; }
}
private OLVListItem listViewItem;
private OLVListItem listViewItem = item;
/// <summary>
/// The data value of the cell as it stands in the control.
@@ -959,7 +950,7 @@ namespace BrightIdeasSoftware
public int SubItemIndex {
get { return this.subItemIndex; }
}
private int subItemIndex;
private int subItemIndex = subItemIndex;
/// <summary>
/// The data value of the cell before the edit operation began.
@@ -967,7 +958,7 @@ namespace BrightIdeasSoftware
public Object Value {
get { return this.value; }
}
private Object value;
private Object value = column.GetValue(item.RowObject);
/// <summary>
/// The bounds of the cell that is going to be or has been edited.
@@ -975,7 +966,7 @@ namespace BrightIdeasSoftware
public Rectangle CellBounds {
get { return this.cellBounds; }
}
private Rectangle cellBounds;
private Rectangle cellBounds = cellBounds;
/// <summary>
/// Gets or sets whether the control used for editing should be auto matically disposed
@@ -1160,25 +1151,22 @@ namespace BrightIdeasSoftware
}
private SortOrder secondarySortOrder;
}
/// <summary>
/// This event is triggered when the contents of a list have changed
/// and we want the world to have a chance to filter the list.
/// </summary>
public class FilterEventArgs : EventArgs
/// <remarks>
/// Create a FilterEventArgs
/// </remarks>
/// <param name="objects"></param>
public class FilterEventArgs(IEnumerable objects) : EventArgs
{
/// <summary>
/// Create a FilterEventArgs
/// </summary>
/// <param name="objects"></param>
public FilterEventArgs(IEnumerable objects) {
this.Objects = objects;
}
/// <summary>
/// Gets or sets what objects are being filtered
/// </summary>
public IEnumerable Objects;
public IEnumerable Objects = objects;
/// <summary>
/// Gets or sets what objects survived the filtering
@@ -1267,17 +1255,13 @@ namespace BrightIdeasSoftware
/// <remarks>
/// When used with a virtual list, OldObjects will always be null.
/// </remarks>
public class ItemsChangingEventArgs : CancellableEventArgs
/// <remarks>
/// Create ItemsChangingEventArgs
/// </remarks>
/// <param name="oldObjects"></param>
/// <param name="newObjects"></param>
public class ItemsChangingEventArgs(IEnumerable oldObjects, IEnumerable newObjects) : CancellableEventArgs
{
/// <summary>
/// Create ItemsChangingEventArgs
/// </summary>
/// <param name="oldObjects"></param>
/// <param name="newObjects"></param>
public ItemsChangingEventArgs(IEnumerable oldObjects, IEnumerable newObjects) {
this.oldObjects = oldObjects;
this.NewObjects = newObjects;
}
/// <summary>
/// Gets the objects that were in the list before it change.
@@ -1286,47 +1270,40 @@ namespace BrightIdeasSoftware
public IEnumerable OldObjects {
get { return oldObjects; }
}
private IEnumerable oldObjects;
private IEnumerable oldObjects = oldObjects;
/// <summary>
/// Gets or sets the objects that will be in the list after it changes.
/// </summary>
public IEnumerable NewObjects;
public IEnumerable NewObjects = newObjects;
}
/// <summary>
/// This event is triggered by RemoveObjects before any change has been made to the list.
/// </summary>
public class ItemsRemovingEventArgs : CancellableEventArgs
/// <remarks>
/// Create an ItemsRemovingEventArgs
/// </remarks>
/// <param name="objectsToRemove"></param>
public class ItemsRemovingEventArgs(ICollection objectsToRemove) : CancellableEventArgs
{
/// <summary>
/// Create an ItemsRemovingEventArgs
/// </summary>
/// <param name="objectsToRemove"></param>
public ItemsRemovingEventArgs(ICollection objectsToRemove) {
this.ObjectsToRemove = objectsToRemove;
}
/// <summary>
/// Gets or sets the objects that will be removed
/// </summary>
public ICollection ObjectsToRemove;
public ICollection ObjectsToRemove = objectsToRemove;
}
/// <summary>
/// Triggered after the user types into a list
/// </summary>
public class AfterSearchingEventArgs : EventArgs
/// <remarks>
/// Create an AfterSearchingEventArgs
/// </remarks>
/// <param name="stringToFind"></param>
/// <param name="indexSelected"></param>
public class AfterSearchingEventArgs(string stringToFind, int indexSelected) : EventArgs
{
/// <summary>
/// Create an AfterSearchingEventArgs
/// </summary>
/// <param name="stringToFind"></param>
/// <param name="indexSelected"></param>
public AfterSearchingEventArgs(string stringToFind, int indexSelected) {
this.stringToFind = stringToFind;
this.indexSelected = indexSelected;
}
/// <summary>
/// Gets the string that was actually searched for
@@ -1334,7 +1311,7 @@ namespace BrightIdeasSoftware
public string StringToFind {
get { return this.stringToFind; }
}
private string stringToFind;
private string stringToFind = stringToFind;
/// <summary>
/// Gets or sets whether an the event handler already handled this event
@@ -1348,23 +1325,19 @@ namespace BrightIdeasSoftware
public int IndexSelected {
get { return this.indexSelected; }
}
private int indexSelected;
private int indexSelected = indexSelected;
}
/// <summary>
/// Triggered when the user types into a list
/// </summary>
public class BeforeSearchingEventArgs : CancellableEventArgs
/// <remarks>
/// Create BeforeSearchingEventArgs
/// </remarks>
/// <param name="stringToFind"></param>
/// <param name="startSearchFrom"></param>
public class BeforeSearchingEventArgs(string stringToFind, int startSearchFrom) : CancellableEventArgs
{
/// <summary>
/// Create BeforeSearchingEventArgs
/// </summary>
/// <param name="stringToFind"></param>
/// <param name="startSearchFrom"></param>
public BeforeSearchingEventArgs(string stringToFind, int startSearchFrom) {
this.StringToFind = stringToFind;
this.StartSearchFrom = startSearchFrom;
}
/// <summary>
/// Gets or sets the string that will be found by the search routine
@@ -1372,12 +1345,12 @@ namespace BrightIdeasSoftware
/// <remarks>Modifying this value does not modify the memory of what the user has typed.
/// When the user next presses a character, the search string will revert to what
/// the user has actually typed.</remarks>
public string StringToFind;
public string StringToFind = stringToFind;
/// <summary>
/// Gets or sets the index of the first row that will be considered to matching.
/// </summary>
public int StartSearchFrom;
public int StartSearchFrom = startSearchFrom;
}
/// <summary>
@@ -2035,27 +2008,20 @@ namespace BrightIdeasSoftware
return string.Format("NewHotCellHitLocation: {0}, HotCellHitLocationEx: {1}, NewHotColumnIndex: {2}, NewHotRowIndex: {3}, HotGroup: {4}", this.newHotCellHitLocation, this.hotCellHitLocationEx, this.newHotColumnIndex, this.newHotRowIndex, this.hotGroup);
}
}
/// <summary>
/// Let the world know that a checkbox on a subitem is changing
/// </summary>
public class SubItemCheckingEventArgs : CancellableEventArgs
/// <remarks>
/// Create a new event block
/// </remarks>
/// <param name="column"></param>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
/// <param name="currentValue"></param>
/// <param name="newValue"></param>
public class SubItemCheckingEventArgs(OLVColumn column, OLVListItem item, int subItemIndex, CheckState currentValue, CheckState newValue) : CancellableEventArgs
{
/// <summary>
/// Create a new event block
/// </summary>
/// <param name="column"></param>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
/// <param name="currentValue"></param>
/// <param name="newValue"></param>
public SubItemCheckingEventArgs(OLVColumn column, OLVListItem item, int subItemIndex, CheckState currentValue, CheckState newValue) {
this.column = column;
this.listViewItem = item;
this.subItemIndex = subItemIndex;
this.currentValue = currentValue;
this.newValue = newValue;
}
/// <summary>
/// The column of the cell that is having its checkbox changed.
@@ -2063,7 +2029,7 @@ namespace BrightIdeasSoftware
public OLVColumn Column {
get { return this.column; }
}
private OLVColumn column;
private OLVColumn column = column;
/// <summary>
/// The model object of the row of the cell that is having its checkbox changed.
@@ -2078,7 +2044,7 @@ namespace BrightIdeasSoftware
public OLVListItem ListViewItem {
get { return this.listViewItem; }
}
private OLVListItem listViewItem;
private OLVListItem listViewItem = item;
/// <summary>
/// The current check state of the cell.
@@ -2086,7 +2052,7 @@ namespace BrightIdeasSoftware
public CheckState CurrentValue {
get { return this.currentValue; }
}
private CheckState currentValue;
private CheckState currentValue = currentValue;
/// <summary>
/// The proposed new check state of the cell.
@@ -2095,7 +2061,7 @@ namespace BrightIdeasSoftware
get { return this.newValue; }
set { this.newValue = value; }
}
private CheckState newValue;
private CheckState newValue = newValue;
/// <summary>
/// The index of the cell that is going to be or has been edited.
@@ -2103,21 +2069,18 @@ namespace BrightIdeasSoftware
public int SubItemIndex {
get { return this.subItemIndex; }
}
private int subItemIndex;
private int subItemIndex = subItemIndex;
}
/// <summary>
/// This event argument block is used when groups are created for a list.
/// </summary>
public class CreateGroupsEventArgs : EventArgs
/// <remarks>
/// Create a CreateGroupsEventArgs
/// </remarks>
/// <param name="parms"></param>
public class CreateGroupsEventArgs(GroupingParameters parms) : EventArgs
{
/// <summary>
/// Create a CreateGroupsEventArgs
/// </summary>
/// <param name="parms"></param>
public CreateGroupsEventArgs(GroupingParameters parms) {
this.parameters = parms;
}
/// <summary>
/// Gets the settings that control the creation of groups
@@ -2125,7 +2088,7 @@ namespace BrightIdeasSoftware
public GroupingParameters Parameters {
get { return this.parameters; }
}
private GroupingParameters parameters;
private GroupingParameters parameters = parms;
/// <summary>
/// Gets or sets the groups that should be used
@@ -2151,16 +2114,12 @@ namespace BrightIdeasSoftware
/// <summary>
/// This event argument block is used when the text of a group task is clicked
/// </summary>
public class GroupTaskClickedEventArgs : EventArgs
/// <remarks>
/// Create a GroupTaskClickedEventArgs
/// </remarks>
/// <param name="group"></param>
public class GroupTaskClickedEventArgs(OLVGroup group) : EventArgs
{
/// <summary>
/// Create a GroupTaskClickedEventArgs
/// </summary>
/// <param name="group"></param>
public GroupTaskClickedEventArgs(OLVGroup group)
{
this.group = group;
}
/// <summary>
/// Gets which group was clicked
@@ -2169,7 +2128,7 @@ namespace BrightIdeasSoftware
{
get { return this.group; }
}
private readonly OLVGroup group;
private readonly OLVGroup group = group;
}
/// <summary>
@@ -2207,18 +2166,13 @@ namespace BrightIdeasSoftware
/// <summary>
/// This event argument block is used when the state of group has changed (collapsed, selected)
/// </summary>
public class GroupStateChangedEventArgs : EventArgs {
/// <summary>
/// Create a GroupStateChangedEventArgs
/// </summary>
/// <param name="group"></param>
/// <param name="oldState"> </param>
/// <param name="newState"> </param>
public GroupStateChangedEventArgs(OLVGroup group, GroupState oldState, GroupState newState) {
this.group = group;
this.oldState = oldState;
this.newState = newState;
}
/// <remarks>
/// Create a GroupStateChangedEventArgs
/// </remarks>
/// <param name="group"></param>
/// <param name="oldState"> </param>
/// <param name="newState"> </param>
public class GroupStateChangedEventArgs(OLVGroup group, GroupState oldState, GroupState newState) : EventArgs {
/// <summary>
/// Gets whether the group was collapsed by this event
@@ -2291,7 +2245,7 @@ namespace BrightIdeasSoftware
get { return this.group; }
}
private readonly OLVGroup group;
private readonly OLVGroup group = group;
/// <summary>
/// Gets the previous state of the group
@@ -2300,7 +2254,7 @@ namespace BrightIdeasSoftware
get { return this.oldState; }
}
private readonly GroupState oldState;
private readonly GroupState oldState = oldState;
/// <summary>
@@ -2310,7 +2264,7 @@ namespace BrightIdeasSoftware
get { return this.newState; }
}
private readonly GroupState newState;
private readonly GroupState newState = newState;
}
/// <summary>

View File

@@ -311,18 +311,14 @@ namespace BrightIdeasSoftware
/// <remarks>
/// Munger uses a chain of these resolve a dotted aspect name.
/// </remarks>
public class SimpleMunger
/// <remarks>
/// Create a SimpleMunger
/// </remarks>
/// <param name="aspectName"></param>
public class SimpleMunger(String aspectName)
{
#region Life and death
/// <summary>
/// Create a SimpleMunger
/// </summary>
/// <param name="aspectName"></param>
public SimpleMunger(String aspectName)
{
this.aspectName = aspectName;
}
#region Life and death
#endregion
@@ -344,7 +340,7 @@ namespace BrightIdeasSoftware
public string AspectName {
get { return aspectName; }
}
private readonly string aspectName;
private readonly string aspectName = aspectName;
#endregion
@@ -494,19 +490,14 @@ namespace BrightIdeasSoftware
/// <summary>
/// These exceptions are raised when a munger finds something it cannot process
/// </summary>
public class MungerException : ApplicationException
/// <remarks>
/// Create a MungerException
/// </remarks>
/// <param name="munger"></param>
/// <param name="target"></param>
/// <param name="ex"></param>
public class MungerException(SimpleMunger munger, object target, Exception ex) : ApplicationException("Munger failed", ex)
{
/// <summary>
/// Create a MungerException
/// </summary>
/// <param name="munger"></param>
/// <param name="target"></param>
/// <param name="ex"></param>
public MungerException(SimpleMunger munger, object target, Exception ex)
: base("Munger failed", ex) {
this.munger = munger;
this.target = target;
}
/// <summary>
/// Get the munger that raised the exception
@@ -514,7 +505,7 @@ namespace BrightIdeasSoftware
public SimpleMunger Munger {
get { return munger; }
}
private readonly SimpleMunger munger;
private readonly SimpleMunger munger = munger;
/// <summary>
/// Gets the target that threw the exception
@@ -522,7 +513,7 @@ namespace BrightIdeasSoftware
public object Target {
get { return target; }
}
private readonly object target;
private readonly object target = target;
}
/*

View File

@@ -309,12 +309,9 @@ namespace BrightIdeasSoftware
/// A default implementation of the IOwnerDataCallback interface
/// </summary>
[Guid("6FC61F50-80E8-49b4-B200-3F38D3865ABD")]
internal class OwnerDataCallbackImpl : IOwnerDataCallback
internal class OwnerDataCallbackImpl(VirtualObjectListView olv) : IOwnerDataCallback
{
public OwnerDataCallbackImpl(VirtualObjectListView olv) {
this.olv = olv;
}
VirtualObjectListView olv;
VirtualObjectListView olv = olv;
#region IOwnerDataCallback Members

View File

@@ -145,20 +145,17 @@ namespace BrightIdeasSoftware
/// <summary>
/// A do-nothing implementation of the VirtualListDataSource interface.
/// </summary>
public class AbstractVirtualListDataSource : IVirtualListDataSource, IFilterableDataSource
/// <remarks>
/// Creates an AbstractVirtualListDataSource
/// </remarks>
/// <param name="listView"></param>
public class AbstractVirtualListDataSource(VirtualObjectListView listView) : IVirtualListDataSource, IFilterableDataSource
{
/// <summary>
/// Creates an AbstractVirtualListDataSource
/// </summary>
/// <param name="listView"></param>
public AbstractVirtualListDataSource(VirtualObjectListView listView) {
this.listView = listView;
}
/// <summary>
/// The list view that this data source is giving information to.
/// </summary>
protected VirtualObjectListView listView;
protected VirtualObjectListView listView = listView;
/// <summary>
///
@@ -295,15 +292,12 @@ namespace BrightIdeasSoftware
/// <summary>
/// This class mimics the behavior of VirtualObjectListView v1.x.
/// </summary>
public class VirtualListVersion1DataSource : AbstractVirtualListDataSource
/// <remarks>
/// Creates a VirtualListVersion1DataSource
/// </remarks>
/// <param name="listView"></param>
public class VirtualListVersion1DataSource(VirtualObjectListView listView) : AbstractVirtualListDataSource(listView)
{
/// <summary>
/// Creates a VirtualListVersion1DataSource
/// </summary>
/// <param name="listView"></param>
public VirtualListVersion1DataSource(VirtualObjectListView listView)
: base(listView) {
}
#region Public properties

View File

@@ -369,14 +369,8 @@ namespace BrightIdeasSoftware.Design
/// only have to modify the returned collection of actions, but we have to implement
/// the properties and commands that the returned actions use. </para>
/// </remarks>
private class ListViewActionListAdapter : DesignerActionList
private class ListViewActionListAdapter(ObjectListViewDesigner designer, DesignerActionList wrappedList) : DesignerActionList(wrappedList.Component)
{
public ListViewActionListAdapter(ObjectListViewDesigner designer, DesignerActionList wrappedList)
: base(wrappedList.Component) {
this.designer = designer;
this.wrappedList = wrappedList;
}
public override DesignerActionItemCollection GetSortedActionItems() {
DesignerActionItemCollection items = wrappedList.GetSortedActionItems();
items.RemoveAt(2); // remove Edit Groups
@@ -425,21 +419,16 @@ namespace BrightIdeasSoftware.Design
set { SetValue(base.Component, "View", value); }
}
ObjectListViewDesigner designer;
DesignerActionList wrappedList;
ObjectListViewDesigner designer = designer;
DesignerActionList wrappedList = wrappedList;
}
#endregion
#region DesignerCommandSet
private class CDDesignerCommandSet : DesignerCommandSet
private class CDDesignerCommandSet(ComponentDesigner componentDesigner) : DesignerCommandSet
{
public CDDesignerCommandSet(ComponentDesigner componentDesigner) {
this.componentDesigner = componentDesigner;
}
public override ICollection GetCommands(string name) {
// Debug.WriteLine("CDDesignerCommandSet.GetCommands:" + name);
if (componentDesigner != null) {
@@ -453,7 +442,7 @@ namespace BrightIdeasSoftware.Design
return base.GetCommands(name);
}
private readonly ComponentDesigner componentDesigner;
private readonly ComponentDesigner componentDesigner = componentDesigner;
}
#endregion
@@ -463,15 +452,12 @@ namespace BrightIdeasSoftware.Design
/// This class works in conjunction with the OLVColumns property to allow OLVColumns
/// to be added to the ObjectListView.
/// </summary>
public class OLVColumnCollectionEditor : System.ComponentModel.Design.CollectionEditor
/// <remarks>
/// Create a OLVColumnCollectionEditor
/// </remarks>
/// <param name="t"></param>
public class OLVColumnCollectionEditor(Type t) : System.ComponentModel.Design.CollectionEditor(t)
{
/// <summary>
/// Create a OLVColumnCollectionEditor
/// </summary>
/// <param name="t"></param>
public OLVColumnCollectionEditor(Type t)
: base(t) {
}
/// <summary>
/// What type of object does this editor create?

View File

@@ -1,15 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<Deterministic>false</Deterministic>
<RootNamespace>BrightIdeasSoftware</RootNamespace>
<AssemblyName>ObjectListView</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
<NoWarn>$(NoWarn);WFO1000</NoWarn>
<EnableWinFormsAnalyzers>false</EnableWinFormsAnalyzers>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'x64'">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'ARM64'">
<PlatformTarget>ARM64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Content Include="CustomDictionary.xml" Link="CustomDictionary.xml" />
<Content Include="Resources\clear-filter.png" Link="Resources\clear-filter.png" />
@@ -19,7 +25,6 @@
<Content Include="Resources\sort-ascending.png" Link="Resources\sort-ascending.png" />
<Content Include="Resources\sort-descending.png" Link="Resources\sort-descending.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="CellEditing\" />
<Folder Include="DragDrop\" />
@@ -30,9 +35,8 @@
<Folder Include="Resources\" />
<Folder Include="Rendering\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="9.0.2" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.0" />
<PackageReference Include="System.Drawing.Common" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" />
</ItemGroup>
</Project>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -231,15 +231,12 @@ namespace BrightIdeasSoftware {
/// This class provides compatibility for v1 RendererDelegates
/// </summary>
[ToolboxItem(false)]
internal class Version1Renderer : AbstractRenderer {
public Version1Renderer(RenderDelegate renderDelegate) {
this.RenderDelegate = renderDelegate;
}
internal class Version1Renderer(RenderDelegate renderDelegate) : AbstractRenderer {
/// <summary>
/// The renderer delegate that this renderer wraps
/// </summary>
public RenderDelegate RenderDelegate;
public RenderDelegate RenderDelegate = renderDelegate;
#region IRenderer Members
@@ -518,7 +515,7 @@ namespace BrightIdeasSoftware {
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ImageList ImageListOrDefault {
get { return this.ImageList ?? this.ListView.SmallImageList; }
get { return this.ImageList ?? this.ListView.GetSmallImageList(); }
}
/// <summary>
@@ -809,7 +806,7 @@ namespace BrightIdeasSoftware {
/// <param name="g"></param>
/// <returns></returns>
protected virtual Size CalculatePrimaryCheckBoxSize(Graphics g) {
if (!this.ListView.CheckBoxes || !this.ColumnIsPrimary)
if (!this.ListView.GetCheckBoxes() || !this.ColumnIsPrimary)
return Size.Empty;
Size size = this.CalculateCheckBoxSize(g);
@@ -1299,7 +1296,7 @@ namespace BrightIdeasSoftware {
int width = 0;
// Did they hit a check box on the primary column?
if (this.ColumnIsPrimary && this.ListView.CheckBoxes) {
if (this.ColumnIsPrimary && this.ListView.GetCheckBoxes()) {
Size checkBoxSize = this.CalculateCheckBoxSize(g);
int checkBoxTop = this.AlignVertically(r, checkBoxSize.Height);
Rectangle r3 = new Rectangle(r.X, checkBoxTop, checkBoxSize.Width, checkBoxSize.Height);
@@ -1635,7 +1632,7 @@ namespace BrightIdeasSoftware {
/// <param name="r">Bounds of the cell</param>
protected virtual void DrawImageAndText(Graphics g, Rectangle r) {
int offset = 0;
if (this.ListView.CheckBoxes && this.ColumnIsPrimary) {
if (this.ListView.GetCheckBoxes() && this.ColumnIsPrimary) {
offset = this.DrawCheckBox(g, r) + 6;
r.X += offset;
r.Width -= offset;

View File

@@ -51,17 +51,20 @@
* If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com.
*/
using BrightIdeasSoftware.Properties;
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Windows.Forms.VisualStyles;
using System.Drawing.Drawing2D;
using BrightIdeasSoftware.Properties;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
namespace BrightIdeasSoftware
{
[SupportedOSPlatform("windows")]
/// <summary>
/// Class used to capture window messages for the header of the list view
/// control.

View File

@@ -40,11 +40,13 @@ using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Windows.Forms;
namespace BrightIdeasSoftware
{
[SupportedOSPlatform("windows")]
/// <summary>
/// A limited wrapper around a Windows tooltip window.
/// </summary>

View File

@@ -193,7 +193,7 @@ namespace BrightIdeasSoftware
// ReSharper restore DoNotCallOverridableMethodsInConstructor
// This improves hit detection even if we don't have any state image
this.SmallImageList = new ImageList();
this.SetSmallImageList(new ImageList());
// this.StateImageList.ImageSize = new Size(6, 6);
}
@@ -364,7 +364,7 @@ namespace BrightIdeasSoftware
return;
this.hierarchicalCheckboxes = value;
this.CheckBoxes = value;
this.SetCheckBoxes(value);
if (value)
this.TriStateCheckBoxes = false;
}
@@ -2180,15 +2180,12 @@ namespace BrightIdeasSoftware
/// <summary>
/// This class sorts branches according to how their respective model objects are sorted
/// </summary>
public class BranchComparer : IComparer<Branch>
/// <remarks>
/// Create a BranchComparer
/// </remarks>
/// <param name="actualComparer"></param>
public class BranchComparer(IComparer actualComparer) : IComparer<Branch>
{
/// <summary>
/// Create a BranchComparer
/// </summary>
/// <param name="actualComparer"></param>
public BranchComparer(IComparer actualComparer) {
this.actualComparer = actualComparer;
}
/// <summary>
/// Order the two branches
@@ -2200,7 +2197,7 @@ namespace BrightIdeasSoftware
return this.actualComparer.Compare(x.Model, y.Model);
}
private readonly IComparer actualComparer;
private readonly IComparer actualComparer = actualComparer;
}
}

View File

@@ -125,7 +125,7 @@ namespace BrightIdeasSoftware
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.objectListView1.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.SingleClick;
this.objectListView1.CheckBoxes = true;
this.objectListView1.SetCheckBoxes(true);
this.objectListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.olvColumn1});
this.objectListView1.FullRowSelect = true;

View File

@@ -233,13 +233,9 @@ namespace BrightIdeasSoftware
/// A Comparer that will sort a list of columns so that visible ones come before hidden ones,
/// and that are ordered by their display order.
/// </summary>
private class SortByDisplayOrder : IComparer<OLVColumn>
private class SortByDisplayOrder(ColumnSelectionForm form) : IComparer<OLVColumn>
{
public SortByDisplayOrder(ColumnSelectionForm form)
{
this.Form = form;
}
private ColumnSelectionForm Form;
private ColumnSelectionForm Form = form;
#region IComparer<OLVColumn> Members

View File

@@ -72,15 +72,12 @@ namespace BrightIdeasSoftware
/// }
/// </code>
/// </example>
public class TypedObjectListView<T> where T : class
/// <remarks>
/// Create a typed wrapper around the given list.
/// </remarks>
/// <param name="olv">The listview to be wrapped</param>
public class TypedObjectListView<T>(ObjectListView olv) where T : class
{
/// <summary>
/// Create a typed wrapper around the given list.
/// </summary>
/// <param name="olv">The listview to be wrapped</param>
public TypedObjectListView(ObjectListView olv) {
this.olv = olv;
}
//--------------------------------------------------------------------------------------
// Properties
@@ -115,7 +112,7 @@ namespace BrightIdeasSoftware
get { return olv; }
set { olv = value; }
}
private ObjectListView olv;
private ObjectListView olv = olv;
/// <summary>
/// Get or set the list of all model objects
@@ -325,16 +322,13 @@ namespace BrightIdeasSoftware
/// A type-safe wrapper around an OLVColumn
/// </summary>
/// <typeparam name="T"></typeparam>
public class TypedColumn<T> where T : class
/// <remarks>
/// Creates a TypedColumn
/// </remarks>
/// <param name="column"></param>
public class TypedColumn<T>(OLVColumn column) where T : class
{
/// <summary>
/// Creates a TypedColumn
/// </summary>
/// <param name="column"></param>
public TypedColumn(OLVColumn column) {
this.column = column;
}
private OLVColumn column;
private OLVColumn column = column;
/// <summary>
///

View File

@@ -175,7 +175,7 @@ namespace BrightIdeasSoftware
public override IList CheckedObjects {
get {
// If we aren't should checkboxes, then no objects can be checked
if (!this.CheckBoxes)
if (!this.GetCheckBoxes())
return new ArrayList();
// If the data source has somehow vanished, we can't do anything
@@ -199,7 +199,7 @@ namespace BrightIdeasSoftware
return objects;
}
set {
if (!this.CheckBoxes)
if (!this.GetCheckBoxes())
return;
// If a custom check state getter is install, we can't use our check state management

View File

@@ -1,6 +1,3 @@
**NOTICE: This project currently transited to a new maintainer. Development help would be greatly appreciated.**
<br/><br/>
<p align="center">
<img width="450" src="https://github.com/mRemoteNG/mRemoteNG/blob/mRemoteNGProjectFiles/Header_dark.png">
</p>
@@ -28,9 +25,6 @@
<a href="https://www.paypal.com/paypalme/mremoteng">
<img alt="PayPal" src="https://img.shields.io/badge/%24-PayPal-blue.svg?label=Donate&logo=PayPal&style=flat-square">
</a>
<a href="bitcoin:16fUnHUM3k7W9Fvpc6dug7TAdfeGEcLbSg">
<img alt="Bitcoin" src="https://img.shields.io/badge/%24-Bitcoin.svg?label=Donate&logo=bitcoin&style=flat-square">
</a>
</p>
<p align="center">
@@ -54,7 +48,7 @@
| ---------------|--------------|-----------|
| Stable | ![Build status](https://ci.appveyor.com/api/projects/status/rqwxjxldail7btcf?svg=true) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76.20/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.20) |
| Preview | ![Build status](https://ci.appveyor.com/api/projects/status/rqwxjxldail7btcf/branch/preview?svg=true) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.77.1/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.77.1) |
| Nightly | ![Build status](https://ci.appveyor.com/api/projects/status/rqwxjxldail7btcf/branch/develop?svg=true) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/2023.03.03-v1.77.3-nb/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/2023.03.03-v1.77.3-nb) |
| Nightly | ![Build status](https://ci.appveyor.com/api/projects/status/rqwxjxldail7btcf/branch/develop?svg=true) | [![Github Releases](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/20250916-v1.78.2-NB-(3177)/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/20250916-v1.78.2-NB-(3177)) |
## Features
@@ -90,10 +84,9 @@ You will need to compile it yourself using Visual Studio.
### Minimum Requirements
* [Microsoft Visual C++ Redistributable for Visual Studio 2015 - 2022](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)
* [Microsoft .NET 6.0 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/6.0)
* Microsoft Terminal Service Client 6.0 or later
* Needed if you use RDP. mstscax.dll and/or msrdp.ocx be registered.
* [Microsoft .NET Desktop Runtime 9.0](https://dotnet.microsoft.com/download/dotnet/6.0)
* [Microsoft Visual C++ Redistributable x86 (note: use 32-bit, required until #2870 is resolved)](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-supported-redistributable-version)
* Microsoft Terminal Service Client 6.0 or later (needed if you use RDP with mstscax.dll and/or msrdp.ocx to be registered)
### Download
@@ -137,6 +130,7 @@ _If you are using the Portable version, simply deleting the folder that contains
* [PSmRemoteNG](https://github.com/realslacker/PSmRemoteNG) A module to create mRemoteNG connection files from PowerShell.
* [mRemoteNGOpenVPN](https://github.com/T3los/mRemoteNGOpenVPN) A script that can be embedded as an external tool to control OpenVPN.
* [mRemoteNG-Icons](https://github.com/bearlikelion/mRemoteNG-Icons) A collection of fancy icons to customize the connections
## Contribute

View File

@@ -1,38 +0,0 @@
U2FsdGVkX1/uEeToOEIrunpoPNl7NUYNQfI+ixMzGgKX0DlHZxa/PonAVd9NoAE+
dqWegkN8fa/M2HcW8moN5sN0yS88amG8cfwRZNRSgRB4IxDdYPjM/iX7y8FjUh9R
OZnGhq1rAkqcf7ASAdZfQDSFOAEDPQgByN4IB2j/G3ueqV3jf5sWWiM0ielcorWX
jXuEL7uIk9diI3Qh3BVqmrotzErzqTTLB4DWoL1aWqRRYH+exKahfcMT3C9r+tul
ETH6o1im3kdYzFgHl58FmihbHa+h1+c+DWVGGXRxJPw1DZfg8/+ldIy8J75aWimz
2MX+PiBVQj+wYlSSkQLj2EdbpSERlinE1O55ldwpbnMPAlYCgFRdO3/hiB6LiLLt
n9s8f32HLNG20Mk1oxXdN9VPOw+RwQpUf6Zfcyps6e/9EFKBLnwq4cYwM/dHRuez
w48EJX5wKzpukHn2UFg5aCRGYU/4NyUn+AlIjjCMBWY1R0uBhC340cl6YqoPFN12
clzbS6JdQS+ktusCeaKcsj2iknVqQrGY81LKrTaQZdfehGwAn9pMWE3iWRX80yzO
s08lpmHfPK4uhtlyIbdReLn4n7hvB8KRVa7Foms+4wpEwKrL8KF/8CYc89Tm3PSD
LCrLr7rzCHh51ncJXHAwZqY2ZRLnQBVwhIRsFYyZ595b89tuDY00sYpWnTKzWubK
UD993CmYKg1cA+mj6NR6iSmecawsUz68nI/nmHM2APE5cCCHSK3lz40e9Z9Hmy5Y
kVS6c86a+gwNyn4F9t3iISdj2vIOwGMVWQLeY+nwpiKnnOuI0XPtIMjNbhoaDToT
kph2ZVjqbpmYHgTSX71v8Y16Stl+p/dZn0dE2d4JhxOJxDN//H6y7mOwg8DYX9GP
rFBMIEWyEQyEFYTmWgztQ5KU89w0lV1qiWpaiWR/IDkGbUzHR8ELp4NHYPbZnuYa
FFXooJGPsQ02ioXPm18Lkhloo63lANgyBE0jc1x9hPrI0oVn1wTkKdeW13IbHzrn
VsGXeZz06bB46QChXUPmQ49sNkAXcMDnfNFM9ayUa8eVmNx9fWabtBy8qs7rpdv0
1y/2ud4Da9t7SAUvxwI65+b2Ytk05pLFLmQYb01g4BpBDxbJW3yw3CqKgMnLoZ3t
s2kiUpn7FEQU8jbpbFV+UB4DdJgm8S7o1gbTEWYTscZ7l+oLCmQgMYoi/EJDDIa2
cCSdGy4p7kLlLUoO438Mz36+FDf6qX2B86ezVdNnXQb3UPljjDxiOFM6NkI3HTpl
RqxjBg8JdrwoQ1UMha6ucDKhPXq1xkg0dpO9QyjxywssG3krgQ5Py64s5Xu7IgQm
AzmwGTZ6gFZlDTr9SpJkiucF9vexCo6JHHkF8OjhS49FanqB8otJvg5JclVugP51
LcqqvuMkAsFago261SNcOhgtR6nV5B9QgHyr66c6YnTlwt07T1Qq3S1lw2x0Eccs
PKbJDVU5rAHiM71QYmwsuoC8qkYPTtVPIoUTs+5u5aLywVoLejr1dE5twNXy5PYY
fDwubg0YG3kchvv85N3epZ1h50ADq3W3msU9bWDKWwdwIbpGq+dwjkLssBQmjVtI
R8rGbt1DgL7xtRNF9ESnWVkfHJvJu/5oD6wGAU/oIfBxVON0VYb1evc8wRdQTbDH
Dnt+aKwcSPYdyGVRKfRtBGvEZ8rB5hzCXQnS795L0imdfXjBSJn7Pnl9VwpcB3Pr
aZ6s0GcB8kYDEXzjv+o7JF6k5i2I+sVGwvFVGIoVd/Igq2ysrk/GfWVov0SUu78A
JeHYdtRuKwXOdZw2cjZQ72bvFaHOuoXrQnyKyZDWRyu0NB5HLW75v/YEbr4msIm9
E+3HFwRvKSTfUx/M4NgVKrgsHDeBRD4tLNx/SerQvqaplunM7OfAtULucveUhwSo
vT6uNK3URe1qDgX554cz8c6+KrkglTLFMuKfNWj3q/uSM0BxTTD9QgorNdlMmErH
TfV/ZpZACpuMFRbC5xQRkCG1x4U12pdPbtIkGtVBJROEXhP1aw3BDWwrIN7zSgfj
8I4OF4fbj/rSuvI4klzi1zlUMQQnenlRURE+7DKRxtWipJhW9vtDI0LXN7gGfmbR
73uR3YUny6zUJ0svqaWj4Eo6t3g99nmk4D2hm/622dRksv2HqEQiq29jJxlcbdZB
PU96wOp54s/BzgodyI5dh+xL06Obr9AltLV9vw3iK0VBZqquj9FuhvWC1tYlZQJF
AOgVDOGUZzmAJXftI7gaohFBwsT5tAHQtBuY7tB3b1hrnfrFb9FTNxGZJKcIH3p4
dOAvedsfuq+2/lU9iM4tX9fjSzfnGRZRuKCGDSdhE6EDik9/f2kSCoY9z0zJwdZH
324TpGbZNbgcwgHDL9i5Nsnaua5yxtr0/Fr1We1tvn0=

View File

@@ -5,76 +5,60 @@ VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 14.0.25420.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNG", "mRemoteNG\mRemoteNG.csproj", "{4934A491-40BC-4E5B-9166-EA1169A220F6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNGTests", "mRemoteNGTests\mRemoteNGTests.csproj", "{1453B37F-8621-499E-B0B2-6091F76DC0BB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mRemoteNGInstaller", "mRemoteNGInstaller", "{4FE795BE-646E-4F1B-BAD0-A68EA26394DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomActions", "mRemoteNGInstaller\CustomActions\CustomActions.csproj", "{5423D985-CB48-4344-B47F-E8C6D60C8B04}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Installer", "mRemoteNGInstaller\Installer\Installer.wixproj", "{F0168B9F-6815-40DF-BA53-46CEE7683B68}"
ProjectSection(ProjectDependencies) = postProject
{4934A491-40BC-4E5B-9166-EA1169A220F6} = {4934A491-40BC-4E5B-9166-EA1169A220F6}
{5423D985-CB48-4344-B47F-E8C6D60C8B04} = {5423D985-CB48-4344-B47F-E8C6D60C8B04}
{A56A2029-79B8-492A-ABE5-D2BFE05801BD} = {A56A2029-79B8-492A-ABE5-D2BFE05801BD}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNGSpecs", "mRemoteNGSpecs\mRemoteNGSpecs.csproj", "{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalConnectors", "ExternalConnectors\ExternalConnectors.csproj", "{A56A2029-79B8-492A-ABE5-D2BFE05801BD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectListView.NetCore", "ObjectListView\ObjectListView.NetCore.csproj", "{5718734C-03AC-4954-89B1-1723CF03AF10}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|arm64 = Debug|arm64
Debug|x64 = Debug|x64
Release Installer and Portable|arm64 = Release Installer and Portable|arm64
Release Installer and Portable|x64 = Release Installer and Portable|x64
Release|arm64 = Release|arm64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|arm64.ActiveCfg = Debug|arm64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|arm64.Build.0 = Debug|arm64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x64.ActiveCfg = Debug|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x64.Build.0 = Debug|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer and Portable|arm64.ActiveCfg = Release Portable|arm64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer and Portable|arm64.Build.0 = Release Portable|arm64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer and Portable|x64.ActiveCfg = Release Portable|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer and Portable|x64.Build.0 = Release Portable|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|arm64.ActiveCfg = Release|arm64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|arm64.Build.0 = Release|arm64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x64.ActiveCfg = Release|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x64.Build.0 = Release|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x64.ActiveCfg = Debug|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x64.Build.0 = Debug|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer and Portable|x64.ActiveCfg = Release Portable|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x64.ActiveCfg = Release|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x64.ActiveCfg = Debug|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x64.Build.0 = Debug|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer and Portable|x64.Build.0 = Release|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x64.ActiveCfg = Release|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x64.ActiveCfg = Debug|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x64.Build.0 = Debug|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer and Portable|x64.Build.0 = Release|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|x64.ActiveCfg = Release|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x64.ActiveCfg = Debug|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x64.Build.0 = Debug|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer and Portable|x64.ActiveCfg = Release Installer|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|x64.ActiveCfg = Release|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|arm64.ActiveCfg = Debug|arm64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|arm64.Build.0 = Debug|arm64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|x64.ActiveCfg = Debug|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|x64.Build.0 = Debug|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer and Portable|arm64.ActiveCfg = Release Portable|arm64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer and Portable|arm64.Build.0 = Release Portable|arm64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer and Portable|x64.ActiveCfg = Release Portable|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer and Portable|x64.Build.0 = Release Portable|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|arm64.ActiveCfg = Release|arm64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|arm64.Build.0 = Release|arm64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|x64.ActiveCfg = Release|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|x64.Build.0 = Release|x64
{5718734C-03AC-4954-89B1-1723CF03AF10}.Debug|arm64.ActiveCfg = Debug|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Debug|arm64.Build.0 = Debug|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Debug|x64.ActiveCfg = Debug|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Debug|x64.Build.0 = Debug|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release Installer and Portable|arm64.ActiveCfg = Release|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release Installer and Portable|arm64.Build.0 = Release|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release Installer and Portable|x64.ActiveCfg = Release|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release Installer and Portable|x64.Build.0 = Release|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release|arm64.ActiveCfg = Release|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release|arm64.Build.0 = Release|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release|x64.ActiveCfg = Release|Any CPU
{5718734C-03AC-4954-89B1-1723CF03AF10}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5423D985-CB48-4344-B47F-E8C6D60C8B04} = {4FE795BE-646E-4F1B-BAD0-A68EA26394DD}
{F0168B9F-6815-40DF-BA53-46CEE7683B68} = {4FE795BE-646E-4F1B-BAD0-A68EA26394DD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5D390A0C-2FC4-4908-B86E-7E4DEF5916EC}
EndGlobalSection

View File

@@ -0,0 +1,124 @@
using Microsoft.Win32;
using Newtonsoft.Json.Linq;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace mRemoteNG.DotNet.Update
{
[SupportedOSPlatform("windows")]
public class DotNetRuntimeCheck
{
public const string RequiredDotnetVersion = "9.0";
private const string ReleaseFeedUrl = "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json";
#region Installed Version Check
/// <summary>
/// Gets the installed .NET 9 runtime version if present
/// </summary>
/// <returns>The version string (e.g., "v9.0.0") or null if not found</returns>
[SupportedOSPlatform("windows")]
public static string? GetLatestDotNetRuntimeVersion()
{
string[] registryPaths = new[]
{
@"SOFTWARE\dotnet\Setup\InstalledVersions\x86",
@"SOFTWARE\dotnet\Setup\InstalledVersions\x64",
@"SOFTWARE\dotnet\Setup\InstalledVersions\arm64"
};
foreach (string path in registryPaths)
{
try
{
using RegistryKey? key = Registry.LocalMachine.OpenSubKey(path);
if (key == null)
{
continue;
}
// Check for the "sharedhost" subkey
using (RegistryKey? sharedHostKey = key.OpenSubKey("sharedhost"))
{
if (sharedHostKey == null) {
continue;
};
// Look for the "Version" value in sharedhost
object? versionValue = sharedHostKey.GetValue("Version");
if (versionValue != null)
{
string? version = versionValue.ToString();
if (!string.IsNullOrWhiteSpace(version))
{
return version;
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error checking registry fallback: {ex.Message}");
}
}
return null;
}
#endregion Installed Version Check
#region Latest Online Version Check
public static async Task<(string latestRuntimeVersion, string downloadUrl)> GetLatestAvailableDotNetVersionAsync()
{
try
{
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("User-Agent", "DotNetRuntimeChecker");
string jsonContent = await httpClient.GetStringAsync(ReleaseFeedUrl);
JObject releasesIndex = JObject.Parse(jsonContent);
// Find the entry for .NET matching RequiredDotnetVersion
JToken? dotnetEntry = releasesIndex["releases-index"]?.FirstOrDefault(entry => entry["channel-version"]?.ToString() == RequiredDotnetVersion);
if (dotnetEntry != null && dotnetEntry["latest-runtime"] != null)
{
string? latestRuntimeVersion = dotnetEntry["latest-runtime"]?.ToString();
string arch;
switch (RuntimeInformation.OSArchitecture)
{
case Architecture.Arm64:
arch = "arm64";
break;
case Architecture.X86:
arch = "x86";
break;
case Architecture.X64:
arch = "x64";
break;
default:
throw new NotSupportedException($"Unsupported architecture: {RuntimeInformation.OSArchitecture}");
}
if (!string.IsNullOrEmpty(latestRuntimeVersion))
{
// Construct the download URL using the latest version
string downloadUrl = $"https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-{latestRuntimeVersion}-windows-{arch}-installer";
return (latestRuntimeVersion, downloadUrl);
}
}
return ("Unknown", "");
}
catch (Exception ex)
{
Console.WriteLine($"Error fetching latest version: {ex.Message}");
return ("Unknown", "");
}
}
#endregion Latest Online Version Check
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace mRemoteNG.App.Update
{
public class InternetConnection
{
public static bool IsPosible()
{
try
{
using var client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(5);
return client.GetAsync("https://www.microsoft.com").Result.IsSuccessStatusCode;
}
catch (Exception)
{
return false;
}
}
}
}

View File

@@ -0,0 +1,42 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Runtime.Versioning; // Add for SupportedOSPlatform
namespace mRemoteNG.App.Update
{
public class VCppRuntimeCheck
{
[SupportedOSPlatform("windows")]
public static List<string> GetInstalledVcRedistVersions()
{
var installedVersions = new List<string>();
var baseKeys = new[]
{
@"SOFTWARE\Microsoft\VisualStudio",
@"SOFTWARE\WOW6432Node\Microsoft\VisualStudio"
};
for (int major = 14; major <= 17; major++) // Covers 20152022+
{
for (int minor = 0; minor <= 3; minor++)
{
string version = $"{major}.{minor}";
foreach (var baseKey in baseKeys)
{
string path = $@"{baseKey}\{version}\VC\Runtimes\x64";
using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(path))
{
if (key?.GetValue("Installed") is int installed && installed == 1)
{
installedVersions.Add(version);
}
}
}
}
}
return installedVersions;
}
}
}

View File

@@ -54,8 +54,11 @@ namespace mRemoteNG.App.Info
public static Version GetApplicationVersion()
{
_ = System.Version.TryParse(ApplicationVersion, out Version v);
return v;
string cleanedVersion = ApplicationVersion.Split(' ')[0].Replace("(", "").Replace(")", "").Replace("Build", "");
cleanedVersion = cleanedVersion + "." + ApplicationVersion.Split(' ')[^1].Replace(")", "");
_ = System.Version.TryParse(cleanedVersion, out Version parsedVersion);
return parsedVersion;
}
}
}

View File

@@ -9,14 +9,9 @@ using mRemoteNG.Resources.Language;
namespace mRemoteNG.App.Initialization
{
[SupportedOSPlatform("windows")]
public class StartupDataLogger
public class StartupDataLogger(MessageCollector messageCollector)
{
private readonly MessageCollector _messageCollector;
public StartupDataLogger(MessageCollector messageCollector)
{
_messageCollector = messageCollector ?? throw new ArgumentNullException(nameof(messageCollector));
}
private readonly MessageCollector _messageCollector = messageCollector ?? throw new ArgumentNullException(nameof(messageCollector));
public void LogStartupData()
{

View File

@@ -1,101 +1,158 @@
using System;
using Microsoft.IdentityModel.Tokens;
using mRemoteNG.App.Update;
using mRemoteNG.Config.Settings;
using mRemoteNG.DotNet.Update;
using mRemoteNG.DotNet.Update;
using mRemoteNG.UI.Forms;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using mRemoteNG.Config.Settings;
using mRemoteNG.UI.Forms;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class ProgramRoot
{
private static Mutex _mutex;
private static Mutex? _mutex;
private static FrmSplashScreenNew _frmSplashScreen = null;
private static string customResourcePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Languages");
/// <summary>
/// The main entry point for the application.
/// </summary>
private static System.Threading.Thread? _wpfSplashThread;
private static FrmSplashScreenNew? _wpfSplash;
[STAThread]
public static void Main(string[] args)
{
Trace.WriteLine("!!!!!!=============== TEST ==================!!!!!!!!!!!!!");
// Forcing to load System.Configuration.ConfigurationManager before any other assembly to be able to check settings
try
{
string assemblyFile = "System.Configuration.ConfigurationManager" + ".dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
// Ensure the real entry point is definitely STA
MainAsync(args).GetAwaiter().GetResult();
}
if (File.Exists(assemblyPath))
{
Assembly.LoadFrom(assemblyPath);
}
}
catch (FileNotFoundException ex)
{
Trace.WriteLine("Error occured: " + ex.Message);
}
//Subscribe to AssemblyResolve event
private static Task MainAsync(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
//Check if local settings DB exist or accessible
CheckLockalDB();
string? installedVersion = DotNetRuntimeCheck.GetLatestDotNetRuntimeVersion();
//installedVersion = ""; // Force check for testing purposes
Lazy<bool> singleInstanceOption = new Lazy<bool>(() => Properties.OptionsStartupExitPage.Default.SingleInstance);
var checkFail = false;
// Checking .NET Runtime version
var (latestRuntimeVersion, downloadUrl) = DotNetRuntimeCheck.GetLatestAvailableDotNetVersionAsync().GetAwaiter().GetResult();
if (string.IsNullOrEmpty(installedVersion))
{
try
{
var result = MessageBox.Show(
$".NET Desktop Runtime at least {DotNetRuntimeCheck.RequiredDotnetVersion}.0 is required.\n" +
"The application will now exit.\n\nPlease download and install latest desktop runtime:\n" + downloadUrl,
"Missing .NET " + DotNetRuntimeCheck.RequiredDotnetVersion + " Runtime",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Information);
if (result == DialogResult.OK && InternetConnection.IsPosible())
{
try
{
Process.Start(new ProcessStartInfo(fileName: downloadUrl) { UseShellExecute = true });
}
catch (Exception ex)
{
MessageBox.Show($"Unable to open download link: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
catch { }
checkFail = true;
}
// Checking Visual C++ Redistributable version
if (VCppRuntimeCheck.GetInstalledVcRedistVersions() == null || VCppRuntimeCheck.GetInstalledVcRedistVersions().Count == 0)
{
var downloadUrl2 = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
try
{
var result = MessageBox.Show(
$"A Visual C++ (MSVC) runtime library is required.\n" +
"The application will now exit.\n\nPlease download and install latest desktop runtime:\n" + downloadUrl2,
"Missing Visual C++ Redistributable x86 Runtime",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Information);
if (result == DialogResult.OK && InternetConnection.IsPosible())
{
try
{
Process.Start(new ProcessStartInfo(fileName: downloadUrl2) { UseShellExecute = true });
}
catch (Exception ex)
{
MessageBox.Show($"Unable to open download link: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
catch { }
checkFail = true;
}
if (checkFail)
{
Environment.Exit(0);
}
Lazy<bool> singleInstanceOption = new(() => Properties.OptionsStartupExitPage.Default.SingleInstance);
if (singleInstanceOption.Value)
{
StartApplicationAsSingleInstance();
}
else
{
StartApplication();
return Task.CompletedTask;
}
// Assembly resolve handler
private static Assembly? OnAssemblyResolve(object? sender, ResolveEventArgs args)
{
try
{
string assemblyName = new AssemblyName(args.Name).Name ?? string.Empty;
if (assemblyName.EndsWith(".resources", StringComparison.OrdinalIgnoreCase))
return null;
string assemblyFile = assemblyName + ".dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
if (File.Exists(assemblyPath))
return Assembly.LoadFrom(assemblyPath);
}
catch
{
// Suppress resolution exceptions; return null to continue standard probing
}
return null;
}
private static void CheckLockalDB()
{
LocalSettingsDBManager settingsManager = new LocalSettingsDBManager(dbPath: "mRemoteNG.appSettings", useEncryption: false, schemaFilePath: "");
LocalDBManager settingsManager = new LocalDBManager(dbPath: "mRemoteNG.appSettings", useEncryption: false, schemaFilePath: "");
}
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs resolveArgs)
{
string assemblyName = new AssemblyName(resolveArgs.Name).Name.Replace(".resources", string.Empty);
string assemblyFile = assemblyName + ".dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
return null;
}
private static void StartApplication()
{
CatchAllUnhandledExceptions();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
_frmSplashScreen = FrmSplashScreenNew.GetInstance();
Screen targetScreen = Screen.PrimaryScreen;
Rectangle viewport = targetScreen.WorkingArea;
_frmSplashScreen.Top = viewport.Top;
_frmSplashScreen.Left = viewport.Left;
// normally it should be screens[1] however due DPI apply 1 size "same" as default with 100%
_frmSplashScreen.Left = viewport.Left + (targetScreen.Bounds.Size.Width - _frmSplashScreen.Width) / 2;
_frmSplashScreen.Top = viewport.Top + (targetScreen.Bounds.Size.Height - _frmSplashScreen.Height) / 2;
_frmSplashScreen.ShowInTaskbar = false;
_frmSplashScreen.Show();
ShowSplashOnStaThread();
Application.Run(FrmMain.Default);
}
@@ -134,8 +191,24 @@ namespace mRemoteNG.App
Process currentProcess = Process.GetCurrentProcess();
foreach (Process enumeratedProcess in Process.GetProcessesByName(currentProcess.ProcessName))
{
// Safely check for null MainModule and FileName
string? enumeratedFileName = null;
string? currentFileName = null;
try
{
enumeratedFileName = enumeratedProcess.MainModule?.FileName;
currentFileName = currentProcess.MainModule?.FileName;
}
catch
{
// Access to MainModule can throw exceptions for some processes; ignore and continue
continue;
}
if (enumeratedProcess.Id != currentProcess.Id &&
enumeratedProcess.MainModule.FileName == currentProcess.MainModule.FileName &&
!string.IsNullOrEmpty(enumeratedFileName) &&
!string.IsNullOrEmpty(currentFileName) &&
enumeratedFileName == currentFileName &&
enumeratedProcess.MainWindowHandle != IntPtr.Zero)
windowHandle = enumeratedProcess.MainWindowHandle;
}
@@ -145,31 +218,56 @@ namespace mRemoteNG.App
private static void CatchAllUnhandledExceptions()
{
System.Windows.Forms.Application.ThreadException += ApplicationOnThreadException;
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += ApplicationOnThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
}
private static void ApplicationOnThreadException(object sender, ThreadExceptionEventArgs e)
{
// if (PresentationSource.FromVisual(FrmSplashScreenNew))
FrmSplashScreenNew.GetInstance().Close();
CloseSplash();
if (FrmMain.Default.IsDisposed) return;
FrmUnhandledException window = new(e.Exception, false);
window.ShowDialog(FrmMain.Default);
}
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//TODO: Check if splash closed properly
//if (!FrmSplashScreenNew.GetInstance().IsDisposed)
// FrmSplashScreenNew.GetInstance().Close();
FrmUnhandledException window = new(e.ExceptionObject as Exception, e.IsTerminating);
window.ShowDialog(FrmMain.Default);
}
private static void ShowSplashOnStaThread()
{
_wpfSplashThread = new System.Threading.Thread(() =>
{
_wpfSplash = FrmSplashScreenNew.GetInstance();
// Center the splash screen on the primary screen before showing it
_wpfSplash.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
_wpfSplash.ShowInTaskbar = false;
_wpfSplash.Show();
System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(_wpfSplash);
System.Windows.Threading.Dispatcher.Run(); // WPF message loop
})
{ IsBackground = true };
_wpfSplashThread.SetApartmentState(System.Threading.ApartmentState.STA);
_wpfSplashThread.Start();
}
private static void CloseSplash()
{
if (_wpfSplash != null)
{
_wpfSplash.Dispatcher.Invoke(() => _wpfSplash.Close());
_wpfSplash = null;
}
if (_wpfSplashThread != null)
{
_wpfSplashThread.Join();
_wpfSplashThread = null;
}
}
}
}

View File

@@ -84,10 +84,8 @@ namespace mRemoteNG.App
try
{
await _appUpdate.GetUpdateInfoAsync();
if (_appUpdate.IsUpdateAvailable())
{
Windows.Show(WindowType.Update);
}
// Update is available, but don't show the panel automatically at startup
// User can check for updates manually via Help > Check for Updates menu
}
catch (Exception ex)
{

View File

@@ -26,8 +26,9 @@ namespace mRemoteNG.App
internal static ConfigWindow ConfigForm { get; set; } = new ConfigWindow();
internal static ErrorAndInfoWindow ErrorsForm { get; set; } = new ErrorAndInfoWindow();
private static UpdateWindow UpdateForm { get; set; } = new UpdateWindow();
internal static UpdateWindow UpdateForm { get; set; } = new UpdateWindow();
internal static SSHTransferWindow SshtransferForm { get; private set; } = new SSHTransferWindow();
internal static OptionsWindow OptionsFormWindow { get; private set; }
public static void Show(WindowType windowType)
@@ -44,8 +45,10 @@ namespace mRemoteNG.App
_adimportForm.Show(dockPanel);
break;
case WindowType.Options:
FrmMain.OptionsForm.SetActivatedPage(Language.StartupExit);
FrmMain.OptionsForm.Visible = true;
if (OptionsFormWindow == null || OptionsFormWindow.IsDisposed)
OptionsFormWindow = new OptionsWindow();
OptionsFormWindow.SetActivatedPage(Language.StartupExit);
OptionsFormWindow.Show(dockPanel);
break;
case WindowType.SSHTransfer:
if (SshtransferForm == null || SshtransferForm.IsDisposed)

View File

@@ -19,22 +19,16 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Connections
{
[SupportedOSPlatform("windows")]
public class SqlConnectionsLoader : IConnectionsLoader
public class SqlConnectionsLoader(
IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> localConnectionPropertiesDeserializer,
IDataProvider<string> dataProvider) : IConnectionsLoader
{
private readonly IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> _localConnectionPropertiesDeserializer;
private readonly IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> _localConnectionPropertiesDeserializer = localConnectionPropertiesDeserializer.ThrowIfNull(nameof(localConnectionPropertiesDeserializer));
private readonly IDataProvider<string> _dataProvider;
private readonly IDataProvider<string> _dataProvider = dataProvider.ThrowIfNull(nameof(dataProvider));
private Func<Optional<SecureString>> AuthenticationRequestor { get; set; } = () => MiscTools.PasswordDialog("", false);
public SqlConnectionsLoader(
IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> localConnectionPropertiesDeserializer,
IDataProvider<string> dataProvider)
{
_localConnectionPropertiesDeserializer = localConnectionPropertiesDeserializer.ThrowIfNull(nameof(localConnectionPropertiesDeserializer));
_dataProvider = dataProvider.ThrowIfNull(nameof(dataProvider));
}
public ConnectionTreeModel Load()
{
IDatabaseConnector connector = DatabaseConnectorFactory.DatabaseConnectorFromSettings();

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Data.Common;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.Config.DatabaseConnectors;
@@ -23,18 +24,11 @@ using mRemoteNG.Config.Serializers.ConnectionSerializers.Sql;
namespace mRemoteNG.Config.Connections
{
[SupportedOSPlatform("windows")]
public class SqlConnectionsSaver : ISaver<ConnectionTreeModel>
public class SqlConnectionsSaver(SaveFilter saveFilter, ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> localPropertieSerializer, IDataProvider<string> localPropertiesDataProvider) : ISaver<ConnectionTreeModel>
{
private readonly SaveFilter _saveFilter;
private readonly ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> _localPropertiesSerializer;
private readonly IDataProvider<string> _dataProvider;
public SqlConnectionsSaver(SaveFilter saveFilter, ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> localPropertieSerializer, IDataProvider<string> localPropertiesDataProvider)
{
_saveFilter = saveFilter ?? throw new ArgumentNullException(nameof(saveFilter));
_localPropertiesSerializer = localPropertieSerializer.ThrowIfNull(nameof(localPropertieSerializer));
_dataProvider = localPropertiesDataProvider.ThrowIfNull(nameof(localPropertiesDataProvider));
}
private readonly SaveFilter _saveFilter = saveFilter ?? throw new ArgumentNullException(nameof(saveFilter));
private readonly ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> _localPropertiesSerializer = localPropertieSerializer.ThrowIfNull(nameof(localPropertieSerializer));
private readonly IDataProvider<string> _dataProvider = localPropertiesDataProvider.ThrowIfNull(nameof(localPropertiesDataProvider));
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
{
@@ -133,11 +127,20 @@ namespace mRemoteNG.Config.Connections
if (rootTreeNode != null)
{
dbQuery =
databaseConnector.DbCommand(
"INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES('" +
MiscTools.PrepareValueForDB(rootTreeNode.Name) + "', 0, '" + strProtected + "','" +
ConnectionsFileInfo.ConnectionFileVersion + "')");
dbQuery = databaseConnector.DbCommand(
"INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES(@Name, 0, @Protected, @Version)");
DbParameter nameParam = dbQuery.CreateParameter();
nameParam.ParameterName = "@Name";
nameParam.Value = rootTreeNode.Name;
DbParameter protectedParam = dbQuery.CreateParameter();
protectedParam.ParameterName = "@Protected";
protectedParam.Value = strProtected;
DbParameter versionParam = dbQuery.CreateParameter();
versionParam.ParameterName = "@Version";
versionParam.Value = ConnectionsFileInfo.ConnectionFileVersion;
dbQuery.Parameters.Add(nameParam);
dbQuery.Parameters.Add(protectedParam);
dbQuery.Parameters.Add(versionParam);
dbQuery.ExecuteNonQuery();
}
else

View File

@@ -4,6 +4,7 @@ using System.Runtime.Versioning;
using mRemoteNG.App;
using mRemoteNG.Messages;
using mRemoteNG.Resources.Language;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.DataProviders
{
@@ -17,8 +18,13 @@ namespace mRemoteNG.Config.DataProviders
if (WeDontNeedToBackup(fileName))
return;
PathValidator.ValidatePathOrThrow(fileName, nameof(fileName));
string backupFileName =
string.Format(Properties.OptionsBackupPage.Default.BackupFileNameFormat, fileName, DateTime.Now);
PathValidator.ValidatePathOrThrow(backupFileName, nameof(backupFileName));
File.Copy(fileName, backupFileName);
}
catch (Exception ex)

View File

@@ -1,5 +1,6 @@
using System.IO;
using System.Linq;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.DataProviders
{
@@ -7,6 +8,8 @@ namespace mRemoteNG.Config.DataProviders
{
public void PruneBackupFiles(string filePath, int maxBackupsToKeep)
{
PathValidator.ValidatePathOrThrow(filePath, nameof(filePath));
string fileName = Path.GetFileName(filePath);
string directoryName = Path.GetDirectoryName(filePath);

View File

@@ -2,18 +2,30 @@
using System.IO;
using System.Runtime.Versioning;
using mRemoteNG.App;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.DataProviders
{
[SupportedOSPlatform("windows")]
public class FileDataProvider : IDataProvider<string>
{
private string _filePath;
[SupportedOSPlatform("windows")]
public string FilePath { get; set; }
public string FilePath
{
get => _filePath;
set
{
PathValidator.ValidatePathOrThrow(value, nameof(FilePath));
_filePath = value;
}
}
public FileDataProvider(string filePath)
{
FilePath = filePath;
PathValidator.ValidatePathOrThrow(filePath, nameof(filePath));
_filePath = filePath;
}
public virtual string Load()
@@ -59,6 +71,7 @@ namespace mRemoteNG.Config.DataProviders
{
try
{
PathValidator.ValidatePathOrThrow(newPath, nameof(newPath));
File.Move(FilePath, newPath);
FilePath = newPath;
}

View File

@@ -3,14 +3,9 @@
namespace mRemoteNG.Config.DataProviders
{
[SupportedOSPlatform("windows")]
public class FileDataProviderWithRollingBackup : FileDataProvider
public class FileDataProviderWithRollingBackup(string filePath) : FileDataProvider(filePath)
{
private readonly FileBackupCreator _fileBackupCreator;
public FileDataProviderWithRollingBackup(string filePath) : base(filePath)
{
_fileBackupCreator = new FileBackupCreator();
}
private readonly FileBackupCreator _fileBackupCreator = new FileBackupCreator();
public override void Save(string content)
{

View File

@@ -1,13 +1,8 @@
namespace mRemoteNG.Config.DataProviders
{
public class InMemoryStringDataProvider : IDataProvider<string>
public class InMemoryStringDataProvider(string initialContents = "") : IDataProvider<string>
{
private string _contents;
public InMemoryStringDataProvider(string initialContents = "")
{
_contents = initialContents;
}
private string _contents = initialContents;
public string Load()
{

View File

@@ -3,20 +3,15 @@ using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Messages;
using mRemoteNG.App;
using MySql.Data.MySqlClient;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Runtime.Versioning;
namespace mRemoteNG.Config.DataProviders
{
[SupportedOSPlatform("windows")]
public class SqlDataProvider : IDataProvider<DataTable>
public class SqlDataProvider(IDatabaseConnector databaseConnector) : IDataProvider<DataTable>
{
public IDatabaseConnector DatabaseConnector { get; }
public SqlDataProvider(IDatabaseConnector databaseConnector)
{
DatabaseConnector = databaseConnector;
}
public IDatabaseConnector DatabaseConnector { get; } = databaseConnector;
public DataTable Load()
{

View File

@@ -1,44 +1,148 @@
using System;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using LiteDB;
namespace mRemoteNG.Config.DatabaseConnectors
{
[SupportedOSPlatform("windows")]
//[SupportedOSPlatform("windows")]
/// <summary>
/// A helper class for testing database connectivity
/// </summary>
///
using System;
using System.Data.SqlClient;
public class DatabaseConnectionTester
{
public async Task<ConnectionTestResult> TestConnectivity(string type,
string server,
string database,
string username,
string password)
public async Task<ConnectionTestResult> TestConnectivity(string type, string server, string database, string username, string password)
{
using (IDatabaseConnector dbConnector = DatabaseConnectorFactory.DatabaseConnector(type, server, database, username, password))
try
{
try
// Build the connection string based on the provided parameters
string connectionString = $"Data Source={server};Initial Catalog={database};User ID={username};Password={password}";
// Attempt to open a connection to the database
using (SqlConnection connection = new SqlConnection(connectionString))
{
await dbConnector.ConnectAsync();
return ConnectionTestResult.ConnectionSucceded;
await connection.OpenAsync();
}
catch (SqlException sqlException)
return ConnectionTestResult.ConnectionSucceded;
}
catch (SqlException ex)
{
// Handle specific SQL exceptions
switch (ex.Number)
{
if (sqlException.Message.Contains("The server was not found"))
return ConnectionTestResult.ServerNotAccessible;
if (sqlException.Message.Contains("Cannot open database"))
case 4060: // Invalid Database
return ConnectionTestResult.UnknownDatabase;
if (sqlException.Message.Contains("Login failed for user"))
case 18456: // Login Failed
return ConnectionTestResult.CredentialsRejected;
return ConnectionTestResult.UnknownError;
}
catch (Exception)
{
return ConnectionTestResult.UnknownError;
case -1: // Server not accessible
return ConnectionTestResult.ServerNotAccessible;
default:
return ConnectionTestResult.UnknownError;
}
}
catch
{
// Handle any other exceptions
return ConnectionTestResult.UnknownError;
}
}
}
//public class DatabaseConnectionTester
//{
//public async Task<ConnectionTestResult> TestConnectivity(string type, string server, string database, string username, string password)
//{
//using IDatabaseConnector dbConnector = DatabaseConnectorFactory.DatabaseConnector(type, server, database, username, password);
//try
//{
// Validate architecture compatibility
//if (!Environment.Is64BitProcess)
//{
// throw new PlatformNotSupportedException("The application must run in a 64-bit process to use this database connector.");
// }
// Attempt to connect
//using (SqlConnection connection = new SqlConnection("Data Source=172.22.155.100,1433;Initial Catalog=Demo;Integrated Security=False;User ID=sa;Password=London123;Multiple Active Result Sets=True;Connect Timeout=30;Encrypt=True;Trust Server Certificate=True;Application Name=mRemoteNG;Application Intent=ReadOnly"))
//{
// connection.Open();
// Console.WriteLine("Connection successful!");
//}
//Console.WriteLine($"{RuntimeInformation.OSArchitecture}");
//Console.WriteLine($"{RuntimeInformation.ProcessArchitecture}");
//try
//{
// using (SqlConnection connection = new SqlConnection("Data Source=172.22.155.100,1433;Initial Catalog=Demo;Integrated Security=False;User ID=sa;Password=London123;Multiple Active Result Sets=True;Connect Timeout=30;Encrypt=True;Trust Server Certificate=True;Application Name=mRemoteNG;Application Intent=ReadOnly"))
// {
// connection.Open();
// Console.WriteLine("Connection successful!");
// }
//}
//catch (Exception ex)
//{
// Console.WriteLine($"Connection failed: {ex.Message}");
//}
//}
/*
try
{
using (SqlConnection connection = new SqlConnection("Data Source=172.22.155.100,1433;Initial Catalog=Demo;Integrated Security=False;User ID=sa;Password=London123;Multiple Active Result Sets=True;Connect Timeout=30;Encrypt=True;Trust Server Certificate=True;Application Name=mRemoteNG;Application Intent=ReadOnly"))
{
connection.Open();
}
}
catch (TypeInitializationException ex)
{
Console.WriteLine($"Type initialization error: {ex.InnerException?.Message}");
}
//await dbConnector.ConnectAsync();
return ConnectionTestResult.ConnectionSucceded;
}
catch (PlatformNotSupportedException ex)
{
// Log or handle architecture mismatch
Console.WriteLine($"Platform error: {ex.Message}");
return ConnectionTestResult.UnknownError;
}
catch (DllNotFoundException ex)
{
// Handle missing native dependencies
Console.WriteLine($"Missing dependency: {ex.Message}");
return ConnectionTestResult.UnknownError;
}
catch (BadImageFormatException ex)
{
// Handle architecture mismatch in native libraries
Console.WriteLine($"Architecture mismatch: {ex.Message}");
return ConnectionTestResult.UnknownError;
}
catch (SqlException sqlException)
{
if (sqlException.Message.Contains("The server was not found"))
return ConnectionTestResult.ServerNotAccessible;
if (sqlException.Message.Contains("Cannot open database"))
return ConnectionTestResult.UnknownDatabase;
if (sqlException.Message.Contains("Login failed for user"))
return ConnectionTestResult.CredentialsRejected;
return ConnectionTestResult.UnknownError;
}
catch (Exception ex)
{
// Log unexpected errors
Console.WriteLine($"Unexpected error: {ex.Message}");
return ConnectionTestResult.UnknownError;
}
*/
// }
// }
}

View File

@@ -1,7 +1,8 @@
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
using static BrightIdeasSoftware.TreeListView;
// ReSharper disable ArrangeAccessorOwnerBody
@@ -9,7 +10,7 @@ namespace mRemoteNG.Config.DatabaseConnectors
{
public class MSSqlDatabaseConnector : IDatabaseConnector
{
private DbConnection _dbConnection { get; set; } = default(SqlConnection);
private DbConnection _dbConnection { get; set; } = default!;
private string _dbConnectionString = "";
private readonly string _dbHost;
private readonly string _dbCatalog;
@@ -58,10 +59,17 @@ namespace mRemoteNG.Config.DatabaseConnectors
_dbConnectionString = new SqlConnectionStringBuilder
{
ApplicationName = "mRemoteNG",
ApplicationIntent = ApplicationIntent.ReadOnly,
DataSource = $"{hostParts[0]},{_dbPort}",
InitialCatalog = _dbCatalog,
UserID = _dbUsername,
Password = _dbPassword,
IntegratedSecurity = false,
Encrypt = true,
TrustServerCertificate = true,
ConnectTimeout = 30,
MultipleActiveResultSets = true
}.ToString();
}

View File

@@ -10,14 +10,9 @@ using mRemoteNG.Tools;
namespace mRemoteNG.Config.Import
{
[SupportedOSPlatform("windows")]
public class PortScanImporter : IConnectionImporter<IEnumerable<ScanHost>>
public class PortScanImporter(ProtocolType targetProtocolType) : IConnectionImporter<IEnumerable<ScanHost>>
{
private readonly ProtocolType _targetProtocolType;
public PortScanImporter(ProtocolType targetProtocolType)
{
_targetProtocolType = targetProtocolType;
}
private readonly ProtocolType _targetProtocolType = targetProtocolType;
public void Import(IEnumerable<ScanHost> hosts, ContainerInfo destinationContainer)
{

View File

@@ -0,0 +1,140 @@
using System;
using System.Management;
using System.Net.NetworkInformation;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
namespace mRemoteNG.Config.MachineIdentifier
{
[SupportedOSPlatform("windows")]
/// <summary>
/// Provides functionality to generate a consistent and unique machine identifier
/// based on hardware properties (disk serial number, MAC address, BIOS UUID, and machine name).
/// This class is supported only on Windows.
/// </summary>
public static class MachineIdentifierGenerator
{
/// <summary>
/// Generates a consistent machine identifier by combining hardware-based identifiers
/// (disk serial number, MAC address, BIOS UUID, and machine name) and hashing the result.
/// </summary>
/// <returns>A consistent and unique identifier for the machine.</returns>
/// <exception cref="PlatformNotSupportedException">Thrown if the method is called on a non-Windows platform.</exception>
public static string GenerateMachineIdentifier()
{
// Ensure the code runs only on Windows
if (!OperatingSystem.IsWindows())
{
throw new PlatformNotSupportedException("This method is supported only on Windows.");
}
// Retrieve hardware-based identifiers (with fallbacks)
string diskId = GetDiskSerialNumber() ?? "NO_DISK_ID";
string macAddress = GetMacAddress() ?? "NO_MAC_ADDRESS";
string biosUuid = GetBiosUuid() ?? "NO_BIOS_UUID";
string machineName = Environment.MachineName;
// Combine them into a single string
string combined = $"{diskId}_{macAddress}_{biosUuid}_{machineName}";
// Hash the combined string to ensure a fixed length and improve security
using (SHA256 sha256 = SHA256.Create())
{
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(combined));
return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
}
}
/// <summary>
/// Retrieves the serial number of the first physical disk using WMI.
/// </summary>
/// <returns>The disk serial number, or null if the serial number cannot be retrieved.</returns>
private static string GetDiskSerialNumber()
{
try
{
using (ManagementObjectSearcher searcher = new("SELECT SerialNumber FROM Win32_DiskDrive"))
{
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (wmi_HD["SerialNumber"] != null)
{
string serialNumber = wmi_HD["SerialNumber"].ToString().Trim();
if (!string.IsNullOrEmpty(serialNumber))
{
return serialNumber;
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error retrieving disk serial number: {ex.Message}");
}
return null; // Return null if the disk serial number cannot be retrieved
}
/// <summary>
/// Retrieves the MAC address of the first active network adapter.
/// </summary>
/// <returns>The MAC address, or null if the MAC address cannot be retrieved.</returns>
private static string GetMacAddress()
{
try
{
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in interfaces)
{
if (adapter.OperationalStatus == OperationalStatus.Up)
{
string macAddress = adapter.GetPhysicalAddress().ToString();
if (!string.IsNullOrEmpty(macAddress))
{
return macAddress;
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error retrieving MAC address: {ex.Message}");
}
return null; // Return null if the MAC address cannot be retrieved
}
/// <summary>
/// Retrieves the BIOS UUID of the machine using WMI.
/// </summary>
/// <returns>The BIOS UUID, or null if the UUID cannot be retrieved.</returns>
private static string GetBiosUuid()
{
try
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UUID FROM Win32_ComputerSystemProduct"))
{
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (wmi_HD["UUID"] != null)
{
string uuid = wmi_HD["UUID"].ToString().Trim();
if (!string.IsNullOrEmpty(uuid))
{
return uuid;
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error retrieving BIOS UUID: {ex.Message}");
}
return null; // Return null if the BIOS UUID cannot be retrieved
}
}
}

View File

@@ -4,13 +4,8 @@ using mRemoteNG.Connection;
namespace mRemoteNG.Config.Putty
{
public class PuttySessionChangedEventArgs : EventArgs
public class PuttySessionChangedEventArgs(PuttySessionInfo sessionChanged = null) : EventArgs
{
public PuttySessionInfo Session { get; set; }
public PuttySessionChangedEventArgs(PuttySessionInfo sessionChanged = null)
{
Session = sessionChanged;
}
public PuttySessionInfo Session { get; set; } = sessionChanged;
}
}

View File

@@ -135,17 +135,17 @@ namespace mRemoteNG.Config.Putty
{
public static string[] Names => Instance.GetSessionNames();
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context)
{
return new StandardValuesCollection(Names);
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context)
{
return true;
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context)
{
return true;
}

View File

@@ -113,8 +113,10 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
: "";
connectionRecord.Password = headers.Contains("Password")
? connectionCsv[headers.IndexOf("Password")].ConvertToSecureString()
: "".ConvertToSecureString();
// ? connectionCsv[headers.IndexOf("Password")].ConvertToSecureString()
// : "".ConvertToSecureString();
? connectionCsv[headers.IndexOf("Password")]
: "";
connectionRecord.Domain = headers.Contains("Domain")
? connectionCsv[headers.IndexOf("Domain")]

View File

@@ -112,7 +112,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv
sb.Append(FormatForCsv(con.Username));
if (_saveFilter.SavePassword)
sb.Append(con.Password?.ConvertToUnsecureString() + ";");
//sb.Append(con.Password?.ConvertToUnsecureString() + ";");
sb.Append(con.Password + ";");
if (_saveFilter.SaveDomain)
sb.Append(FormatForCsv(con.Domain));

View File

@@ -131,7 +131,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Csv.RemoteDesktopMa
Hostname = hostString,
Port = port,
Username = username,
Password = password?.ConvertToSecureString(),
//Password = password?.ConvertToSecureString(),
Password = password,
Domain = domain,
Icon = connectionType.IconName ?? "mRemoteNG",
Description = description,

View File

@@ -21,16 +21,10 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Sql
{
[SupportedOSPlatform("windows")]
public class DataTableDeserializer : IDeserializer<DataTable, ConnectionTreeModel>
public class DataTableDeserializer(ICryptographyProvider cryptographyProvider, SecureString decryptionKey) : IDeserializer<DataTable, ConnectionTreeModel>
{
private readonly ICryptographyProvider _cryptographyProvider;
private readonly SecureString _decryptionKey;
public DataTableDeserializer(ICryptographyProvider cryptographyProvider, SecureString decryptionKey)
{
_cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
_decryptionKey = decryptionKey.ThrowIfNull(nameof(decryptionKey));
}
private readonly ICryptographyProvider _cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
private readonly SecureString _decryptionKey = decryptionKey.ThrowIfNull(nameof(decryptionKey));
public ConnectionTreeModel Deserialize(DataTable table)
{
@@ -113,7 +107,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Sql
connectionInfo.OpeningCommand = (string)dataRow["OpeningCommand"];
connectionInfo.Panel = (string)dataRow["Panel"];
var pw = dataRow["Password"] as string;
connectionInfo.Password = DecryptValue(pw ?? "").ConvertToSecureString();
//connectionInfo.Password = DecryptValue(pw ?? "").ConvertToSecureString();
connectionInfo.Password = DecryptValue(pw ?? "");
connectionInfo.Port = (int)dataRow["Port"];
connectionInfo.PostExtApp = (string)dataRow["PostExtApp"];
connectionInfo.PreExtApp = (string)dataRow["PreExtApp"];

View File

@@ -14,27 +14,20 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Sql
{
[SupportedOSPlatform("windows")]
public class DataTableSerializer : ISerializer<ConnectionInfo, DataTable>
public class DataTableSerializer(SaveFilter saveFilter, ICryptographyProvider cryptographyProvider, SecureString encryptionKey) : ISerializer<ConnectionInfo, DataTable>
{
private const int DELETE = 0;
private readonly ICryptographyProvider _cryptographyProvider;
private readonly SecureString _encryptionKey;
private readonly ICryptographyProvider _cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
private readonly SecureString _encryptionKey = encryptionKey.ThrowIfNull(nameof(encryptionKey));
private DataTable _dataTable;
private DataTable _sourceDataTable;
private readonly Dictionary<string, int> _sourcePrimaryKeyDict = [];
private const string TABLE_NAME = "tblCons";
private readonly SaveFilter _saveFilter;
private readonly SaveFilter _saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter));
private int _currentNodeIndex;
public Version Version { get; } = new Version(3, 0);
public DataTableSerializer(SaveFilter saveFilter, ICryptographyProvider cryptographyProvider, SecureString encryptionKey)
{
_saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter));
_cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
_encryptionKey = encryptionKey.ThrowIfNull(nameof(encryptionKey));
}
public void SetSourceDataTable(DataTable sourceDataTable)
{
_sourceDataTable = sourceDataTable;
@@ -519,7 +512,10 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Sql
dataRow["InheritVNCViewOnly"].Equals(false);
}
bool pwd = dataRow["Password"].Equals(_saveFilter.SavePassword ? _cryptographyProvider.Encrypt(connectionInfo.Password?.ConvertToUnsecureString(), _encryptionKey) : "") &&
//bool pwd = dataRow["Password"].Equals(_saveFilter.SavePassword ? _cryptographyProvider.Encrypt(connectionInfo.Password?.ConvertToUnsecureString(), _encryptionKey) : "") &&
// dataRow["VNCProxyPassword"].Equals(_cryptographyProvider.Encrypt(connectionInfo.VNCProxyPassword, _encryptionKey)) &&
// dataRow["RDGatewayPassword"].Equals(_cryptographyProvider.Encrypt(connectionInfo.RDGatewayPassword, _encryptionKey));
bool pwd = dataRow["Password"].Equals(_saveFilter.SavePassword ? _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey) : "") &&
dataRow["VNCProxyPassword"].Equals(_cryptographyProvider.Encrypt(connectionInfo.VNCProxyPassword, _encryptionKey)) &&
dataRow["RDGatewayPassword"].Equals(_cryptographyProvider.Encrypt(connectionInfo.RDGatewayPassword, _encryptionKey));
return !(pwd && isFieldNotChange && isInheritanceFieldNotChange);
@@ -572,10 +568,11 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Sql
dataRow["MacAddress"] = connectionInfo.MacAddress;
dataRow["Name"] = connectionInfo.Name;
dataRow["OpeningCommand"] = connectionInfo.OpeningCommand;
dataRow["OpeningCommand"] = connectionInfo.OpeningCommand;
// dataRow["OpeningCommand"] = connectionInfo.OpeningCommand; dublicate?
dataRow["Panel"] = connectionInfo.Panel;
dataRow["ParentID"] = connectionInfo.Parent?.ConstantID ?? "";
dataRow["Password"] = _saveFilter.SavePassword ? _cryptographyProvider.Encrypt(connectionInfo.Password?.ConvertToUnsecureString(), _encryptionKey) : "";
//dataRow["Password"] = _saveFilter.SavePassword ? _cryptographyProvider.Encrypt(connectionInfo.Password?.ConvertToUnsecureString(), _encryptionKey) : "";
dataRow["Password"] = _saveFilter.SavePassword ? _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey) : "";
dataRow["Port"] = connectionInfo.Port;
dataRow["PositionID"] = _currentNodeIndex;
dataRow["PostExtApp"] = connectionInfo.PostExtApp;

View File

@@ -61,7 +61,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
: new XAttribute("Domain", ""));
if (_saveFilter.SavePassword && !connectionInfo.Inheritance.Password)
element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password.ConvertToUnsecureString(), _encryptionKey)));
//element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password.ConvertToUnsecureString(), _encryptionKey)));
element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey)));
else
element.Add(new XAttribute("Password", ""));

View File

@@ -11,23 +11,16 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
{
// ReSharper disable once InconsistentNaming
[SupportedOSPlatform("windows")]
public class XmlConnectionNodeSerializer27 : ISerializer<ConnectionInfo, XElement>
public class XmlConnectionNodeSerializer27(ICryptographyProvider cryptographyProvider,
SecureString encryptionKey,
SaveFilter saveFilter) : ISerializer<ConnectionInfo, XElement>
{
private readonly ICryptographyProvider _cryptographyProvider;
private readonly SecureString _encryptionKey;
private readonly SaveFilter _saveFilter;
private readonly ICryptographyProvider _cryptographyProvider = cryptographyProvider ?? throw new ArgumentNullException(nameof(cryptographyProvider));
private readonly SecureString _encryptionKey = encryptionKey ?? throw new ArgumentNullException(nameof(encryptionKey));
private readonly SaveFilter _saveFilter = saveFilter ?? throw new ArgumentNullException(nameof(saveFilter));
public Version Version { get; } = new Version(2, 7);
public XmlConnectionNodeSerializer27(ICryptographyProvider cryptographyProvider,
SecureString encryptionKey,
SaveFilter saveFilter)
{
_cryptographyProvider = cryptographyProvider ?? throw new ArgumentNullException(nameof(cryptographyProvider));
_encryptionKey = encryptionKey ?? throw new ArgumentNullException(nameof(encryptionKey));
_saveFilter = saveFilter ?? throw new ArgumentNullException(nameof(saveFilter));
}
public XElement Serialize(ConnectionInfo connectionInfo)
{
XElement element = new(XName.Get("Node", ""));
@@ -62,7 +55,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
: new XAttribute("Domain", ""));
if (_saveFilter.SavePassword && !connectionInfo.Inheritance.Password)
element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password.ConvertToUnsecureString(), _encryptionKey)));
//element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password.ConvertToUnsecureString(), _encryptionKey)));
element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey)));
else
element.Add(new XAttribute("Password", ""));
}

View File

@@ -11,23 +11,16 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
{
// ReSharper disable once InconsistentNaming
[SupportedOSPlatform("windows")]
public class XmlConnectionNodeSerializer28 : ISerializer<ConnectionInfo, XElement>
public class XmlConnectionNodeSerializer28(ICryptographyProvider cryptographyProvider,
SecureString encryptionKey,
SaveFilter saveFilter) : ISerializer<ConnectionInfo, XElement>
{
private readonly ICryptographyProvider _cryptographyProvider;
private readonly SecureString _encryptionKey;
private readonly SaveFilter _saveFilter;
private readonly ICryptographyProvider _cryptographyProvider = cryptographyProvider ?? throw new ArgumentNullException(nameof(cryptographyProvider));
private readonly SecureString _encryptionKey = encryptionKey ?? throw new ArgumentNullException(nameof(encryptionKey));
private readonly SaveFilter _saveFilter = saveFilter ?? throw new ArgumentNullException(nameof(saveFilter));
public Version Version { get; } = new Version(2, 8);
public XmlConnectionNodeSerializer28(ICryptographyProvider cryptographyProvider,
SecureString encryptionKey,
SaveFilter saveFilter)
{
_cryptographyProvider = cryptographyProvider ?? throw new ArgumentNullException(nameof(cryptographyProvider));
_encryptionKey = encryptionKey ?? throw new ArgumentNullException(nameof(encryptionKey));
_saveFilter = saveFilter ?? throw new ArgumentNullException(nameof(saveFilter));
}
public XElement Serialize(ConnectionInfo connectionInfo)
{
XElement element = new(XName.Get("Node", ""));
@@ -49,6 +42,7 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
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("TabColor", connectionInfo.TabColor));
element.Add(new XAttribute("Id", connectionInfo.ConstantID));
if (!Runtime.UseCredentialManager)
@@ -62,7 +56,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
: new XAttribute("Domain", ""));
if (_saveFilter.SavePassword && !connectionInfo.Inheritance.Password)
element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password?.ConvertToUnsecureString(), _encryptionKey)));
//element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password?.ConvertToUnsecureString(), _encryptionKey)));
element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey)));
else
element.Add(new XAttribute("Password", ""));
}
@@ -193,6 +188,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
element.Add(new XAttribute("InheritIcon", inheritance.Icon.ToString().ToLowerInvariant()));
if (inheritance.Panel)
element.Add(new XAttribute("InheritPanel", inheritance.Panel.ToString().ToLowerInvariant()));
if (inheritance.TabColor)
element.Add(new XAttribute("InheritTabColor", inheritance.TabColor.ToString().ToLowerInvariant()));
if (inheritance.Password)
element.Add(new XAttribute("InheritPassword", inheritance.Password.ToString().ToLowerInvariant()));
if (inheritance.Port)

View File

@@ -94,8 +94,7 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
connections = _decryptor.LegacyFullFileDecrypt(connections);
if (connections != "")
{
_xmlDocument = new XmlDocument();
_xmlDocument.LoadXml(connections);
_xmlDocument = SecureXmlHelper.LoadXmlFromString(connections);
}
}
@@ -217,8 +216,8 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
if (!Runtime.UseCredentialManager || _confVersion <= 2.6) // 0.2 - 2.6
{
connectionInfo.Username = xmlnode.GetAttributeAsString("Username");
//connectionInfo.Password = _decryptor.Decrypt(xmlnode.GetAttributeAsString("Password"));
connectionInfo.Password = _decryptor.Decrypt(xmlnode.GetAttributeAsString("Password")).ConvertToSecureString();
connectionInfo.Password = _decryptor.Decrypt(xmlnode.GetAttributeAsString("Password"));
//connectionInfo.Password = _decryptor.Decrypt(xmlnode.GetAttributeAsString("Password")).ConvertToSecureString();
connectionInfo.Domain = xmlnode.GetAttributeAsString("Domain");
}
}
@@ -329,6 +328,7 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
connectionInfo.Inheritance.DisplayWallpaper = xmlnode.GetAttributeAsBool("InheritDisplayWallpaper");
connectionInfo.Inheritance.Icon = xmlnode.GetAttributeAsBool("InheritIcon");
connectionInfo.Inheritance.Panel = xmlnode.GetAttributeAsBool("InheritPanel");
connectionInfo.Inheritance.TabColor = xmlnode.GetAttributeAsBool("InheritTabColor");
connectionInfo.Inheritance.Port = xmlnode.GetAttributeAsBool("InheritPort");
connectionInfo.Inheritance.Protocol = xmlnode.GetAttributeAsBool("InheritProtocol");
connectionInfo.Inheritance.PuttySession = xmlnode.GetAttributeAsBool("InheritPuttySession");
@@ -351,6 +351,7 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
connectionInfo.Icon = xmlnode.GetAttributeAsString("Icon");
connectionInfo.Panel = xmlnode.GetAttributeAsString("Panel");
connectionInfo.TabColor = xmlnode.GetAttributeAsString("TabColor");
}
else
{

View File

@@ -12,17 +12,11 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
{
[SupportedOSPlatform("windows")]
public class XmlConnectionsDocumentCompiler
public class XmlConnectionsDocumentCompiler(ICryptographyProvider cryptographyProvider, ISerializer<ConnectionInfo, XElement> connectionNodeSerializer)
{
private readonly ICryptographyProvider _cryptographyProvider;
private readonly ICryptographyProvider _cryptographyProvider = cryptographyProvider ?? throw new ArgumentNullException(nameof(cryptographyProvider));
private SecureString _encryptionKey;
private readonly ISerializer<ConnectionInfo, XElement> _connectionNodeSerializer;
public XmlConnectionsDocumentCompiler(ICryptographyProvider cryptographyProvider, ISerializer<ConnectionInfo, XElement> connectionNodeSerializer)
{
_cryptographyProvider = cryptographyProvider ?? throw new ArgumentNullException(nameof(cryptographyProvider));
_connectionNodeSerializer = connectionNodeSerializer ?? throw new ArgumentNullException(nameof(connectionNodeSerializer));
}
private readonly ISerializer<ConnectionInfo, XElement> _connectionNodeSerializer = connectionNodeSerializer ?? throw new ArgumentNullException(nameof(connectionNodeSerializer));
public XDocument CompileDocument(ConnectionTreeModel connectionTreeModel, bool fullFileEncryption)
{

View File

@@ -4,14 +4,9 @@ using mRemoteNG.Security;
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
{
public class XmlConnectionsDocumentEncryptor
public class XmlConnectionsDocumentEncryptor(ICryptographyProvider cryptographyProvider)
{
private readonly ICryptographyProvider _cryptographyProvider;
public XmlConnectionsDocumentEncryptor(ICryptographyProvider cryptographyProvider)
{
_cryptographyProvider = cryptographyProvider;
}
private readonly ICryptographyProvider _cryptographyProvider = cryptographyProvider;
public XDocument EncryptDocument(XDocument documentToEncrypt, SecureString encryptionKey)
{

View File

@@ -14,22 +14,16 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
{
[SupportedOSPlatform("windows")]
public class XmlConnectionsSerializer : ISerializer<ConnectionTreeModel, string>,
public class XmlConnectionsSerializer(ICryptographyProvider cryptographyProvider,
ISerializer<ConnectionInfo, XElement> connectionNodeSerializer) : ISerializer<ConnectionTreeModel, string>,
ISerializer<ConnectionInfo, string>
{
private readonly ICryptographyProvider _cryptographyProvider;
private readonly ISerializer<ConnectionInfo, XElement> _connectionNodeSerializer;
private readonly ICryptographyProvider _cryptographyProvider = cryptographyProvider;
private readonly ISerializer<ConnectionInfo, XElement> _connectionNodeSerializer = connectionNodeSerializer;
public Version Version => _connectionNodeSerializer.Version;
public bool UseFullEncryption { get; set; }
public XmlConnectionsSerializer(ICryptographyProvider cryptographyProvider,
ISerializer<ConnectionInfo, XElement> connectionNodeSerializer)
{
_cryptographyProvider = cryptographyProvider;
_connectionNodeSerializer = connectionNodeSerializer;
}
public string Serialize(ConnectionTreeModel connectionTreeModel)
{
RootNodeInfo rootNode = (RootNodeInfo)connectionTreeModel.RootNodes.First(node => node is RootNodeInfo);

View File

@@ -15,16 +15,10 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.MiscSerializers
{
[SupportedOSPlatform("windows")]
public class ActiveDirectoryDeserializer
public class ActiveDirectoryDeserializer(string ldapPath, bool importSubOu)
{
private readonly string _ldapPath;
private readonly bool _importSubOu;
public ActiveDirectoryDeserializer(string ldapPath, bool importSubOu)
{
_ldapPath = ldapPath.ThrowIfNullOrEmpty(nameof(ldapPath));
_importSubOu = importSubOu;
}
private readonly string _ldapPath = ldapPath.ThrowIfNullOrEmpty(nameof(ldapPath));
private readonly bool _importSubOu = importSubOu;
public ConnectionTreeModel Deserialize()
{

View File

@@ -10,14 +10,9 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.MiscSerializers
{
[SupportedOSPlatform("windows")]
public class PortScanDeserializer : IDeserializer<IEnumerable<ScanHost>, ConnectionTreeModel>
public class PortScanDeserializer(ProtocolType targetProtocolType) : IDeserializer<IEnumerable<ScanHost>, ConnectionTreeModel>
{
private readonly ProtocolType _targetProtocolType;
public PortScanDeserializer(ProtocolType targetProtocolType)
{
_targetProtocolType = targetProtocolType;
}
private readonly ProtocolType _targetProtocolType = targetProtocolType;
public ConnectionTreeModel Deserialize(IEnumerable<ScanHost> scannedHosts)
{
@@ -66,6 +61,10 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
if (host.Vnc)
finalProtocol = ProtocolType.VNC;
break;
case ProtocolType.ARD:
if (host.Vnc)
finalProtocol = ProtocolType.ARD;
break;
default:
protocolValid = false;
break;

View File

@@ -20,8 +20,7 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
RootNodeInfo root = new(RootNodeType.Connection);
connectionTreeModel.AddRootNode(root);
XmlDocument xmlDocument = new();
xmlDocument.LoadXml(puttycmConnectionsXml);
XmlDocument xmlDocument = SecureXmlHelper.LoadXmlFromString(puttycmConnectionsXml);
XmlNode configurationNode = xmlDocument.SelectSingleNode("/configuration");
@@ -134,7 +133,8 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
XmlNode loginNode = xmlNode.SelectSingleNode("./login");
connectionInfo.Username = loginNode?.SelectSingleNode("login")?.InnerText;
connectionInfo.Password = loginNode?.SelectSingleNode("password")?.InnerText.ConvertToSecureString();
//connectionInfo.Password = loginNode?.SelectSingleNode("password")?.InnerText.ConvertToSecureString();
connectionInfo.Password = loginNode?.SelectSingleNode("password")?.InnerText;
// ./prompt
// ./timeout/connectiontimeout

View File

@@ -101,6 +101,9 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
case "allow desktop composition":
connectionInfo.EnableDesktopComposition = value == "1";
break;
case "keyboardhook":
connectionInfo.RedirectKeys = value == "1";
break;
case "redirectsmartcards":
connectionInfo.RedirectSmartCards = value == "1";
break;
@@ -156,6 +159,34 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
case "gatewayhostname":
connectionInfo.RDGatewayHostname = value;
break;
case "gatewaycredentialssource":
switch(value)
{
case "0":
connectionInfo.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.ExternalCredentialProvider;
break;
case "1":
connectionInfo.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.SmartCard;
break;
case "2":
connectionInfo.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.Yes;
break;
case "3":
// Both 3 and 4 require that the user enter gateway credentials manually
connectionInfo.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.No;
break;
case "4":
// Both 3 and 4 require that the user enter gateway credentials manually
connectionInfo.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.No;
break;
case "5":
connectionInfo.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.AccessToken;
break;
}
break;
case "gatewayaccesstoken":
connectionInfo.RDGatewayAccessToken = value;
break;
case "alternate shell":
connectionInfo.RDPStartProgram = value;
break;

View File

@@ -26,9 +26,7 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
ConnectionTreeModel connectionTreeModel = new();
RootNodeInfo root = new(RootNodeType.Connection);
XmlDocument xmlDocument = new();
xmlDocument.LoadXml(rdcmConnectionsXml);
XmlDocument xmlDocument = SecureXmlHelper.LoadXmlFromString(rdcmConnectionsXml);
XmlNode rdcManNode = xmlDocument.SelectSingleNode("/RDCMan");
VerifySchemaVersion(rdcManNode);
@@ -164,12 +162,15 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
if (_schemaVersion == 1) // Version 2.2 allows clear text passwords
{
connectionInfo.Password = passwordNode?.Attributes?["storeAsClearText"]?.Value == "True"
? passwordNode.InnerText.ConvertToSecureString()
: DecryptRdcManPassword(passwordNode?.InnerText).ConvertToSecureString();
//? passwordNode.InnerText.ConvertToSecureString()
//: DecryptRdcManPassword(passwordNode?.InnerText).ConvertToSecureString();
? passwordNode.InnerText
: DecryptRdcManPassword(passwordNode?.InnerText);
}
else
{
connectionInfo.Password = DecryptRdcManPassword(passwordNode?.InnerText).ConvertToSecureString();
//connectionInfo.Password = DecryptRdcManPassword(passwordNode?.InnerText).ConvertToSecureString();
connectionInfo.Password = DecryptRdcManPassword(passwordNode?.InnerText);
}
connectionInfo.Domain = logonCredentialsNode.SelectSingleNode("./domain")?.InnerText ?? string.Empty;

View File

@@ -2,6 +2,7 @@
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Container;
using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using System;
@@ -22,8 +23,7 @@ namespace mRemoteNG.Config.Serializers.MiscSerializers
RootNodeInfo root = new(RootNodeType.Connection);
connectionTreeModel.AddRootNode(root);
XmlDocument xmlDocument = new();
xmlDocument.LoadXml(content);
XmlDocument xmlDocument = SecureXmlHelper.LoadXmlFromString(content);
XmlNode sessionsNode = xmlDocument.SelectSingleNode("/VanDyke/key[@name=\"Sessions\"]");

View File

@@ -9,16 +9,11 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlDatabaseVersionVerifier
public class SqlDatabaseVersionVerifier(IDatabaseConnector databaseConnector)
{
private readonly Version _currentSupportedVersion = new(3, 0);
private readonly IDatabaseConnector _databaseConnector;
public SqlDatabaseVersionVerifier(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool VerifyDatabaseVersion(Version dbVersion)
{

View File

@@ -7,14 +7,9 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion22To23Upgrader : IVersionUpgrader
public class SqlVersion22To23Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion22To23Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -7,14 +7,9 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion23To24Upgrader : IVersionUpgrader
public class SqlVersion23To24Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion23To24Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -7,14 +7,9 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion24To25Upgrader : IVersionUpgrader
public class SqlVersion24To25Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion24To25Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -7,14 +7,9 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion25To26Upgrader : IVersionUpgrader
public class SqlVersion25To26Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion25To26Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -2,20 +2,15 @@
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Messages;
using System;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion26To27Upgrader : IVersionUpgrader
public class SqlVersion26To27Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion26To27Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -3,20 +3,15 @@ using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Messages;
using System;
using System.Data.Common;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion27To28Upgrader : IVersionUpgrader
public class SqlVersion27To28Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion27To28Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -8,15 +8,10 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion28To29Upgrader : IVersionUpgrader
public class SqlVersion28To29Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly Version _version = new(2, 9);
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion28To29Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -8,15 +8,10 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Config.Serializers.Versioning
{
[SupportedOSPlatform("windows")]
public class SqlVersion29To30Upgrader : IVersionUpgrader
public class SqlVersion29To30Upgrader(IDatabaseConnector databaseConnector) : IVersionUpgrader
{
private readonly Version _version = new(3, 0);
private readonly IDatabaseConnector _databaseConnector;
public SqlVersion29To30Upgrader(IDatabaseConnector databaseConnector)
{
_databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
}
private readonly IDatabaseConnector _databaseConnector = databaseConnector ?? throw new ArgumentNullException(nameof(databaseConnector));
public bool CanUpgrade(Version currentVersion)
{

View File

@@ -5,6 +5,7 @@ using mRemoteNG.UI.Forms;
using System.IO;
using System.Xml;
using mRemoteNG.Messages;
using mRemoteNG.Security;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
using System.Runtime.Versioning;
@@ -40,18 +41,18 @@ namespace mRemoteNG.Config.Settings
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), GeneralAppInfo.ProductName, SettingsFileInfo.ExtAppsFilesName);
#endif
string newPath = Path.Combine(SettingsFileInfo.SettingsPath, SettingsFileInfo.ExtAppsFilesName);
XmlDocument xDom = new();
XmlDocument xDom;
if (File.Exists(newPath))
{
_messageCollector.AddMessage(MessageClass.InformationMsg, $"Loading External Apps from: {newPath}",
true);
xDom.Load(newPath);
xDom = SecureXmlHelper.LoadXmlFromFile(newPath);
}
#if !PORTABLE
else if (File.Exists(oldPath))
{
_messageCollector.AddMessage(MessageClass.InformationMsg, $"Loading External Apps from: {oldPath}", true);
xDom.Load(oldPath);
xDom = SecureXmlHelper.LoadXmlFromFile(oldPath);
}
#endif

View File

@@ -2,12 +2,14 @@
using System.IO;
using System.Collections.Generic;
using System.Text.Json;
using System.Management;
using JsonSerializer = System.Text.Json.JsonSerializer;
using LiteDB;
using System.Linq;
using LiteDB;
using mRemoteNG.Config.MachineIdentifier;
using System.Runtime.Versioning;
public class LocalSettingsDBManager
[SupportedOSPlatform("windows")]
public class LocalDBManager
{
private readonly string _dbPath;
private readonly string _schemaPath;
@@ -21,12 +23,31 @@ public class LocalSettingsDBManager
/// <param name="dbPath">The path to the database file.</param>
/// <param name="useEncryption">Indicates whether to use encryption for the database. If null, no change is made to an existing database.</param>
/// <param name="schemaFilePath">Optional path to a schema file for creating the database structure.</param>
public LocalSettingsDBManager(string dbPath = null, bool? useEncryption = null, string schemaFilePath = null)
public LocalDBManager(string dbPath = null, bool? useEncryption = null, string schemaFilePath = null)
{
_dbPath = string.IsNullOrWhiteSpace(dbPath) ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mRemoteNG.appSettings") : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dbPath);
_schemaPath = string.IsNullOrWhiteSpace(schemaFilePath) ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Schemas\\mremoteng_default_settings_v1_0.json") : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, schemaFilePath);
_useEncryption = useEncryption;
_mRIdentifier = Convert.ToBase64String(System.Security.Cryptography.SHA256.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(GetDiskIdentifier() + "_" + Environment.MachineName)));
/// <summary>
/// Generate a unique identifier for the machine
/// </summary>
try
{
// Generate the machine identifier
_mRIdentifier = MachineIdentifierGenerator.GenerateMachineIdentifier();
Console.WriteLine($"Generated Identifier: {_mRIdentifier}");
}
catch (PlatformNotSupportedException ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
// Check if disk identifier is empty and prevent database creation if true
if (string.IsNullOrEmpty(_mRIdentifier))
@@ -53,6 +74,7 @@ public class LocalSettingsDBManager
}
}
/// <summary>
/// Ensures default settings are imported if the database is empty.
/// </summary>
@@ -111,6 +133,10 @@ public class LocalSettingsDBManager
{
if (!string.IsNullOrWhiteSpace(schemaFilePath) && File.Exists(schemaFilePath))
{
if (schemaFilePath == null || schemaFilePath.Contains("../") || schemaFilePath.Contains(@"..\"))
{
throw new ArgumentException("Invalid file path");
}
var schemaJson = File.ReadAllText(schemaFilePath);
using (JsonDocument doc = JsonDocument.Parse(schemaJson))
{
@@ -247,6 +273,10 @@ public void EncryptDatabase()
{
if (File.Exists(jsonFilePath))
{
if (jsonFilePath == null || jsonFilePath.Contains("../") || jsonFilePath.Contains(@"..\"))
{
throw new ArgumentException("Invalid file path");
}
var json = File.ReadAllText(jsonFilePath);
var settingsData = JsonSerializer.Deserialize<Dictionary<string, List<Setting>>>(json);
@@ -286,6 +316,10 @@ public void EncryptDatabase()
}
var json = JsonSerializer.Serialize(settingsData, new JsonSerializerOptions { WriteIndented = true });
if (jsonFilePath == null || jsonFilePath.Contains("../") || jsonFilePath.Contains(@"..\"))
{
throw new ArgumentException("Invalid file path");
}
File.WriteAllText(jsonFilePath, json);
Console.WriteLine("Settings successfully exported to JSON file.");
}
@@ -369,42 +403,6 @@ public void EncryptDatabase()
}
}
/// <summary>
/// Gets the unique machine identifier (serial number of the hard drive) combined with the machine name and encrypts it using SHA256.
/// </summary>
/// <returns>Unique machine identifier.</returns>
private static string GetDiskIdentifier()
{
if (OperatingSystem.IsWindows())
{
try
{
// Use ManagementObject to get the serial number of the hard drive
using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_DiskDrive"))
{
foreach (var disk in searcher.Get())
{
string sn = "" + disk["SerialNumber"]; // 2025-01-14 in .net8 this returns NULL in virtual machines
return sn.Trim();
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error getting disk identifier: {ex.Message}");
throw new InvalidOperationException("Failed to retrieve disk identifier. Please ensure the disk information is accessible.");
}
}
else
{
throw new PlatformNotSupportedException("This method is only supported on Windows.");
}
// Return an empty string if no serial number is found
return string.Empty;
}
// Setting class
public class Setting

View File

@@ -1,4 +1,4 @@
// The MIT License (MIT)
// The MIT License (MIT)
//
// Copyright(c) crdx
//
@@ -31,6 +31,7 @@ using System.Windows.Forms;
using System.Collections.Specialized;
using System.Xml;
using System.IO;
using mRemoteNG.Security;
//using mRemoteNG.App;
@@ -61,8 +62,7 @@ namespace mRemoteNG.Config.Settings.Providers
if (_xmlDocument != null) return _xmlDocument;
try
{
_xmlDocument = new XmlDocument();
_xmlDocument.Load(_filePath);
_xmlDocument = SecureXmlHelper.LoadXmlFromFile(_filePath);
}
catch (Exception /*ex*/)
{

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.Http;
using mRemoteNG.Connection.Protocol.RDP;
@@ -14,7 +15,7 @@ using System.Security;
namespace mRemoteNG.Connection
{
[SupportedOSPlatform("windows")]
public abstract class AbstractConnectionRecord : INotifyPropertyChanged
public abstract class AbstractConnectionRecord(string uniqueId) : INotifyPropertyChanged
{
#region Fields
@@ -22,6 +23,8 @@ namespace mRemoteNG.Connection
private string _description;
private string _icon;
private string _panel;
private string _color;
private string _tabColor;
private string _hostname;
private ExternalAddressProvider _externalAddressProvider;
@@ -30,14 +33,15 @@ namespace mRemoteNG.Connection
private ExternalCredentialProvider _externalCredentialProvider;
private string _userViaAPI = "";
private string _username = "";
private SecureString _password = null;
//private SecureString _password = null;
private string _password = null;
private string _domain = "";
private string _vmId = "";
private bool _useEnhancedMode;
private string _sshTunnelConnectionName = "";
private ProtocolType _protocol;
private RdpVersion _rdpProtocolVersion;
private RdpVersion _rdpProtocolVersion = RdpVersion.Rdc10;
private string _extApp;
private int _port;
private string _sshOptions = "";
@@ -152,6 +156,28 @@ namespace mRemoteNG.Connection
set => SetField(ref _panel, value, "Panel");
}
[LocalizedAttributes.LocalizedCategory(nameof(Language.Display)),
LocalizedAttributes.LocalizedDisplayName(nameof(Language.Color)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionColor)),
Editor(typeof(System.Drawing.Design.ColorEditor), typeof(System.Drawing.Design.UITypeEditor)),
TypeConverter(typeof(MiscTools.TabColorConverter))]
public virtual string Color
{
get => GetPropertyValue("Color", _color);
set => SetField(ref _color, value, "Color");
}
[LocalizedAttributes.LocalizedCategory(nameof(Language.Display)),
LocalizedAttributes.LocalizedDisplayName(nameof(Language.TabColor)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionTabColor)),
Editor(typeof(System.Drawing.Design.ColorEditor), typeof(System.Drawing.Design.UITypeEditor)),
TypeConverter(typeof(MiscTools.TabColorConverter))]
public virtual string TabColor
{
get => GetPropertyValue("TabColor", _tabColor);
set => SetField(ref _tabColor, value, "TabColor");
}
#endregion
#region Connection
@@ -202,7 +228,7 @@ namespace mRemoteNG.Connection
[LocalizedAttributes.LocalizedCategory(nameof(Language.Connection), 2),
LocalizedAttributes.LocalizedDisplayName(nameof(Language.Username)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionUsername)),
AttributeUsedInProtocol(ProtocolType.RDP, ProtocolType.SSH1, ProtocolType.SSH2)]
AttributeUsedInProtocol(ProtocolType.RDP, ProtocolType.SSH1, ProtocolType.SSH2, ProtocolType.HTTP, ProtocolType.HTTPS, ProtocolType.IntApp)]
public virtual string Username
{
get => GetPropertyValue("Username", _username);
@@ -214,7 +240,8 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionPassword)),
PasswordPropertyText(true),
AttributeUsedInAllProtocolsExcept(ProtocolType.Telnet, ProtocolType.Rlogin, ProtocolType.RAW)]
public virtual SecureString Password
//public virtual SecureString Password
public virtual string Password
{
get => GetPropertyValue("Password", _password);
set => SetField(ref _password, value, "Password");
@@ -827,7 +854,7 @@ namespace mRemoteNG.Connection
#region Misc
[Browsable(false)] public string ConstantID { get; }
[Browsable(false)] public string ConstantID { get; } = uniqueId.ThrowIfNullOrEmpty(nameof(uniqueId));
[LocalizedAttributes.LocalizedCategory(nameof(Language.Miscellaneous), 7),
LocalizedAttributes.LocalizedDisplayName(nameof(Language.ExternalToolBefore)),
@@ -906,7 +933,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.Compression)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionCompression)),
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public ProtocolVNC.Compression VNCCompression
{
@@ -918,7 +945,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.Encoding)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionEncoding)),
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public ProtocolVNC.Encoding VNCEncoding
{
@@ -930,7 +957,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.AuthenticationMode)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionAuthenticationMode)),
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public ProtocolVNC.AuthMode VNCAuthMode
{
@@ -942,7 +969,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.ProxyType)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionVNCProxyType)),
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public ProtocolVNC.ProxyType VNCProxyType
{
@@ -953,7 +980,7 @@ namespace mRemoteNG.Connection
[LocalizedAttributes.LocalizedCategory(nameof(Language.Proxy), 7),
LocalizedAttributes.LocalizedDisplayName(nameof(Language.ProxyAddress)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionVNCProxyAddress)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public string VNCProxyIP
{
@@ -964,7 +991,7 @@ namespace mRemoteNG.Connection
[LocalizedAttributes.LocalizedCategory(nameof(Language.Proxy), 7),
LocalizedAttributes.LocalizedDisplayName(nameof(Language.ProxyPort)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionVNCProxyPort)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public int VNCProxyPort
{
@@ -975,7 +1002,7 @@ namespace mRemoteNG.Connection
[LocalizedAttributes.LocalizedCategory(nameof(Language.Proxy), 7),
LocalizedAttributes.LocalizedDisplayName(nameof(Language.ProxyUsername)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionVNCProxyUsername)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public string VNCProxyUsername
{
@@ -987,7 +1014,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.ProxyPassword)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionVNCProxyPassword)),
PasswordPropertyText(true),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public string VNCProxyPassword
{
@@ -999,7 +1026,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.Colors)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionColors)),
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
AttributeUsedInProtocol(ProtocolType.VNC),
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD),
Browsable(false)]
public ProtocolVNC.Colors VNCColors
{
@@ -1011,7 +1038,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.SmartSizeMode)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionSmartSizeMode)),
TypeConverter(typeof(MiscTools.EnumTypeConverter)),
AttributeUsedInProtocol(ProtocolType.VNC)]
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD)]
public ProtocolVNC.SmartSizeMode VNCSmartSizeMode
{
get => GetPropertyValue("VNCSmartSizeMode", _vncSmartSizeMode);
@@ -1022,7 +1049,7 @@ namespace mRemoteNG.Connection
LocalizedAttributes.LocalizedDisplayName(nameof(Language.ViewOnly)),
LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionViewOnly)),
TypeConverter(typeof(MiscTools.YesNoTypeConverter)),
AttributeUsedInProtocol(ProtocolType.VNC)]
AttributeUsedInProtocol(ProtocolType.VNC, ProtocolType.ARD)]
public bool VNCViewOnly
{
get => GetPropertyValue("VNCViewOnly", _vncViewOnly);
@@ -1030,20 +1057,14 @@ namespace mRemoteNG.Connection
}
#endregion
#endregion
protected AbstractConnectionRecord(string uniqueId)
{
ConstantID = uniqueId.ThrowIfNullOrEmpty(nameof(uniqueId));
}
protected virtual TPropertyType GetPropertyValue<TPropertyType>(string propertyName, TPropertyType value)
{
return (TPropertyType)GetType().GetProperty(propertyName)?.GetValue(this, null);
}
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void RaisePropertyChangedEvent(object sender, PropertyChangedEventArgs args)
{

View File

@@ -12,22 +12,22 @@ namespace mRemoteNG.Connection
{
public static string[] Icons = { };
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context)
{
return new StandardValuesCollection(Icons);
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context)
{
return true;
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context)
{
return true;
}
public static System.Drawing.Icon FromString(string iconName)
public static System.Drawing.Icon? FromString(string iconName)
{
try
{
@@ -41,7 +41,7 @@ namespace mRemoteNG.Connection
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, $"Couldn\'t get Icon from String" + Environment.NewLine + ex.Message);
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, $"Couldn't get Icon from String" + Environment.NewLine + ex.Message);
}
return null;

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Reflection;
using mRemoteNG.App;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.ARD;
using mRemoteNG.Connection.Protocol.Http;
using mRemoteNG.Connection.Protocol.PowerShell;
using mRemoteNG.Connection.Protocol.RAW;
@@ -254,6 +255,8 @@ namespace mRemoteNG.Connection
return (int)RdpProtocol.Defaults.Port;
case ProtocolType.VNC:
return (int)ProtocolVNC.Defaults.Port;
case ProtocolType.ARD:
return (int)ProtocolARD.Defaults.Port;
case ProtocolType.SSH1:
return (int)ProtocolSSH1.Defaults.Port;
case ProtocolType.SSH2:
@@ -289,6 +292,8 @@ namespace mRemoteNG.Connection
Description = Settings.Default.ConDefaultDescription;
Icon = Settings.Default.ConDefaultIcon;
Panel = Language.General;
Color = string.Empty;
TabColor = string.Empty;
}
private void SetConnectionDefaults()

View File

@@ -6,18 +6,17 @@ using System.Runtime.Versioning;
namespace mRemoteNG.Connection
{
[SupportedOSPlatform("windows")]
public class ConnectionInfoComparer<TProperty> : IComparer<ConnectionInfo> where TProperty : IComparable<TProperty>
public class ConnectionInfoComparer<TProperty>(Func<ConnectionInfo, TProperty> sortExpression) : IComparer<ConnectionInfo> where TProperty : IComparable<TProperty>
{
private readonly Func<ConnectionInfo, TProperty> _sortExpression;
private readonly Func<ConnectionInfo, TProperty> _sortExpression = sortExpression;
public ListSortDirection SortDirection { get; set; } = ListSortDirection.Ascending;
public ConnectionInfoComparer(Func<ConnectionInfo, TProperty> sortExpression)
public int Compare(ConnectionInfo? x, ConnectionInfo? y)
{
_sortExpression = sortExpression;
}
if (x == null && y == null) return 0;
if (x == null) return SortDirection == ListSortDirection.Ascending ? -1 : 1;
if (y == null) return SortDirection == ListSortDirection.Ascending ? 1 : -1;
public int Compare(ConnectionInfo x, ConnectionInfo y)
{
return SortDirection == ListSortDirection.Ascending ? CompareAscending(x, y) : CompareDescending(x, y);
}

View File

@@ -50,6 +50,18 @@ namespace mRemoteNG.Connection
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
public bool Panel { get; set; }
[LocalizedAttributes.LocalizedCategory(nameof(Language.Display), 2),
LocalizedAttributes.LocalizedDisplayNameInherit(nameof(Language.Color)),
LocalizedAttributes.LocalizedDescriptionInherit(nameof(Language.PropertyDescriptionColor)),
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
public bool Color { get; set; }
[LocalizedAttributes.LocalizedCategory(nameof(Language.Display), 2),
LocalizedAttributes.LocalizedDisplayNameInherit(nameof(Language.TabColor)),
LocalizedAttributes.LocalizedDescriptionInherit(nameof(Language.PropertyDescriptionTabColor)),
TypeConverter(typeof(MiscTools.YesNoTypeConverter))]
public bool TabColor { get; set; }
#endregion
#region Connection

View File

@@ -406,21 +406,16 @@ namespace mRemoteNG.Connection
try
{
ProtocolBase prot = (ProtocolBase)sender;
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.ConnenctionCloseEvent,
true);
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.ConnenctionCloseEvent, true);
string connDetail;
if (prot.InterfaceControl.OriginalInfo.Hostname == "" &&
prot.InterfaceControl.Info.Protocol == ProtocolType.IntApp)
if (prot.InterfaceControl.OriginalInfo.Hostname == "" && prot.InterfaceControl.Info.Protocol == ProtocolType.IntApp)
connDetail = prot.InterfaceControl.Info.ExtApp;
else if (prot.InterfaceControl.OriginalInfo.Hostname != "")
connDetail = prot.InterfaceControl.OriginalInfo.Hostname;
else
connDetail = "UNKNOWN";
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg,
string.Format(Language.ConnenctionClosedByUser, connDetail,
prot.InterfaceControl.Info.Protocol,
Environment.UserName));
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.ConnenctionClosedByUser, connDetail, prot.InterfaceControl.Info.Protocol, Environment.UserName));
prot.InterfaceControl.OriginalInfo.OpenConnections.Remove(prot);
if (_activeConnections.Contains(prot.InterfaceControl.Info.ConstantID))
_activeConnections.Remove(prot.InterfaceControl.Info.ConstantID);

View File

@@ -23,12 +23,12 @@ using mRemoteNG.Config.Serializers.ConnectionSerializers.Sql;
namespace mRemoteNG.Connection
{
[SupportedOSPlatform("windows")]
public class ConnectionsService
public class ConnectionsService(PuttySessionsManager puttySessionsManager)
{
private static readonly object SaveLock = new();
private readonly PuttySessionsManager _puttySessionsManager;
private readonly IDataProvider<string> _localConnectionPropertiesDataProvider;
private readonly LocalConnectionPropertiesXmlSerializer _localConnectionPropertiesSerializer;
private readonly PuttySessionsManager _puttySessionsManager = puttySessionsManager ?? throw new ArgumentNullException(nameof(puttySessionsManager));
private readonly IDataProvider<string> _localConnectionPropertiesDataProvider = new FileDataProvider(Path.Combine(SettingsFileInfo.SettingsPath, SettingsFileInfo.LocalConnectionProperties));
private readonly LocalConnectionPropertiesXmlSerializer _localConnectionPropertiesSerializer = new LocalConnectionPropertiesXmlSerializer();
private bool _batchingSaves = false;
private bool _saveRequested = false;
private bool _saveAsyncRequested = false;
@@ -42,13 +42,6 @@ namespace mRemoteNG.Connection
public ConnectionTreeModel ConnectionTreeModel { get; private set; }
public ConnectionsService(PuttySessionsManager puttySessionsManager)
{
_puttySessionsManager = puttySessionsManager ?? throw new ArgumentNullException(nameof(puttySessionsManager));
_localConnectionPropertiesDataProvider = new FileDataProvider(Path.Combine(SettingsFileInfo.SettingsPath, SettingsFileInfo.LocalConnectionProperties));
_localConnectionPropertiesSerializer = new LocalConnectionPropertiesXmlSerializer();
}
public void NewConnectionsFile(string filename)
{
try

View File

@@ -1,4 +1,4 @@
namespace mRemoteNG.Connection
namespace mRemoteNG.Connection
{
public sealed partial class InterfaceControl : System.Windows.Forms.Panel
{
@@ -21,14 +21,11 @@ namespace mRemoteNG.Connection
//Required by the Windows Form Designer
private System.ComponentModel.Container components = null;
//NOTE: The following procedure is required by the Windows Form Designer
//It can be modified using the Windows Form Designer.
//Do not modify it using the code editor.
[System.Diagnostics.DebuggerStepThrough()]
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
}
//NOTE: The following procedure is required by the Windows Form Designer
//It can be modified using the Windows Form Designer.
//Do not modify it using the code editor.
[System.Diagnostics.DebuggerStepThrough()]
private void InitializeComponent() => components = new System.ComponentModel.Container();
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Runtime.Versioning;
using mRemoteNG.Connection.Protocol.VNC;
namespace mRemoteNG.Connection.Protocol.ARD
{
[SupportedOSPlatform("windows")]
public class ProtocolARD : ProtocolVNC
{
public ProtocolARD()
{
}
public new enum Defaults
{
Port = 5900
}
}
}

View File

@@ -5,6 +5,7 @@ using mRemoteNG.Connection.Protocol.Rlogin;
using mRemoteNG.Connection.Protocol.SSH;
using mRemoteNG.Connection.Protocol.Telnet;
using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNG.Connection.Protocol.ARD;
using System;
using mRemoteNG.Connection.Protocol.PowerShell;
using mRemoteNG.Resources.Language;
@@ -28,6 +29,8 @@ namespace mRemoteNG.Connection.Protocol
return rdp;
case ProtocolType.VNC:
return new ProtocolVNC();
case ProtocolType.ARD:
return new ProtocolARD();
case ProtocolType.SSH1:
return new ProtocolSSH1();
case ProtocolType.SSH2:

View File

@@ -1,11 +1,13 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Runtime.Versioning;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Connection.Protocol
{
[SupportedOSPlatform("windows")]
public class ProtocolList : CollectionBase, INotifyCollectionChanged
{
public ProtocolBase this[object index]
@@ -23,7 +25,6 @@ namespace mRemoteNG.Connection.Protocol
public new int Count => List.Count;
public void Add(ProtocolBase cProt)
{
List.Add(cProt);
@@ -64,7 +65,7 @@ namespace mRemoteNG.Connection.Protocol
RaiseCollectionChangedEvent(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
public event NotifyCollectionChangedEventHandler? CollectionChanged; // Fix for CS8612: Declare the event as nullable to match the interface.
private void RaiseCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs args)
{

View File

@@ -35,6 +35,9 @@ namespace mRemoteNG.Connection.Protocol
[LocalizedAttributes.LocalizedDescription(nameof(Language.PowerShell))]
PowerShell = 10,
[LocalizedAttributes.LocalizedDescription(nameof(Language.Ard))]
ARD = 11,
[LocalizedAttributes.LocalizedDescription(nameof(Language.ExternalTool))]
IntApp = 20
}

Some files were not shown because too many files have changed in this diff Show More