├── .gitignore ├── LICENSE ├── LockChecker ├── LockCheck.vb ├── LockChecker.vbproj └── My Project │ ├── Application.Designer.vb │ ├── Application.myapp │ ├── AssemblyInfo.vb │ ├── Resources.Designer.vb │ ├── Resources.resx │ ├── Settings.Designer.vb │ └── Settings.settings ├── RDP2MSI ├── .gitignore ├── App.config ├── My Project │ ├── Application.Designer.vb │ ├── Application.myapp │ ├── AssemblyInfo.vb │ ├── Resources.Designer.vb │ ├── Resources.resx │ ├── Settings.Designer.vb │ ├── Settings.settings │ └── app.manifest ├── RDP2MSI.vb └── RDP2MSI.vbproj ├── RDP2MSILib ├── .gitignore ├── My Project │ ├── Application.Designer.vb │ ├── Application.myapp │ ├── AssemblyInfo.vb │ ├── Resources.Designer.vb │ ├── Resources.resx │ ├── Settings.Designer.vb │ └── Settings.settings ├── RDP2MSILib.vb └── RDP2MSILib.vbproj ├── RDPFileLib ├── .gitignore ├── My Project │ ├── Application.Designer.vb │ ├── Application.myapp │ ├── AssemblyInfo.vb │ ├── Resources.Designer.vb │ ├── Resources.resx │ ├── Settings.Designer.vb │ └── Settings.settings ├── RDPFileLib.bak.vbproj ├── RDPFileLib.vb ├── RDPFileLib.vbproj └── app.config ├── RDPSign ├── My Project │ ├── Application.Designer.vb │ ├── Application.myapp │ ├── AssemblyInfo.vb │ ├── Resources.Designer.vb │ ├── Resources.resx │ ├── Settings.Designer.vb │ └── Settings.settings ├── RDPSign.vb └── RDPSign.vbproj ├── README.md ├── remoteapp-tool ├── .gitignore ├── App.config ├── ApplicationEvents.vb ├── HelpSystem.vb ├── IconLib.dll ├── IconModule.vb ├── LocalFtaModule.vb ├── My Project │ ├── Application.Designer.vb │ ├── Application.myapp │ ├── AssemblyInfo.vb │ ├── Resources.Designer.vb │ ├── Resources.resx │ ├── Settings.Designer.vb │ ├── Settings.settings │ └── app.manifest ├── RDP2MSImodule.vb ├── RDPOptionsWindow.Designer.vb ├── RDPOptionsWindow.resx ├── RDPOptionsWindow.vb ├── RemoteApp Tool.sln ├── RemoteApp Tool.vbproj ├── RemoteApp Tool_TemporaryKey.pfx ├── RemoteAppAboutWindow.Designer.vb ├── RemoteAppAboutWindow.resx ├── RemoteAppAboutWindow.vb ├── RemoteAppCreateClientConnection.Designer.vb ├── RemoteAppCreateClientConnection.resx ├── RemoteAppCreateClientConnection.vb ├── RemoteAppEditWindow.Designer.vb ├── RemoteAppEditWindow.resx ├── RemoteAppEditWindow.vb ├── RemoteAppFileTypeAssociation.Designer.vb ├── RemoteAppFileTypeAssociation.resx ├── RemoteAppFileTypeAssociation.vb ├── RemoteAppFunctions.vb ├── RemoteAppHostOptions.Designer.vb ├── RemoteAppHostOptions.resx ├── RemoteAppHostOptions.vb ├── RemoteAppIconPicker.Designer.vb ├── RemoteAppIconPicker.resx ├── RemoteAppIconPicker.vb ├── RemoteAppMainWindow.Designer.vb ├── RemoteAppMainWindow.resx ├── RemoteAppMainWindow.vb ├── add-window.ico └── app.manifest └── remoteapplib ├── .gitignore ├── App.config ├── My Project └── AssemblyInfo.vb ├── RemoteAppLib.vb └── RemoteAppLib.vbproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | 33 | # Visual Studio 2015/2017 cache/options directory 34 | .vs/ 35 | # Uncomment if you have tasks that create the project's static files in wwwroot 36 | #wwwroot/ 37 | 38 | # Visual Studio 2017 auto generated files 39 | Generated\ Files/ 40 | 41 | # MSTest test Results 42 | [Tt]est[Rr]esult*/ 43 | [Bb]uild[Ll]og.* 44 | 45 | # NUNIT 46 | *.VisualState.xml 47 | TestResult.xml 48 | 49 | # Build Results of an ATL Project 50 | [Dd]ebugPS/ 51 | [Rr]eleasePS/ 52 | dlldata.c 53 | 54 | # Benchmark Results 55 | BenchmarkDotNet.Artifacts/ 56 | 57 | # .NET Core 58 | project.lock.json 59 | project.fragment.lock.json 60 | artifacts/ 61 | 62 | # StyleCop 63 | StyleCopReport.xml 64 | 65 | # Files built by Visual Studio 66 | *_i.c 67 | *_p.c 68 | *_h.h 69 | *.ilk 70 | *.meta 71 | *.obj 72 | *.iobj 73 | *.pch 74 | *.pdb 75 | *.ipdb 76 | *.pgc 77 | *.pgd 78 | *.rsp 79 | *.sbr 80 | *.tlb 81 | *.tli 82 | *.tlh 83 | *.tmp 84 | *.tmp_proj 85 | *_wpftmp.csproj 86 | *.log 87 | *.vspscc 88 | *.vssscc 89 | .builds 90 | *.pidb 91 | *.svclog 92 | *.scc 93 | 94 | # Chutzpah Test files 95 | _Chutzpah* 96 | 97 | # Visual C++ cache files 98 | ipch/ 99 | *.aps 100 | *.ncb 101 | *.opendb 102 | *.opensdf 103 | *.sdf 104 | *.cachefile 105 | *.VC.db 106 | *.VC.VC.opendb 107 | 108 | # Visual Studio profiler 109 | *.psess 110 | *.vsp 111 | *.vspx 112 | *.sap 113 | 114 | # Visual Studio Trace Files 115 | *.e2e 116 | 117 | # TFS 2012 Local Workspace 118 | $tf/ 119 | 120 | # Guidance Automation Toolkit 121 | *.gpState 122 | 123 | # ReSharper is a .NET coding add-in 124 | _ReSharper*/ 125 | *.[Rr]e[Ss]harper 126 | *.DotSettings.user 127 | 128 | # JustCode is a .NET coding add-in 129 | .JustCode 130 | 131 | # TeamCity is a build add-in 132 | _TeamCity* 133 | 134 | # DotCover is a Code Coverage Tool 135 | *.dotCover 136 | 137 | # AxoCover is a Code Coverage Tool 138 | .axoCover/* 139 | !.axoCover/settings.json 140 | 141 | # Visual Studio code coverage results 142 | *.coverage 143 | *.coveragexml 144 | 145 | # NCrunch 146 | _NCrunch_* 147 | .*crunch*.local.xml 148 | nCrunchTemp_* 149 | 150 | # MightyMoose 151 | *.mm.* 152 | AutoTest.Net/ 153 | 154 | # Web workbench (sass) 155 | .sass-cache/ 156 | 157 | # Installshield output folder 158 | [Ee]xpress/ 159 | 160 | # DocProject is a documentation generator add-in 161 | DocProject/buildhelp/ 162 | DocProject/Help/*.HxT 163 | DocProject/Help/*.HxC 164 | DocProject/Help/*.hhc 165 | DocProject/Help/*.hhk 166 | DocProject/Help/*.hhp 167 | DocProject/Help/Html2 168 | DocProject/Help/html 169 | 170 | # Click-Once directory 171 | publish/ 172 | 173 | # Publish Web Output 174 | *.[Pp]ublish.xml 175 | *.azurePubxml 176 | # Note: Comment the next line if you want to checkin your web deploy settings, 177 | # but database connection strings (with potential passwords) will be unencrypted 178 | *.pubxml 179 | *.publishproj 180 | 181 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 182 | # checkin your Azure Web App publish settings, but sensitive information contained 183 | # in these scripts will be unencrypted 184 | PublishScripts/ 185 | 186 | # NuGet Packages 187 | *.nupkg 188 | # The packages folder can be ignored because of Package Restore 189 | **/[Pp]ackages/* 190 | # except build/, which is used as an MSBuild target. 191 | !**/[Pp]ackages/build/ 192 | # Uncomment if necessary however generally it will be regenerated when needed 193 | #!**/[Pp]ackages/repositories.config 194 | # NuGet v3's project.json files produces more ignorable files 195 | *.nuget.props 196 | *.nuget.targets 197 | 198 | # Microsoft Azure Build Output 199 | csx/ 200 | *.build.csdef 201 | 202 | # Microsoft Azure Emulator 203 | ecf/ 204 | rcf/ 205 | 206 | # Windows Store app package directories and files 207 | AppPackages/ 208 | BundleArtifacts/ 209 | Package.StoreAssociation.xml 210 | _pkginfo.txt 211 | *.appx 212 | *.appxbundle 213 | *.appxupload 214 | 215 | # Visual Studio cache files 216 | # files ending in .cache can be ignored 217 | *.[Cc]ache 218 | # but keep track of directories ending in .cache 219 | !?*.[Cc]ache/ 220 | 221 | # Others 222 | ClientBin/ 223 | ~$* 224 | *~ 225 | *.dbmdl 226 | *.dbproj.schemaview 227 | *.jfm 228 | *.pfx 229 | *.publishsettings 230 | orleans.codegen.cs 231 | 232 | # Including strong name files can present a security risk 233 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 234 | #*.snk 235 | 236 | # Since there are multiple workflows, uncomment next line to ignore bower_components 237 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 238 | #bower_components/ 239 | 240 | # RIA/Silverlight projects 241 | Generated_Code/ 242 | 243 | # Backup & report files from converting an old project file 244 | # to a newer Visual Studio version. Backup files are not needed, 245 | # because we have git ;-) 246 | _UpgradeReport_Files/ 247 | Backup*/ 248 | UpgradeLog*.XML 249 | UpgradeLog*.htm 250 | ServiceFabricBackup/ 251 | *.rptproj.bak 252 | 253 | # SQL Server files 254 | *.mdf 255 | *.ldf 256 | *.ndf 257 | 258 | # Business Intelligence projects 259 | *.rdl.data 260 | *.bim.layout 261 | *.bim_*.settings 262 | *.rptproj.rsuser 263 | *- Backup*.rdl 264 | 265 | # Microsoft Fakes 266 | FakesAssemblies/ 267 | 268 | # GhostDoc plugin setting file 269 | *.GhostDoc.xml 270 | 271 | # Node.js Tools for Visual Studio 272 | .ntvs_analysis.dat 273 | node_modules/ 274 | 275 | # Visual Studio 6 build log 276 | *.plg 277 | 278 | # Visual Studio 6 workspace options file 279 | *.opt 280 | 281 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 282 | *.vbw 283 | 284 | # Visual Studio LightSwitch build output 285 | **/*.HTMLClient/GeneratedArtifacts 286 | **/*.DesktopClient/GeneratedArtifacts 287 | **/*.DesktopClient/ModelManifest.xml 288 | **/*.Server/GeneratedArtifacts 289 | **/*.Server/ModelManifest.xml 290 | _Pvt_Extensions 291 | 292 | # Paket dependency manager 293 | .paket/paket.exe 294 | paket-files/ 295 | 296 | # FAKE - F# Make 297 | .fake/ 298 | 299 | # CodeRush personal settings 300 | .cr/personal 301 | 302 | # Python Tools for Visual Studio (PTVS) 303 | __pycache__/ 304 | *.pyc 305 | 306 | # Cake - Uncomment if you are using it 307 | # tools/** 308 | # !tools/packages.config 309 | 310 | # Tabs Studio 311 | *.tss 312 | 313 | # Telerik's JustMock configuration file 314 | *.jmconfig 315 | 316 | # BizTalk build output 317 | *.btp.cs 318 | *.btm.cs 319 | *.odx.cs 320 | *.xsd.cs 321 | 322 | # OpenCover UI analysis results 323 | OpenCover/ 324 | 325 | # Azure Stream Analytics local run output 326 | ASALocalRun/ 327 | 328 | # MSBuild Binary and Structured Log 329 | *.binlog 330 | 331 | # NVidia Nsight GPU debugger configuration file 332 | *.nvuser 333 | 334 | # MFractors (Xamarin productivity tool) working folder 335 | .mfractor/ 336 | 337 | # Local History for Visual Studio 338 | .localhistory/ 339 | 340 | # BeatPulse healthcheck temp database 341 | healthchecksdb 342 | 343 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 344 | MigrationBackup/ 345 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | IconLib (remoteapp-tool/iconlib.dll) is copyright (c) 2009 Castor Tiu. 2 | It is licenced under a Creative Commons Attribution-Share Alike 3.0 Unported License. 3 | Licence: https://creativecommons.org/licenses/by-sa/3.0/ 4 | Website: https://www.codeproject.com/Articles/16178/IconLib-Icons-Unfolded-MultiIcon-and-Windows-Vista 5 | 6 | The remainder of the "remoteapptool" project is licenced as follows: 7 | 8 | MIT License 9 | 10 | Copyright (c) 2019 kimmknight 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in all 20 | copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | SOFTWARE. 29 | -------------------------------------------------------------------------------- /LockChecker/LockChecker.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {029C010D-728B-4B87-B54A-08B2BBF49BD7} 8 | Library 9 | LockChecker 10 | LockChecker 11 | 512 12 | Windows 13 | v4.0 14 | true 15 | 16 | 17 | true 18 | full 19 | true 20 | true 21 | bin\Debug\ 22 | LockChecker.xml 23 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 24 | 25 | 26 | pdbonly 27 | false 28 | true 29 | true 30 | bin\Release\ 31 | LockChecker.xml 32 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 33 | 34 | 35 | On 36 | 37 | 38 | Binary 39 | 40 | 41 | Off 42 | 43 | 44 | On 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | True 69 | Application.myapp 70 | 71 | 72 | True 73 | True 74 | Resources.resx 75 | 76 | 77 | True 78 | Settings.settings 79 | True 80 | 81 | 82 | 83 | 84 | VbMyResourcesResXFileCodeGenerator 85 | Resources.Designer.vb 86 | My.Resources 87 | Designer 88 | 89 | 90 | 91 | 92 | MyApplicationCodeGenerator 93 | Application.Designer.vb 94 | 95 | 96 | SettingsSingleFileGenerator 97 | My 98 | Settings.Designer.vb 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /LockChecker/My Project/Application.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | -------------------------------------------------------------------------------- /LockChecker/My Project/Application.myapp: -------------------------------------------------------------------------------- 1 |  2 | 3 | false 4 | false 5 | 0 6 | true 7 | 0 8 | 1 9 | true 10 | 11 | -------------------------------------------------------------------------------- /LockChecker/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | ' 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /LockChecker/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My.Resources 16 | 17 | 'This class was auto-generated by the StronglyTypedResourceBuilder 18 | 'class via a tool like ResGen or Visual Studio. 19 | 'To add or remove a member, edit your .ResX file then rerun ResGen 20 | 'with the /str option, or rebuild your VS project. 21 | ''' 22 | ''' A strongly-typed resource class, for looking up localized strings, etc. 23 | ''' 24 | _ 28 | Friend Module Resources 29 | 30 | Private resourceMan As Global.System.Resources.ResourceManager 31 | 32 | Private resourceCulture As Global.System.Globalization.CultureInfo 33 | 34 | ''' 35 | ''' Returns the cached ResourceManager instance used by this class. 36 | ''' 37 | _ 38 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 39 | Get 40 | If Object.ReferenceEquals(resourceMan, Nothing) Then 41 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("LockChecker.Resources", GetType(Resources).Assembly) 42 | resourceMan = temp 43 | End If 44 | Return resourceMan 45 | End Get 46 | End Property 47 | 48 | ''' 49 | ''' Overrides the current thread's CurrentUICulture property for all 50 | ''' resource lookups using this strongly typed resource class. 51 | ''' 52 | _ 53 | Friend Property Culture() As Global.System.Globalization.CultureInfo 54 | Get 55 | Return resourceCulture 56 | End Get 57 | Set(ByVal value As Global.System.Globalization.CultureInfo) 58 | resourceCulture = value 59 | End Set 60 | End Property 61 | End Module 62 | End Namespace 63 | -------------------------------------------------------------------------------- /LockChecker/My Project/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /LockChecker/My Project/Settings.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My 16 | 17 | _ 20 | Partial Friend NotInheritable Class MySettings 21 | Inherits Global.System.Configuration.ApplicationSettingsBase 22 | 23 | Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) 24 | 25 | #Region "My.Settings Auto-Save Functionality" 26 | #If _MyType = "WindowsForms" Then 27 | Private Shared addedHandler As Boolean 28 | 29 | Private Shared addedHandlerLockObject As New Object 30 | 31 | _ 32 | Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) 33 | If My.Application.SaveMySettingsOnExit Then 34 | My.Settings.Save() 35 | End If 36 | End Sub 37 | #End If 38 | #End Region 39 | 40 | Public Shared ReadOnly Property [Default]() As MySettings 41 | Get 42 | 43 | #If _MyType = "WindowsForms" Then 44 | If Not addedHandler Then 45 | SyncLock addedHandlerLockObject 46 | If Not addedHandler Then 47 | AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings 48 | addedHandler = True 49 | End If 50 | End SyncLock 51 | End If 52 | #End If 53 | Return defaultInstance 54 | End Get 55 | End Property 56 | End Class 57 | End Namespace 58 | 59 | Namespace My 60 | 61 | _ 64 | Friend Module MySettingsProperty 65 | 66 | _ 67 | Friend ReadOnly Property Settings() As Global.LockChecker.My.MySettings 68 | Get 69 | Return Global.LockChecker.My.MySettings.Default 70 | End Get 71 | End Property 72 | End Module 73 | End Namespace 74 | -------------------------------------------------------------------------------- /LockChecker/My Project/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RDP2MSI/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | -------------------------------------------------------------------------------- /RDP2MSI/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/Application.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/Application.myapp: -------------------------------------------------------------------------------- 1 |  2 | 3 | false 4 | false 5 | 0 6 | true 7 | 0 8 | 2 9 | true 10 | 11 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | ' 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | Imports System 15 | 16 | Namespace My.Resources 17 | 18 | 'This class was auto-generated by the StronglyTypedResourceBuilder 19 | 'class via a tool like ResGen or Visual Studio. 20 | 'To add or remove a member, edit your .ResX file then rerun ResGen 21 | 'with the /str option, or rebuild your VS project. 22 | ''' 23 | ''' A strongly-typed resource class, for looking up localized strings, etc. 24 | ''' 25 | _ 29 | Friend Module Resources 30 | 31 | Private resourceMan As Global.System.Resources.ResourceManager 32 | 33 | Private resourceCulture As Global.System.Globalization.CultureInfo 34 | 35 | ''' 36 | ''' Returns the cached ResourceManager instance used by this class. 37 | ''' 38 | _ 39 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 40 | Get 41 | If Object.ReferenceEquals(resourceMan, Nothing) Then 42 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RDP2MSI.Resources", GetType(Resources).Assembly) 43 | resourceMan = temp 44 | End If 45 | Return resourceMan 46 | End Get 47 | End Property 48 | 49 | ''' 50 | ''' Overrides the current thread's CurrentUICulture property for all 51 | ''' resource lookups using this strongly typed resource class. 52 | ''' 53 | _ 54 | Friend Property Culture() As Global.System.Globalization.CultureInfo 55 | Get 56 | Return resourceCulture 57 | End Get 58 | Set 59 | resourceCulture = value 60 | End Set 61 | End Property 62 | End Module 63 | End Namespace 64 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/Settings.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My 16 | 17 | _ 20 | Partial Friend NotInheritable Class MySettings 21 | Inherits Global.System.Configuration.ApplicationSettingsBase 22 | 23 | Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) 24 | 25 | #Region "My.Settings Auto-Save Functionality" 26 | #If _MyType = "WindowsForms" Then 27 | Private Shared addedHandler As Boolean 28 | 29 | Private Shared addedHandlerLockObject As New Object 30 | 31 | _ 32 | Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) 33 | If My.Application.SaveMySettingsOnExit Then 34 | My.Settings.Save() 35 | End If 36 | End Sub 37 | #End If 38 | #End Region 39 | 40 | Public Shared ReadOnly Property [Default]() As MySettings 41 | Get 42 | 43 | #If _MyType = "WindowsForms" Then 44 | If Not addedHandler Then 45 | SyncLock addedHandlerLockObject 46 | If Not addedHandler Then 47 | AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings 48 | addedHandler = True 49 | End If 50 | End SyncLock 51 | End If 52 | #End If 53 | Return defaultInstance 54 | End Get 55 | End Property 56 | End Class 57 | End Namespace 58 | 59 | Namespace My 60 | 61 | _ 64 | Friend Module MySettingsProperty 65 | 66 | _ 67 | Friend ReadOnly Property Settings() As Global.RDP2MSI.My.MySettings 68 | Get 69 | Return Global.RDP2MSI.My.MySettings.Default 70 | End Get 71 | End Property 72 | End Module 73 | End Namespace 74 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RDP2MSI/My Project/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /RDP2MSI/RDP2MSI.vb: -------------------------------------------------------------------------------- 1 | Module RDP2MSI 2 | 3 | Sub Main() 4 | Dim cmdRdpPath = "" 5 | Dim cmdSwitches = "" 6 | 7 | LogText("RDP2MSI" & vbCrLf) 8 | If My.Application.CommandLineArgs.Count = 0 Then 9 | ShowUsage() 10 | End 11 | ElseIf My.Application.CommandLineArgs.Count = 1 Then 12 | cmdRdpPath = My.Application.CommandLineArgs(0) 13 | ElseIf My.Application.CommandLineArgs.Count = 2 Then 14 | If My.Application.CommandLineArgs(0).StartsWith("/") Then 15 | cmdSwitches = My.Application.CommandLineArgs(0) 16 | cmdRdpPath = My.Application.CommandLineArgs(1) 17 | Else 18 | cmdSwitches = My.Application.CommandLineArgs(1) 19 | cmdRdpPath = My.Application.CommandLineArgs(0) 20 | End If 21 | ElseIf My.Application.CommandLineArgs.Count > 2 Then 22 | LogText("Error: Too many parameters provided.", True) 23 | End If 24 | 25 | Dim relCmdRdpPath = System.IO.Directory.GetCurrentDirectory & "\" & cmdRdpPath 26 | If Not cmdRdpPath.Contains(":") Then cmdRdpPath = relCmdRdpPath 27 | 28 | If Not My.Computer.FileSystem.FileExists(cmdRdpPath) Then LogText("Error: Unable to find RDP file: " & cmdRdpPath, True) 29 | 30 | If Not cmdSwitches.ToUpper.Contains("D") Then 31 | If Not cmdSwitches.ToUpper.Contains("S") Then 32 | cmdSwitches += "DS" 33 | End If 34 | End If 35 | 36 | 37 | PrepareRDP2MSI(cmdRdpPath, cmdSwitches.ToUpper) 38 | End Sub 39 | 40 | Sub ShowUsage() 41 | LogText("Usage: rdp2msi.exe [/DSNATU] rdpfile.rdp") 42 | LogText("") 43 | LogText("Switches:") 44 | LogText("") 45 | LogText(" /D MSI will deploy desktop shortcut.") 46 | LogText(" /S MSI will deploy shortcut in Start Menu > Programs > (AppName)") 47 | LogText(" /N Requires /S. MSI will not create subfolder in Start Menu > Programs.") 48 | LogText(" /A Generate upgrade code based on app name. By default, it is random.") 49 | LogText(" /T Do not include the (remote) tag on deployed shortcuts.") 50 | LogText(" /U MSI installs per-user. By default, MSI will install per-machine.") 51 | LogText("") 52 | LogText("If no switches are specified, /DS is implied.") 53 | LogText("") 54 | LogText("If an ICO file with the same name as the RDP file exists, it will be used.") 55 | LogText("") 56 | End Sub 57 | 58 | Private Sub PrepareRDP2MSI(rdpFilePath As String, Optional cmdSwitches As String = "DS") 59 | If Not My.Computer.FileSystem.FileExists(rdpFilePath) Then LogText("Error: Unable to find RDP file: " & rdpFilePath, True) 60 | If Not rdpFilePath.ToLower.EndsWith(".rdp") Then LogText("Error: Input file must be an RDP file.", True) 61 | 62 | Dim RDP As New RDP2MSIlib.RDP 63 | RDP.rdpPath = rdpFilePath 64 | 65 | If Not RDP.WixInstalled Then LogText("Error: WiX Toolset not found. If you have just installed it, please reboot and try again.", True) 66 | 67 | LogText("RDP file: " & rdpFilePath) 68 | Dim RemoteAppFullName = RDP.ReadRDPProperty("remoteapplicationname") 69 | Dim RDPFullAddress = RDP.ReadRDPProperty("full address") 70 | If RDPFullAddress = "" Then LogText("Error: RDP file does not contain a Remote Desktop Server address.", True) 71 | If RemoteAppFullName = "" Then 72 | 'Full desktop connection 73 | LogText("RDP file type: Full desktop session") 74 | Else 75 | 'RemoteApp connection 76 | LogText("RDP file type: RemoteApp") 77 | LogText("App full name: " & RemoteAppFullName) 78 | End If 79 | LogText("Command line switches: " & cmdSwitches.ToUpper) 80 | 81 | 82 | RDP.ShortcutInStart = cmdSwitches.Contains("S") 83 | RDP.ShortcutOnDesktop = cmdSwitches.Contains("D") 84 | RDP.ShortcutSubfolderInStart = Not cmdSwitches.Contains("N") 85 | Dim ShortcutLocations As New List(Of String) 86 | If RDP.ShortcutInStart Then 87 | If RDP.ShortcutSubfolderInStart Then 88 | ShortcutLocations.Add("Start menu (subfolder)") 89 | Else 90 | ShortcutLocations.Add("Start menu (top level)") 91 | End If 92 | End If 93 | If RDP.ShortcutOnDesktop Then ShortcutLocations.Add("Desktop") 94 | 95 | LogText("Shortcut locations: " & String.Join(", ", ShortcutLocations)) 96 | 97 | RDP.ProductUpgradeRandom = Not cmdSwitches.Contains("A") 98 | LogText("MSI upgrade code: {" & RDP.ProductUpgradeCode & "}") 99 | If cmdSwitches.Contains("T") Then RDP.ProductRemoteTag = "" 100 | 101 | RDP.PerUser = cmdSwitches.Contains("U") 102 | If RDP.PerUser Then 103 | LogText("MSI install context: User") 104 | Else 105 | LogText("MSI install context: Machine") 106 | End If 107 | 108 | Dim ShortcutTag = "NONE" 109 | If Not RDP.ProductRemoteTag = "" Then ShortcutTag = "(" & RDP.ProductRemoteTag & ")" 110 | LogText("Shortcut tag: " & ShortcutTag) 111 | 112 | LogText("") 113 | LogText("Generating MSI...") 114 | 115 | RDP.CreateMSI() 116 | 117 | 118 | 119 | End Sub 120 | 121 | 122 | Private Sub LogText(TheText As String, Optional DoExit As Boolean = False) 123 | Console.WriteLine(TheText) 124 | If DoExit = True Then 125 | 'CleanupTempFiles() 126 | End 127 | End If 128 | End Sub 129 | 130 | End Module 131 | 132 | 133 | -------------------------------------------------------------------------------- /RDP2MSI/RDP2MSI.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1001A958-40DB-4444-9CD7-09D1188072D1} 8 | Exe 9 | Sub Main 10 | RDP2MSI 11 | RDP2MSI 12 | 512 13 | Console 14 | v4.0 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | true 22 | true 23 | bin\Debug\ 24 | RDP2MSI.xml 25 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | false 31 | true 32 | true 33 | bin\Release\ 34 | RDP2MSI.xml 35 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 36 | 37 | 38 | On 39 | 40 | 41 | Binary 42 | 43 | 44 | Off 45 | 46 | 47 | On 48 | 49 | 50 | My Project\app.manifest 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | True 77 | Application.myapp 78 | 79 | 80 | True 81 | True 82 | Resources.resx 83 | 84 | 85 | True 86 | Settings.settings 87 | True 88 | 89 | 90 | 91 | 92 | VbMyResourcesResXFileCodeGenerator 93 | Resources.Designer.vb 94 | My.Resources 95 | Designer 96 | 97 | 98 | 99 | 100 | 101 | MyApplicationCodeGenerator 102 | Application.Designer.vb 103 | 104 | 105 | SettingsSingleFileGenerator 106 | My 107 | Settings.Designer.vb 108 | 109 | 110 | 111 | 112 | 113 | {e1cb5f9c-230f-4967-8f19-335f8e4a4906} 114 | RDP2MSILib 115 | 116 | 117 | 118 | 125 | -------------------------------------------------------------------------------- /RDP2MSILib/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | -------------------------------------------------------------------------------- /RDP2MSILib/My Project/Application.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | -------------------------------------------------------------------------------- /RDP2MSILib/My Project/Application.myapp: -------------------------------------------------------------------------------- 1 |  2 | 3 | false 4 | false 5 | 0 6 | true 7 | 0 8 | 1 9 | true 10 | 11 | -------------------------------------------------------------------------------- /RDP2MSILib/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | ' 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /RDP2MSILib/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | Imports System 15 | 16 | Namespace My.Resources 17 | 18 | 'This class was auto-generated by the StronglyTypedResourceBuilder 19 | 'class via a tool like ResGen or Visual Studio. 20 | 'To add or remove a member, edit your .ResX file then rerun ResGen 21 | 'with the /str option, or rebuild your VS project. 22 | ''' 23 | ''' A strongly-typed resource class, for looking up localized strings, etc. 24 | ''' 25 | _ 29 | Friend Module Resources 30 | 31 | Private resourceMan As Global.System.Resources.ResourceManager 32 | 33 | Private resourceCulture As Global.System.Globalization.CultureInfo 34 | 35 | ''' 36 | ''' Returns the cached ResourceManager instance used by this class. 37 | ''' 38 | _ 39 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 40 | Get 41 | If Object.ReferenceEquals(resourceMan, Nothing) Then 42 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RDP2MSIlib.Resources", GetType(Resources).Assembly) 43 | resourceMan = temp 44 | End If 45 | Return resourceMan 46 | End Get 47 | End Property 48 | 49 | ''' 50 | ''' Overrides the current thread's CurrentUICulture property for all 51 | ''' resource lookups using this strongly typed resource class. 52 | ''' 53 | _ 54 | Friend Property Culture() As Global.System.Globalization.CultureInfo 55 | Get 56 | Return resourceCulture 57 | End Get 58 | Set 59 | resourceCulture = value 60 | End Set 61 | End Property 62 | End Module 63 | End Namespace 64 | -------------------------------------------------------------------------------- /RDP2MSILib/My Project/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /RDP2MSILib/My Project/Settings.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My 16 | 17 | _ 20 | Partial Friend NotInheritable Class MySettings 21 | Inherits Global.System.Configuration.ApplicationSettingsBase 22 | 23 | Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) 24 | 25 | #Region "My.Settings Auto-Save Functionality" 26 | #If _MyType = "WindowsForms" Then 27 | Private Shared addedHandler As Boolean 28 | 29 | Private Shared addedHandlerLockObject As New Object 30 | 31 | _ 32 | Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) 33 | If My.Application.SaveMySettingsOnExit Then 34 | My.Settings.Save() 35 | End If 36 | End Sub 37 | #End If 38 | #End Region 39 | 40 | Public Shared ReadOnly Property [Default]() As MySettings 41 | Get 42 | 43 | #If _MyType = "WindowsForms" Then 44 | If Not addedHandler Then 45 | SyncLock addedHandlerLockObject 46 | If Not addedHandler Then 47 | AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings 48 | addedHandler = True 49 | End If 50 | End SyncLock 51 | End If 52 | #End If 53 | Return defaultInstance 54 | End Get 55 | End Property 56 | End Class 57 | End Namespace 58 | 59 | Namespace My 60 | 61 | _ 64 | Friend Module MySettingsProperty 65 | 66 | _ 67 | Friend ReadOnly Property Settings() As Global.RDP2MSIlib.My.MySettings 68 | Get 69 | Return Global.RDP2MSIlib.My.MySettings.Default 70 | End Get 71 | End Property 72 | End Module 73 | End Namespace 74 | -------------------------------------------------------------------------------- /RDP2MSILib/My Project/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RDP2MSILib/RDP2MSILib.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E1CB5F9C-230F-4967-8F19-335F8E4A4906} 8 | Library 9 | RDP2MSIlib 10 | RDP2MSIlib 11 | 512 12 | Windows 13 | v4.0 14 | 15 | 16 | 17 | true 18 | full 19 | true 20 | true 21 | bin\Debug\ 22 | RDP2MSIlib.xml 23 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 24 | 25 | 26 | pdbonly 27 | false 28 | true 29 | true 30 | bin\Release\ 31 | RDP2MSIlib.xml 32 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 33 | 34 | 35 | On 36 | 37 | 38 | Binary 39 | 40 | 41 | Off 42 | 43 | 44 | On 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | True 71 | Application.myapp 72 | 73 | 74 | True 75 | True 76 | Resources.resx 77 | 78 | 79 | True 80 | Settings.settings 81 | True 82 | 83 | 84 | 85 | 86 | VbMyResourcesResXFileCodeGenerator 87 | Resources.Designer.vb 88 | My.Resources 89 | Designer 90 | 91 | 92 | 93 | 94 | MyApplicationCodeGenerator 95 | Application.Designer.vb 96 | 97 | 98 | SettingsSingleFileGenerator 99 | My 100 | Settings.Designer.vb 101 | 102 | 103 | 104 | 105 | {029c010d-728b-4b87-b54a-08b2bbf49bd7} 106 | LockChecker 107 | 108 | 109 | 110 | 117 | -------------------------------------------------------------------------------- /RDPFileLib/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | -------------------------------------------------------------------------------- /RDPFileLib/My Project/Application.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | -------------------------------------------------------------------------------- /RDPFileLib/My Project/Application.myapp: -------------------------------------------------------------------------------- 1 |  2 | 3 | false 4 | false 5 | 0 6 | true 7 | 0 8 | 1 9 | true 10 | 11 | -------------------------------------------------------------------------------- /RDPFileLib/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | ' 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /RDPFileLib/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | Imports System 15 | 16 | Namespace My.Resources 17 | 18 | 'This class was auto-generated by the StronglyTypedResourceBuilder 19 | 'class via a tool like ResGen or Visual Studio. 20 | 'To add or remove a member, edit your .ResX file then rerun ResGen 21 | 'with the /str option, or rebuild your VS project. 22 | ''' 23 | ''' A strongly-typed resource class, for looking up localized strings, etc. 24 | ''' 25 | _ 29 | Friend Module Resources 30 | 31 | Private resourceMan As Global.System.Resources.ResourceManager 32 | 33 | Private resourceCulture As Global.System.Globalization.CultureInfo 34 | 35 | ''' 36 | ''' Returns the cached ResourceManager instance used by this class. 37 | ''' 38 | _ 39 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 40 | Get 41 | If Object.ReferenceEquals(resourceMan, Nothing) Then 42 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RDPFileLib.Resources", GetType(Resources).Assembly) 43 | resourceMan = temp 44 | End If 45 | Return resourceMan 46 | End Get 47 | End Property 48 | 49 | ''' 50 | ''' Overrides the current thread's CurrentUICulture property for all 51 | ''' resource lookups using this strongly typed resource class. 52 | ''' 53 | _ 54 | Friend Property Culture() As Global.System.Globalization.CultureInfo 55 | Get 56 | Return resourceCulture 57 | End Get 58 | Set 59 | resourceCulture = value 60 | End Set 61 | End Property 62 | End Module 63 | End Namespace 64 | -------------------------------------------------------------------------------- /RDPFileLib/My Project/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /RDPFileLib/My Project/Settings.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My 16 | 17 | _ 20 | Partial Friend NotInheritable Class MySettings 21 | Inherits Global.System.Configuration.ApplicationSettingsBase 22 | 23 | Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) 24 | 25 | #Region "My.Settings Auto-Save Functionality" 26 | #If _MyType = "WindowsForms" Then 27 | Private Shared addedHandler As Boolean 28 | 29 | Private Shared addedHandlerLockObject As New Object 30 | 31 | _ 32 | Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) 33 | If My.Application.SaveMySettingsOnExit Then 34 | My.Settings.Save() 35 | End If 36 | End Sub 37 | #End If 38 | #End Region 39 | 40 | Public Shared ReadOnly Property [Default]() As MySettings 41 | Get 42 | 43 | #If _MyType = "WindowsForms" Then 44 | If Not addedHandler Then 45 | SyncLock addedHandlerLockObject 46 | If Not addedHandler Then 47 | AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings 48 | addedHandler = True 49 | End If 50 | End SyncLock 51 | End If 52 | #End If 53 | Return defaultInstance 54 | End Get 55 | End Property 56 | End Class 57 | End Namespace 58 | 59 | Namespace My 60 | 61 | _ 64 | Friend Module MySettingsProperty 65 | 66 | _ 67 | Friend ReadOnly Property Settings() As Global.RDPFileLib.My.MySettings 68 | Get 69 | Return Global.RDPFileLib.My.MySettings.Default 70 | End Get 71 | End Property 72 | End Module 73 | End Namespace 74 | -------------------------------------------------------------------------------- /RDPFileLib/My Project/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /RDPFileLib/RDPFileLib.bak.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {258307D5-A407-4622-BF1A-BDCA8E3D2FAA} 8 | Library 9 | RDPFileLib 10 | RDPFileLib 11 | 512 12 | Windows 13 | v4.0 14 | 15 | 16 | 17 | true 18 | full 19 | true 20 | true 21 | bin\Debug\ 22 | RDPFileLib.xml 23 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 24 | 25 | 26 | pdbonly 27 | false 28 | true 29 | true 30 | bin\Release\ 31 | RDPFileLib.xml 32 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 33 | 34 | 35 | On 36 | 37 | 38 | Binary 39 | 40 | 41 | Off 42 | 43 | 44 | On 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | True 70 | Application.myapp 71 | 72 | 73 | True 74 | True 75 | Resources.resx 76 | 77 | 78 | True 79 | Settings.settings 80 | True 81 | 82 | 83 | 84 | 85 | VbMyResourcesResXFileCodeGenerator 86 | Resources.Designer.vb 87 | My.Resources 88 | Designer 89 | 90 | 91 | 92 | 93 | 94 | MyApplicationCodeGenerator 95 | Application.Designer.vb 96 | 97 | 98 | SettingsSingleFileGenerator 99 | My 100 | Settings.Designer.vb 101 | 102 | 103 | 104 | 111 | -------------------------------------------------------------------------------- /RDPFileLib/RDPFileLib.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {258307D5-A407-4622-BF1A-BDCA8E3D2FAA} 8 | Library 9 | RDPFileLib 10 | RDPFileLib 11 | 512 12 | Windows 13 | v4.0 14 | 15 | 16 | 17 | true 18 | full 19 | true 20 | true 21 | bin\Debug\ 22 | RDPFileLib.xml 23 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 24 | 25 | 26 | pdbonly 27 | false 28 | true 29 | true 30 | bin\Release\ 31 | RDPFileLib.xml 32 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 33 | 34 | 35 | On 36 | 37 | 38 | Binary 39 | 40 | 41 | Off 42 | 43 | 44 | On 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | True 71 | Application.myapp 72 | 73 | 74 | True 75 | True 76 | Resources.resx 77 | 78 | 79 | True 80 | Settings.settings 81 | True 82 | 83 | 84 | 85 | 86 | VbMyResourcesResXFileCodeGenerator 87 | Resources.Designer.vb 88 | My.Resources 89 | Designer 90 | 91 | 92 | 93 | 94 | 95 | MyApplicationCodeGenerator 96 | Application.Designer.vb 97 | 98 | 99 | SettingsSingleFileGenerator 100 | My 101 | Settings.Designer.vb 102 | 103 | 104 | 105 | 106 | {029C010D-728B-4B87-B54A-08B2BBF49BD7} 107 | LockChecker 108 | 109 | 110 | 111 | 118 | -------------------------------------------------------------------------------- /RDPFileLib/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /RDPSign/My Project/Application.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | -------------------------------------------------------------------------------- /RDPSign/My Project/Application.myapp: -------------------------------------------------------------------------------- 1 |  2 | 3 | false 4 | false 5 | 0 6 | true 7 | 0 8 | 1 9 | true 10 | 11 | -------------------------------------------------------------------------------- /RDPSign/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | ' 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /RDPSign/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | Imports System 15 | 16 | Namespace My.Resources 17 | 18 | 'This class was auto-generated by the StronglyTypedResourceBuilder 19 | 'class via a tool like ResGen or Visual Studio. 20 | 'To add or remove a member, edit your .ResX file then rerun ResGen 21 | 'with the /str option, or rebuild your VS project. 22 | ''' 23 | ''' A strongly-typed resource class, for looking up localized strings, etc. 24 | ''' 25 | _ 29 | Friend Module Resources 30 | 31 | Private resourceMan As Global.System.Resources.ResourceManager 32 | 33 | Private resourceCulture As Global.System.Globalization.CultureInfo 34 | 35 | ''' 36 | ''' Returns the cached ResourceManager instance used by this class. 37 | ''' 38 | _ 39 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 40 | Get 41 | If Object.ReferenceEquals(resourceMan, Nothing) Then 42 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RDPSign.Resources", GetType(Resources).Assembly) 43 | resourceMan = temp 44 | End If 45 | Return resourceMan 46 | End Get 47 | End Property 48 | 49 | ''' 50 | ''' Overrides the current thread's CurrentUICulture property for all 51 | ''' resource lookups using this strongly typed resource class. 52 | ''' 53 | _ 54 | Friend Property Culture() As Global.System.Globalization.CultureInfo 55 | Get 56 | Return resourceCulture 57 | End Get 58 | Set 59 | resourceCulture = value 60 | End Set 61 | End Property 62 | End Module 63 | End Namespace 64 | -------------------------------------------------------------------------------- /RDPSign/My Project/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /RDPSign/My Project/Settings.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My 16 | 17 | _ 20 | Partial Friend NotInheritable Class MySettings 21 | Inherits Global.System.Configuration.ApplicationSettingsBase 22 | 23 | Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) 24 | 25 | #Region "My.Settings Auto-Save Functionality" 26 | #If _MyType = "WindowsForms" Then 27 | Private Shared addedHandler As Boolean 28 | 29 | Private Shared addedHandlerLockObject As New Object 30 | 31 | _ 32 | Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs) 33 | If My.Application.SaveMySettingsOnExit Then 34 | My.Settings.Save() 35 | End If 36 | End Sub 37 | #End If 38 | #End Region 39 | 40 | Public Shared ReadOnly Property [Default]() As MySettings 41 | Get 42 | 43 | #If _MyType = "WindowsForms" Then 44 | If Not addedHandler Then 45 | SyncLock addedHandlerLockObject 46 | If Not addedHandler Then 47 | AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings 48 | addedHandler = True 49 | End If 50 | End SyncLock 51 | End If 52 | #End If 53 | Return defaultInstance 54 | End Get 55 | End Property 56 | End Class 57 | End Namespace 58 | 59 | Namespace My 60 | 61 | _ 64 | Friend Module MySettingsProperty 65 | 66 | _ 67 | Friend ReadOnly Property Settings() As Global.RDPSign.My.MySettings 68 | Get 69 | Return Global.RDPSign.My.MySettings.Default 70 | End Get 71 | End Property 72 | End Module 73 | End Namespace 74 | -------------------------------------------------------------------------------- /RDPSign/My Project/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RDPSign/RDPSign.vb: -------------------------------------------------------------------------------- 1 | Imports System.Windows.Forms 2 | 3 | Public Class RDPSign 4 | Public ErrorNumber As Integer = 0 5 | Public ErrorString As String = "" 6 | 7 | Sub main() 8 | 9 | End Sub 10 | 11 | ''' 12 | ''' Get all Certificate friendly names 13 | ''' 14 | ''' String array of Certificate friendly names 15 | Function GetCertificateFriendlyName() 16 | Dim CertStoreLM As Security.Cryptography.X509Certificates.X509Store 17 | Dim CertStoreCU As Security.Cryptography.X509Certificates.X509Store 18 | CertStoreLM = GetCertificateStoreLM() 19 | CertStoreCU = GetCertificateStoreCU() 20 | 21 | Dim FriendlyNames(CertStoreLM.Certificates.Count + CertStoreCU.Certificates.Count) As String 22 | Dim Counter As Integer = 0 23 | For Each Certificate In CertStoreLM.Certificates 24 | If Certificate.FriendlyName IsNot "" Then 25 | FriendlyNames(Counter) = Certificate.FriendlyName 26 | Counter = Counter + 1 27 | End If 28 | Next 29 | For Each Certificate In CertStoreCU.Certificates 30 | If Certificate.FriendlyName IsNot "" Then 31 | FriendlyNames(Counter) = Certificate.FriendlyName 32 | Counter = Counter + 1 33 | End If 34 | Next 35 | Array.Resize(FriendlyNames, Counter) 36 | Return FriendlyNames 37 | End Function 38 | 39 | ''' 40 | ''' Open the Local Machine certificate store and return it to the calling function/sub 41 | ''' 42 | ''' Certificate Store 43 | Function GetCertificateStoreLM() 44 | Dim CertStore As New Security.Cryptography.X509Certificates.X509Store(Security.Cryptography.X509Certificates.StoreLocation.LocalMachine) 45 | CertStore.Open(Security.Cryptography.X509Certificates.OpenFlags.ReadOnly) 46 | Return CertStore 47 | End Function 48 | 49 | ''' 50 | ''' Open the Current User certificate store and return it to the calling function/sub 51 | ''' 52 | ''' Certificate Store 53 | Function GetCertificateStoreCU() 54 | Dim CertStore As New Security.Cryptography.X509Certificates.X509Store(Security.Cryptography.X509Certificates.StoreLocation.CurrentUser) 55 | CertStore.Open(Security.Cryptography.X509Certificates.OpenFlags.ReadOnly) 56 | Return CertStore 57 | End Function 58 | 59 | ''' 60 | ''' Given a friendly name, find and return the associated thumbprint 61 | ''' 62 | ''' String of the Friendly Name of a certificate 63 | ''' String of the thumbprint of the certificate 64 | Function GetThumbprint(FriendlyName As String) 65 | Dim Thumbprint As String 66 | Dim CertStoreLM As Security.Cryptography.X509Certificates.X509Store 67 | CertStoreLM = GetCertificateStoreLM() 68 | For Each certificate In CertStoreLM.Certificates 69 | If certificate.FriendlyName = FriendlyName Then 70 | Thumbprint = certificate.Thumbprint 71 | CertStoreLM.Close() 72 | Return Thumbprint 73 | End If 74 | Next 75 | CertStoreLM.Close() 76 | Dim CertStoreCU As Security.Cryptography.X509Certificates.X509Store 77 | CertStoreCU = GetCertificateStoreCU() 78 | For Each certificate In CertStoreCU.Certificates 79 | If certificate.FriendlyName = FriendlyName Then 80 | Thumbprint = certificate.Thumbprint 81 | CertStoreCU.Close() 82 | Return Thumbprint 83 | End If 84 | Next 85 | ' We could get here if something went wrong such as Certificate was removed from certificate store after it was loaded into the application 86 | ' return an invalid thumbprint 87 | Return "0000" 88 | End Function 89 | 90 | ''' 91 | ''' Sign an RDP file and make a backup of the unsigned one if requested 92 | ''' 93 | ''' Thumbprint used to sign RDP file 94 | ''' Location of RDP file 95 | ''' Boolean indicating if a backup should be created or not 96 | Sub SignRDP(Thumbprint As String, RDPFileLocation As String, CreateBackup As Boolean) 97 | If Thumbprint = "0000" Then 98 | 'Invalid thumbprint, this should be handled on the application side, but just as a safety, return without doing any work if invalid thumbprint sent 99 | Return 100 | End If 101 | If CreateBackup Then 102 | Dim BackupFile = System.IO.Path.GetDirectoryName(RDPFileLocation) & "\" & System.IO.Path.GetFileNameWithoutExtension(RDPFileLocation) & "-Unsigned.rdp" 103 | Dim LockCheck As New LockChecker.LockChecker() 104 | Dim FileLocked As String 105 | Dim SkipFile As Boolean = False 106 | FileLocked = LockCheck.CheckLock(BackupFile) 107 | While Not (FileLocked = "No locks") 108 | If (MessageBox.Show("The file " + BackupFile + " is currently locked. Lock information:" + FileLocked + vbNewLine + "Do you want to try again?", "File Locked", MessageBoxButtons.YesNo) = DialogResult.Yes) Then 109 | FileLocked = LockCheck.CheckLock(BackupFile) 110 | Else 111 | MessageBox.Show("The following file will not be copied:" + vbNewLine + BackupFile) 112 | SkipFile = True 113 | FileLocked = "No locks" 114 | End If 115 | End While 116 | If Not (SkipFile) Then 117 | System.IO.File.Copy(RDPFileLocation, BackupFile, True) 'backup file with overwrite 118 | End If 119 | 120 | End If 121 | 122 | 'If we get here, we should be good to run the command to sign the RDP file. 123 | 124 | 'Grab the rdpsign.exe location and then verify that it exists 125 | 126 | Dim Command = GetRdpsignExeLocation() 127 | 128 | If My.Computer.FileSystem.FileExists(Command) Then 129 | 130 | Dim Arguments As String 131 | Dim FileVersionInfo As FileVersionInfo = FileVersionInfo.GetVersionInfo(Command) 132 | ' On my windows 10 computer, the argument is /sha256 instead of /sha1. /sha1 doesn't work. 133 | ' On my windows 10 computer, the Product parts come in at 10.0.18362.1 134 | ' On a Windows Server 2008 R2 server I have access to, the argument is /sha1. 135 | ' On a Windows Server 2008 R2 server I have access to, the Product parts come in at 6.1.7601.17514 which is lower than the windows 10 ones. 136 | ' I do not have other versions of windows to test, so will need external testing for this. 137 | ' Not sure where the version number switches over, but also not sure how to determine which method to use otherwise 138 | If (FileVersionInfo.ProductMajorPart >= 10) Then 139 | Arguments = " /sha256 " & Thumbprint & " """ & RDPFileLocation & """" 140 | 141 | Else 142 | Arguments = " /sha1 " & Thumbprint & " """ & RDPFileLocation & """" 143 | End If 144 | Dim StartInfo As New ProcessStartInfo 145 | StartInfo.FileName = Command 146 | StartInfo.Arguments = Arguments 147 | StartInfo.WindowStyle = ProcessWindowStyle.Hidden 148 | Process.Start(StartInfo) 149 | Else 150 | MessageBox.Show("RDPSign executable not found:" & vbNewLine & vbNewLine & Command, My.Application.Info.AssemblyName, MessageBoxButtons.OK, MessageBoxIcon.Error) 151 | End If 152 | 153 | End Sub 154 | 155 | ''' 156 | ''' Find the full path to rdpsign.exe from a list of possible locations 157 | ''' 158 | ''' A path to rdpsign.exe or an empty string 159 | Function GetRdpsignExeLocation() 160 | 'Each path to check for rdpsign.exe is added to this array. 161 | 'If it is found in more than one location, the lowest in the list will be selected. 162 | Dim PossibleRdpsignPaths() As String = { 163 | GetSysDir(), 164 | My.Application.Info.DirectoryPath 165 | } 166 | 167 | Dim FinalRdpSignPath As String = "" 168 | 169 | For Each RdpsignPath In PossibleRdpsignPaths 170 | If My.Computer.FileSystem.FileExists(RdpsignPath & "\rdpsign.exe") Then 171 | FinalRdpSignPath = RdpsignPath & "\rdpsign.exe" 172 | End If 173 | Next 174 | 175 | Return FinalRdpSignPath 176 | 177 | End Function 178 | 179 | 180 | Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long 181 | 182 | Function GetSysDir() As String 183 | Return Environment.SystemDirectory.ToString 184 | End Function 185 | 186 | End Class 187 | -------------------------------------------------------------------------------- /RDPSign/RDPSign.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {57DABB69-B1D3-445F-91E7-B0412ABAC218} 8 | Library 9 | RDPSign 10 | RDPSign 11 | 512 12 | Windows 13 | v4.0 14 | true 15 | 16 | 17 | 18 | true 19 | full 20 | true 21 | true 22 | bin\Debug\ 23 | RDPSign.xml 24 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 25 | 26 | 27 | pdbonly 28 | false 29 | true 30 | true 31 | bin\Release\ 32 | RDPSign.xml 33 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 34 | 35 | 36 | On 37 | 38 | 39 | Binary 40 | 41 | 42 | Off 43 | 44 | 45 | On 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | True 73 | Application.myapp 74 | 75 | 76 | True 77 | True 78 | Resources.resx 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | 87 | 88 | 89 | VbMyResourcesResXFileCodeGenerator 90 | Resources.Designer.vb 91 | My.Resources 92 | Designer 93 | 94 | 95 | 96 | 97 | MyApplicationCodeGenerator 98 | Application.Designer.vb 99 | 100 | 101 | SettingsSingleFileGenerator 102 | My 103 | Settings.Designer.vb 104 | 105 | 106 | 107 | 108 | {029c010d-728b-4b87-b54a-08b2bbf49bd7} 109 | LockChecker 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # RemoteApp Tool 4 | 5 | With Microsoft RemoteApp technology, you can seamlessly use an application that is running on another computer. 6 | 7 | RemoteApp Tool is a utility that allows you to create/manage RemoteApps hosted on Windows (7, 8, 10, 11, XP and Server) as well as generate RDP and MSI files for clients. 8 | 9 | If you want your RemoteApps to appear in the Start Menu of your clients, or via a web interface, check out [RAWeb](https://github.com/kimmknight/raweb)! 10 | 11 | If you have questions, comments or suggestions about RemoteApp Tool, please visit [Discussions](https://github.com/kimmknight/remoteapptool/discussions). 12 | 13 | ## Features 14 | 15 | * Create and manage RemoteApps on Windows desktops and servers 16 | * Generate RDP files 17 | * Generate MSI installers (requires WiX Toolset) 18 | * Use a Remote Desktop Gateway 19 | * Set options such as session timeouts 20 | * Select icons for your apps 21 | * File type associations for deployed apps 22 | * Sign RDP files 23 | * Backup RemoteApps 24 | 25 | ## Requirements 26 | 27 | * Microsoft .Net Framework 4 28 | * [WiX Toolset v3](https://wixtoolset.org/docs/wix3/) (If you want to create MSIs. Reboot after installing.) 29 | * A **supported** edition of Windows XP, 7, 8, 10, or Server. See the [compatibility chart](https://github.com/kimmknight/remoteapptool/wiki/Windows-Compatibility). 30 | 31 | **Note:** If you try to host RemoteApps on an incompatible edition of Windows (eg. Windows 10 Home), the tool will run but RemoteApps ***will not work***. The RDP client will appear to be connecting, then just disappear with no error shown. 32 | 33 | ## Download 34 | 35 | **Latest:** 36 | 37 | [RemoteApp Tool 6.1.0.0 Installer](https://github.com/kimmknight/remoteapptool/releases/download/v6.1.0.0/RemoteApp.Tool.6100.msi) 38 | 39 | [RemoteApp Tool 6.1.0.0 Zip](https://github.com/kimmknight/remoteapptool/releases/download/v6.1.0.0/RemoteApp.Tool.6100.zip) 40 | 41 | Please note: The latest installer no longer works on Windows XP, use the Zip instead. 42 | 43 | Other recent releases are available [here](https://github.com/kimmknight/remoteapptool/releases), and really old releases are available [here](https://github.com/kimmknight/remoteapptool/wiki/Version-history-(pre-GitHub)). 44 | 45 | ## User guide 46 | 47 | [How to create a RemoteApp and use it on another computer](https://github.com/kimmknight/remoteapptool/wiki/Create-a-RemoteApp-and-use-it-on-another-computer) 48 | 49 | ## Screenshots 50 | 51 | ![Screenshot 1](https://raw.githubusercontent.com/wiki/kimmknight/remoteapptool/images/screenshots/ss1.png) 52 | 53 | 54 | ![Screenshot 2](https://raw.githubusercontent.com/wiki/kimmknight/remoteapptool/images/screenshots/ss2.png) 55 | 56 | 57 | ![Screenshot 3](https://raw.githubusercontent.com/wiki/kimmknight/remoteapptool/images/screenshots/ss3.png) 58 | 59 | 60 | ![Screenshot 4](https://raw.githubusercontent.com/wiki/kimmknight/remoteapptool/images/screenshots/ss5.png) 61 | 62 | 63 | ![Screenshot 4](https://raw.githubusercontent.com/wiki/kimmknight/remoteapptool/images/screenshots/ss4.png) 64 | -------------------------------------------------------------------------------- /remoteapp-tool/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | -------------------------------------------------------------------------------- /remoteapp-tool/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 0 15 | 16 | 17 | 0 18 | 19 | 20 | False 21 | 22 | 23 | False 24 | 25 | 26 | 27 | 28 | 29 | 3389 30 | 31 | 32 | 33 | 34 | 35 | False 36 | 37 | 38 | 39 | 40 | 41 | False 42 | 43 | 44 | True 45 | 46 | 47 | True 48 | 49 | 50 | False 51 | 52 | 53 | True 54 | 55 | 56 | remote 57 | 58 | 59 | False 60 | 61 | 62 | False 63 | 64 | 65 | False 66 | 67 | 68 | False 69 | 70 | 71 | False 72 | 73 | 74 | False 75 | 76 | 77 | 0 78 | 79 | 80 | disableremoteappcapscheck|disableremoteappcapscheck|i|1 81 | drivestoredirect|drivestoredirect|s|* 82 | prompt_for_credentials|prompt for credentials|i|1 83 | promptcredentialonce|promptcredentialonce|i|0 84 | redirectcomports|redirectcomports|i|1 85 | span_monitors|span monitors|i|1 86 | use_multimon|use multimon|i|1 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /remoteapp-tool/ApplicationEvents.vb: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /remoteapp-tool/HelpSystem.vb: -------------------------------------------------------------------------------- 1 | Module HelpSystem 2 | Public Sub SetupTips(TheForm As Windows.Forms.Form) 3 | Dim toolTip1 As New ToolTip With { 4 | .AutoPopDelay = 10000, 5 | .InitialDelay = 500, 6 | .ReshowDelay = 500 7 | } 8 | 9 | Dim HelpString As String 10 | 11 | For Each Control As Control In TheForm.Controls 12 | For Each SubControl As Control In Control.Controls 13 | For Each SubSubControl In SubControl.Controls 14 | For Each SubSubSubControl In SubSubControl.Controls 15 | HelpString = GetTipString(Control.Parent.Name, SubSubSubControl.Name) 16 | If Not HelpString = "" Then toolTip1.SetToolTip(SubSubSubControl, HelpString) 17 | Next 18 | HelpString = GetTipString(Control.Parent.Name, SubSubControl.Name) 19 | If Not HelpString = "" Then toolTip1.SetToolTip(SubSubControl, HelpString) 20 | Next 21 | HelpString = GetTipString(Control.Parent.Name, SubControl.Name) 22 | If Not HelpString = "" Then toolTip1.SetToolTip(SubControl, HelpString) 23 | Next 24 | HelpString = GetTipString(Control.Parent.Name, Control.Name) 25 | If Not HelpString = "" Then toolTip1.SetToolTip(Control, HelpString) 26 | Next 27 | 28 | End Sub 29 | 30 | Private Function GetTipString(FormName As String, ControlName As String) As String 31 | Dim TipString As String = "" 32 | 33 | Dim TipText As String = GetTipFile() 34 | Dim TipArray = TipText.Split(ControlChars.CrLf.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) 35 | 36 | For Each TipLine As String In TipArray 37 | Dim TipLineArray = TipLine.Split("|") 38 | If TipLineArray(0) = FormName And TipLineArray(1) = ControlName Then TipString = TipLineArray(2) 39 | Next 40 | 41 | TipString = TipString.Replace("\r", vbCr) 42 | TipString = TipString.Replace("\n", vbLf) 43 | 44 | Return TipString 45 | End Function 46 | 47 | Private Function GetTipFile() As String 48 | Dim TipFile As String = "" 49 | 50 | If My.Computer.FileSystem.FileExists("tips.txt") Then 51 | TipFile = My.Computer.FileSystem.ReadAllText("tips.txt") 52 | Else 53 | TipFile = GetBuiltInTips() 54 | End If 55 | 56 | Return TipFile 57 | End Function 58 | 59 | Private Function GetBuiltInTips() As String 60 | Dim Tips As String = "" 61 | 62 | Tips += "RemoteAppMainWindow|CreateButton|Add a new RemoteApp." & vbCrLf 63 | Tips += "RemoteAppMainWindow|DeleteButton|Remove selected RemoteApp." & vbCrLf 64 | Tips += "RemoteAppMainWindow|EditButton|Edit properties of selected RemoteApp." & vbCrLf 65 | Tips += "RemoteAppMainWindow|CreateClientConnection|Creates a RDP file or MSI installer for the selected RemoteApp." & vbCrLf 66 | 67 | Tips += "RemoteAppEditWindow|SaveButton|Save changes and close." & vbCrLf 68 | Tips += "RemoteAppEditWindow|FTAButton|Set file type associations for this RemoteApp." & vbCrLf 69 | Tips += "RemoteAppEditWindow|CancelEditButton|Discard changes and close." & vbCrLf 70 | Tips += "RemoteAppEditWindow|BrowseIconPath|Select an icon for the RemoteApp." & vbCrLf 71 | Tips += "RemoteAppEditWindow|IconPathCopyButton|Copy the value from the ""Path"" field into the ""Icon path"" field. " & vbCrLf 72 | Tips += "RemoteAppEditWindow|BrowsePath|Browse for application." & vbCrLf 73 | Tips += "RemoteAppEditWindow|IconResetButton|Reset the icon to the default for this application." & vbCrLf 74 | 75 | 'IconResetButton 76 | 77 | Tips += "RemoteAppCreateClientConnection|RDPRadioButton|Create an RDP file." & vbCrLf 78 | Tips += "RemoteAppCreateClientConnection|MSIRadioButton|Create an MSI file." & vbCrLf 79 | Tips += "RemoteAppCreateClientConnection|EditAfterSave|Edit the RDP connection file." & vbCrLf 80 | Tips += "RemoteAppCreateClientConnection|CreateRAWebIcon|Generate an icon for the application and any file type associations.\r\nUse this with RAWeb." & vbCrLf 81 | Tips += "RemoteAppCreateClientConnection|FTAButton|Set file type associations for this RemoteApp.\r\nChanges here will only affect this client connection. They will not be saved." & vbCrLf 82 | Tips += "RemoteAppCreateClientConnection|DisabledFTACheckBox|Do not include file type associations in this client connection." & vbCrLf 83 | Tips += "RemoteAppCreateClientConnection|SaveButton|Save window settings for next time." & vbCrLf 84 | Tips += "RemoteAppCreateClientConnection|ResetButton|Reset window settings to defaults." & vbCrLf 85 | Tips += "RemoteAppCreateClientConnection|CancelEditButton|Close and return to the main window." & vbCrLf 86 | Tips += "RemoteAppCreateClientConnection|CreateButton|Create the client connection and choose where to save it." & vbCrLf 87 | Tips += "RemoteAppCreateClientConnection|UseRDGatewayCheckBox|Use a Remote Desktop Gateway to connect to the host." & vbCrLf 88 | Tips += "RemoteAppCreateClientConnection|AttemptDirectCheckBox|Try a direct connection first, if that fails then use the Remote Desktop Gateway." & vbCrLf 89 | Tips += "RemoteAppCreateClientConnection|ShortcutTagCheckBox|Append some text to the end of each shortcut title." & vbCrLf 90 | Tips += "RemoteAppCreateClientConnection|PerMachineRadioButton|Should the shortcuts install for all users (per-machine), or only for the logged in user (per user)?" & vbCrLf 91 | Tips += "RemoteAppCreateClientConnection|PerUserRadioButton|Should the shortcuts install for all users (per-machine), or only for the logged in user (per user)?" & vbCrLf 92 | Tips += "RemoteAppCreateClientConnection|CheckBoxSignRDPEnabled|Digitally sign the RDP file." & vbCrLf 93 | Tips += "RemoteAppCreateClientConnection|CheckBoxCreateSignedAndUnsigned|Produce both a signed and unsigned copy of the RDP file." & vbCrLf 94 | 95 | Tips += "RemoteAppFileTypeAssociation|CreateButton|Create a new File Type Association." & vbCrLf 96 | Tips += "RemoteAppFileTypeAssociation|DeleteButton|Delete selected File Type Association." & vbCrLf 97 | Tips += "RemoteAppFileTypeAssociation|EditButton|Change icon of selected File Type Association." & vbCrLf 98 | Tips += "RemoteAppFileTypeAssociation|SetAssociationButton|Create or remove the selected File Type Association on the current system." & vbCrLf 99 | Tips += "RemoteAppFileTypeAssociation|CloseButton|Save changes and close." & vbCrLf 100 | 101 | Tips += "RemoteAppIconPicker|BrowseButton|Browse for a file that contains icons." & vbCrLf 102 | Tips += "RemoteAppIconPicker|CancelEditButton|Discard changes and close." & vbCrLf 103 | Tips += "RemoteAppIconPicker|OKButton|Choose the selected icon." & vbCrLf 104 | 105 | Return Tips 106 | End Function 107 | 108 | End Module 109 | -------------------------------------------------------------------------------- /remoteapp-tool/IconLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimmknight/remoteapptool/9c97cbde54af99026146341f083fcfe0750d0510/remoteapp-tool/IconLib.dll -------------------------------------------------------------------------------- /remoteapp-tool/IconModule.vb: -------------------------------------------------------------------------------- 1 | Imports System.IO 2 | Imports System.Drawing 3 | Imports System.Collections.Generic 4 | 5 | Public Class IconExtractor 6 | Private Declare Function ExtractIconEx _ 7 | Lib "shell32.dll" Alias "ExtractIconExA" _ 8 | (ByVal lpszFile As String, ByVal nIconIndex As Int32, _ 9 | ByRef phiconLarge As Int32, ByRef phiconSmall As Int32, _ 10 | ByVal nIcons As Int32) As Int32 11 | 12 | Private Declare Function ExtractIcon _ 13 | Lib "shell32.dll" Alias "ExtractIconA" _ 14 | (ByVal hInst As IntPtr, ByVal lpszExeFileName As String, _ 15 | ByVal nIconIndex As Int32) As Int32 16 | 17 | Private Declare Function DrawIconEx _ 18 | Lib "user32" _ 19 | (ByVal hdc As Int32, ByVal xLeft As Int32, ByVal yTop As Int32, _ 20 | ByVal hIcon As IntPtr, ByVal cxWidth As Int32, ByVal cyWidth As Int32, _ 21 | ByVal istepIfAniCur As Int32, ByVal hbrFlickerFreeDraw As Int32, _ 22 | ByVal diFlags As Int32) As Int32 23 | 24 | Private Declare Function DestroyIcon _ 25 | Lib "user32" _ 26 | (ByVal hIcon As Int32) As Int32 27 | 28 | Private m_hIcons() As Int32 29 | 30 | 31 | Protected Overrides Sub Finalize() 32 | 33 | MyBase.Finalize() 34 | 35 | Dim countIcons As Integer = m_hIcons.Length 36 | 37 | If countIcons > 0 Then 38 | 39 | For iconIndex As Integer = 0 To countIcons - 1 40 | 41 | DestroyIcon(m_hIcons(iconIndex)) 42 | 43 | Next iconIndex 44 | 45 | End If 46 | 47 | End Sub 48 | 49 | Public Function ExtractIcons(ByVal filePath As String, ByVal hInst As IntPtr) As List(Of Icon) 50 | 51 | Dim listIcons As New List(Of Icon) 52 | 53 | Try 54 | 55 | Dim numIcons As Integer = ExtractIconEx(filePath, -1, 0&, 0&, 0&) 56 | 57 | If numIcons = 0 Then 58 | Throw New Exception("No icons found in " & filePath) 59 | End If 60 | 61 | numIcons -= 1 62 | 63 | For currentIcon As Integer = 0 To numIcons 64 | 65 | m_hIcons(currentIcon) = ExtractIcon(hInst, filePath, currentIcon) 66 | 67 | Dim handleIcon As New IntPtr(m_hIcons(currentIcon)) 68 | 69 | If Not handleIcon.Equals(IntPtr.Zero) Then 70 | 71 | listIcons.Add(Icon.FromHandle(handleIcon)) 72 | 73 | End If 74 | 75 | Next currentIcon 76 | 77 | Catch ex As Exception 78 | 79 | MessageBox.Show(ex.ToString()) 80 | 81 | End Try 82 | 83 | Return listIcons 84 | 85 | End Function 86 | 87 | End Class 88 | 89 | Module IconModule 90 | 91 | Public Sub TestIconLib() 92 | Dim testIcon As New IconLib.MultiIcon 93 | End Sub 94 | 95 | Public Function IconFromFilePath(filePath As String) As Icon 96 | Dim result As Icon = Nothing 97 | Try 98 | result = Icon.ExtractAssociatedIcon(filePath) 99 | Catch 100 | End Try 101 | Return result 102 | End Function 103 | 104 | Public Function ExtractToIco(IconSourcePath As String, IconSourceIndex As Integer, IcoDestPath As String) As Boolean 105 | Dim success = False 106 | Dim IconLoadError As Boolean = False 107 | If My.Computer.FileSystem.FileExists(IconSourcePath) = True Then 108 | Dim mIcon As New IconLib.MultiIcon 109 | Try 110 | mIcon.Load(IconSourcePath) 111 | Catch Ex As Exception 112 | IconLoadError = True 113 | End Try 114 | 115 | If Not IconLoadError Then 116 | Dim sIcon As IconLib.SingleIcon 117 | If IconSourceIndex = 0 Then 118 | sIcon = mIcon.FirstOrDefault 119 | Else 120 | sIcon = mIcon.Item(IconSourceIndex) 121 | End If 122 | 123 | Try 124 | sIcon.Save(IcoDestPath) 125 | success = True 126 | Catch Ex As Exception 127 | 128 | End Try 129 | End If 130 | End If 131 | 132 | Return success 133 | End Function 134 | 135 | Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconExA" (ByVal lpszFile As String, ByVal nIconIndex As Integer, ByRef phiconLarge As Integer, ByRef phiconSmall As Integer, ByVal nIcons As Integer) As Integer 136 | 137 | Public Function ReturnIcon(ByVal Path As String, ByVal Index As Integer, Optional ByVal small As Boolean = False) As Icon 138 | Dim bigIcon As Integer 139 | Dim smallIcon As Integer 140 | ExtractIcon(Path, Index, bigIcon, smallIcon, 1) 141 | If bigIcon = 0 Then 142 | ExtractIcon(Path, 0, bigIcon, smallIcon, 1) 143 | End If 144 | If bigIcon <> 0 Then 145 | If small = False Then 146 | Return Icon.FromHandle(bigIcon) 147 | Else 148 | Return Icon.FromHandle(smallIcon) 149 | End If 150 | Else 151 | Return ReturnIcon(GetSysDir() & "\user32.dll", 0) 152 | End If 153 | End Function 154 | 155 | End Module -------------------------------------------------------------------------------- /remoteapp-tool/LocalFtaModule.vb: -------------------------------------------------------------------------------- 1 | Imports RemoteAppLib 2 | 3 | Module LocalFtaModule 4 | 5 | Public Sub RemoveUnusedFTAs() 6 | Dim KeyNames = My.Computer.Registry.ClassesRoot().GetSubKeyNames 7 | Dim RemoveCount As Integer = 0 8 | 9 | For Each KeyName In KeyNames 10 | Dim FTAkey As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot.OpenSubKey(KeyName) 11 | Dim RAvalue As String = FTAkey.GetValue("RemoteApp", "") 12 | If Not RAvalue = "" Then 13 | For Each KeyName2 In KeyNames 14 | Try 15 | Dim FTkey As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot.OpenSubKey(KeyName2) 16 | Dim FTvalue As String = FTkey.GetValue("", "") 17 | If FTvalue = KeyName Then 18 | Dim sra As New RemoteAppLib.SystemRemoteApps 19 | Dim AppExists As Boolean = False 20 | For Each app As RemoteAppLib.RemoteApp In sra.GetAll 21 | If app.Name = GetAppForFTA(KeyName2) Then AppExists = True 22 | Next 23 | If Not AppExists Then 24 | LocalFtaModule.DeleteFTA(KeyName2) 25 | RemoveCount += 1 26 | End If 27 | End If 28 | Catch ex As Exception 29 | 30 | End Try 31 | 32 | Next 33 | End If 34 | Next 35 | 36 | MessageBox.Show("Unused file type associations removed: " & RemoveCount, "File Type Association", MessageBoxButtons.OK, MessageBoxIcon.Information) 37 | End Sub 38 | 39 | Public Function CreateFTACollection(ftaCol As FileTypeAssociationCollection, exeFile As String, RemoteAppName As String, Optional overwrite As Boolean = False) As String 40 | CreateFTACollection = "" 41 | For Each fta As FileTypeAssociation In ftaCol 42 | If DoesFTAExist(fta.Extension) And CreateFTA(fta, exeFile, RemoteAppName, overwrite) = False Then 43 | CreateFTACollection += "|" & fta.Extension 44 | End If 45 | Next 46 | CreateFTACollection = CreateFTACollection.Trim("|") 47 | End Function 48 | 49 | Public Function CreateFTA(fta As FileTypeAssociation, exeFile As String, RemoteAppName As String, Optional overwrite As Boolean = False) As Boolean 50 | If DoesFTAExist(fta.Extension) = False Or overwrite = True Then 51 | DeleteFTA(fta.Extension) 52 | 53 | Dim FileTypeReg = My.Computer.Registry.ClassesRoot.CreateSubKey("." & fta.Extension) 54 | FileTypeReg.SetValue("", fta.Extension & "_file") 55 | 56 | Dim FileTypeKey = My.Computer.Registry.ClassesRoot.CreateSubKey(fta.Extension & "_file") 57 | FileTypeKey.SetValue("RemoteApp", RemoteAppName) 58 | 59 | Dim FileTypeKeyShell = FileTypeKey.CreateSubKey("shell") 60 | Dim FileTypeKeyShellOpen = FileTypeKeyShell.CreateSubKey("open") 61 | Dim FileTypeKeyShellOpenCommand = FileTypeKeyShellOpen.CreateSubKey("command") 62 | 63 | FileTypeKeyShellOpenCommand.SetValue("", """" & exeFile & """ ""%1""") 64 | 65 | Dim FileTypeKeyDefIcon = FileTypeKey.CreateSubKey("DefaultIcon") 66 | FileTypeKeyDefIcon.SetValue("", """" & fta.IconPath & """," & fta.IconIndex) 67 | CreateFTA = True 68 | Else 69 | CreateFTA = False 70 | End If 71 | End Function 72 | 73 | Public Function GetAppForFTA(fileExtension As String) As String 74 | fileExtension = fileExtension.TrimStart(".") 75 | GetAppForFTA = "" 76 | 77 | If DoesFTAExist(fileExtension) And IsFTAMine(fileExtension) Then 78 | Try 79 | Dim HKCRext As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot().OpenSubKey("." & fileExtension) 80 | Dim HKCRfta = HKCRext.GetValue("", "") 81 | If Not HKCRfta = "" Then 82 | Dim HKCRftaKey As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot().OpenSubKey(HKCRfta) 83 | GetAppForFTA = HKCRftaKey.GetValue("RemoteApp", "") 84 | End If 85 | 86 | Catch ex As Exception 87 | 88 | End Try 89 | 90 | End If 91 | End Function 92 | 93 | Public Sub DeleteFTA(fileExtension As String) 94 | fileExtension = fileExtension.TrimStart(".") 95 | If Not My.Computer.Registry.ClassesRoot.OpenSubKey("." & fileExtension) Is Nothing Then _ 96 | My.Computer.Registry.ClassesRoot.DeleteSubKeyTree("." & fileExtension) 97 | 98 | If Not My.Computer.Registry.ClassesRoot.OpenSubKey(fileExtension & "_file") Is Nothing Then _ 99 | My.Computer.Registry.ClassesRoot.DeleteSubKeyTree(fileExtension & "_file") 100 | End Sub 101 | 102 | Public Function DoesFTAExist(fileExtension As String) As Boolean 103 | fileExtension = fileExtension.TrimStart(".") 104 | Dim FTAexists As Boolean = False 105 | 106 | If Not (My.Computer.Registry.ClassesRoot().OpenSubKey("." & fileExtension) Is Nothing) Then 107 | FTAexists = True 108 | End If 109 | 110 | Return FTAexists 111 | End Function 112 | 113 | 114 | Public Function IsFTAMine(fileExtension As String) As Boolean 115 | fileExtension = fileExtension.TrimStart(".") 116 | IsFTAMine = False 117 | Try 118 | Dim HKCRext As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot().OpenSubKey("." & fileExtension) 119 | Dim HKCRfta = HKCRext.GetValue("", "") 120 | If Not HKCRfta = "" Then 121 | Dim HKCRftaKey As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot().OpenSubKey(HKCRfta) 122 | If Not HKCRftaKey.GetValue("RemoteApp", "") = "" Then IsFTAMine = True 123 | End If 124 | 125 | Catch ex As Exception 126 | 127 | End Try 128 | 129 | End Function 130 | 131 | End Module 132 | -------------------------------------------------------------------------------- /remoteapp-tool/My Project/Application.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My 16 | 17 | 'NOTE: This file is auto-generated; do not modify it directly. To make changes, 18 | ' or if you encounter build errors in this file, go to the Project Designer 19 | ' (go to Project Properties or double-click the My Project node in 20 | ' Solution Explorer), and make changes on the Application tab. 21 | ' 22 | Partial Friend Class MyApplication 23 | 24 | _ 25 | Public Sub New() 26 | MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows) 27 | Me.IsSingleInstance = true 28 | Me.EnableVisualStyles = true 29 | Me.SaveMySettingsOnExit = true 30 | Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses 31 | End Sub 32 | 33 | _ 34 | Protected Overrides Sub OnCreateMainForm() 35 | Me.MainForm = Global.RemoteApp_Tool.RemoteAppMainWindow 36 | End Sub 37 | End Class 38 | End Namespace 39 | -------------------------------------------------------------------------------- /remoteapp-tool/My Project/Application.myapp: -------------------------------------------------------------------------------- 1 |  2 | 3 | true 4 | RemoteAppMainWindow 5 | true 6 | 0 7 | true 8 | 0 9 | true 10 | -------------------------------------------------------------------------------- /remoteapp-tool/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | ' 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /remoteapp-tool/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.42000 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | Imports System 15 | 16 | Namespace My.Resources 17 | 18 | 'This class was auto-generated by the StronglyTypedResourceBuilder 19 | 'class via a tool like ResGen or Visual Studio. 20 | 'To add or remove a member, edit your .ResX file then rerun ResGen 21 | 'with the /str option, or rebuild your VS project. 22 | ''' 23 | ''' A strongly-typed resource class, for looking up localized strings, etc. 24 | ''' 25 | _ 29 | Friend Module Resources 30 | 31 | Private resourceMan As Global.System.Resources.ResourceManager 32 | 33 | Private resourceCulture As Global.System.Globalization.CultureInfo 34 | 35 | ''' 36 | ''' Returns the cached ResourceManager instance used by this class. 37 | ''' 38 | _ 39 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 40 | Get 41 | If Object.ReferenceEquals(resourceMan, Nothing) Then 42 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RemoteApp_Tool.Resources", GetType(Resources).Assembly) 43 | resourceMan = temp 44 | End If 45 | Return resourceMan 46 | End Get 47 | End Property 48 | 49 | ''' 50 | ''' Overrides the current thread's CurrentUICulture property for all 51 | ''' resource lookups using this strongly typed resource class. 52 | ''' 53 | _ 54 | Friend Property Culture() As Global.System.Globalization.CultureInfo 55 | Get 56 | Return resourceCulture 57 | End Get 58 | Set 59 | resourceCulture = value 60 | End Set 61 | End Property 62 | End Module 63 | End Namespace 64 | -------------------------------------------------------------------------------- /remoteapp-tool/My Project/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | -------------------------------------------------------------------------------- /remoteapp-tool/My Project/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 0 7 | 8 | 9 | 0 10 | 11 | 12 | False 13 | 14 | 15 | False 16 | 17 | 18 | 19 | 20 | 21 | 3389 22 | 23 | 24 | 25 | 26 | 27 | False 28 | 29 | 30 | 31 | 32 | 33 | False 34 | 35 | 36 | True 37 | 38 | 39 | True 40 | 41 | 42 | False 43 | 44 | 45 | True 46 | 47 | 48 | remote 49 | 50 | 51 | False 52 | 53 | 54 | False 55 | 56 | 57 | False 58 | 59 | 60 | False 61 | 62 | 63 | False 64 | 65 | 66 | False 67 | 68 | 69 | 0 70 | 71 | 72 | disableremoteappcapscheck|disableremoteappcapscheck|i|1 73 | drivestoredirect|drivestoredirect|s|* 74 | prompt_for_credentials|prompt for credentials|i|1 75 | promptcredentialonce|promptcredentialonce|i|0 76 | redirectcomports|redirectcomports|i|1 77 | span_monitors|span monitors|i|1 78 | use_multimon|use multimon|i|1 79 | 80 | 81 | -------------------------------------------------------------------------------- /remoteapp-tool/My Project/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 52 | -------------------------------------------------------------------------------- /remoteapp-tool/RemoteApp Tool.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29424.173 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RemoteApp Tool", "RemoteApp Tool.vbproj", "{2D140FE4-0794-43AC-BE7B-9D918B3F9C61}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {785B6808-B2FE-4C18-9D63-6DAB46482374} = {785B6808-B2FE-4C18-9D63-6DAB46482374} 9 | {57DABB69-B1D3-445F-91E7-B0412ABAC218} = {57DABB69-B1D3-445F-91E7-B0412ABAC218} 10 | {E1CB5F9C-230F-4967-8F19-335F8E4A4906} = {E1CB5F9C-230F-4967-8F19-335F8E4A4906} 11 | {258307D5-A407-4622-BF1A-BDCA8E3D2FAA} = {258307D5-A407-4622-BF1A-BDCA8E3D2FAA} 12 | EndProjectSection 13 | EndProject 14 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RemoteAppLib", "..\RemoteAppLib\RemoteAppLib.vbproj", "{785B6808-B2FE-4C18-9D63-6DAB46482374}" 15 | EndProject 16 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RDP2MSILib", "..\RDP2MSILib\RDP2MSILib.vbproj", "{E1CB5F9C-230F-4967-8F19-335F8E4A4906}" 17 | EndProject 18 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RDP2MSI", "..\RDP2MSI\RDP2MSI.vbproj", "{1001A958-40DB-4444-9CD7-09D1188072D1}" 19 | ProjectSection(ProjectDependencies) = postProject 20 | {E1CB5F9C-230F-4967-8F19-335F8E4A4906} = {E1CB5F9C-230F-4967-8F19-335F8E4A4906} 21 | EndProjectSection 22 | EndProject 23 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RDPFileLib", "..\RDPFileLib\RDPFileLib.vbproj", "{258307D5-A407-4622-BF1A-BDCA8E3D2FAA}" 24 | EndProject 25 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RDPSign", "..\RDPSign\RDPSign.vbproj", "{57DABB69-B1D3-445F-91E7-B0412ABAC218}" 26 | EndProject 27 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "LockChecker", "..\LockChecker\LockChecker.vbproj", "{029C010D-728B-4B87-B54A-08B2BBF49BD7}" 28 | EndProject 29 | Global 30 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 31 | Debug|Any CPU = Debug|Any CPU 32 | Release|Any CPU = Release|Any CPU 33 | EndGlobalSection 34 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 35 | {2D140FE4-0794-43AC-BE7B-9D918B3F9C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {2D140FE4-0794-43AC-BE7B-9D918B3F9C61}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {2D140FE4-0794-43AC-BE7B-9D918B3F9C61}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {2D140FE4-0794-43AC-BE7B-9D918B3F9C61}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {785B6808-B2FE-4C18-9D63-6DAB46482374}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {785B6808-B2FE-4C18-9D63-6DAB46482374}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {785B6808-B2FE-4C18-9D63-6DAB46482374}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {785B6808-B2FE-4C18-9D63-6DAB46482374}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {E1CB5F9C-230F-4967-8F19-335F8E4A4906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {E1CB5F9C-230F-4967-8F19-335F8E4A4906}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {E1CB5F9C-230F-4967-8F19-335F8E4A4906}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {E1CB5F9C-230F-4967-8F19-335F8E4A4906}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {1001A958-40DB-4444-9CD7-09D1188072D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 48 | {1001A958-40DB-4444-9CD7-09D1188072D1}.Debug|Any CPU.Build.0 = Debug|Any CPU 49 | {1001A958-40DB-4444-9CD7-09D1188072D1}.Release|Any CPU.ActiveCfg = Release|Any CPU 50 | {1001A958-40DB-4444-9CD7-09D1188072D1}.Release|Any CPU.Build.0 = Release|Any CPU 51 | {258307D5-A407-4622-BF1A-BDCA8E3D2FAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 52 | {258307D5-A407-4622-BF1A-BDCA8E3D2FAA}.Debug|Any CPU.Build.0 = Debug|Any CPU 53 | {258307D5-A407-4622-BF1A-BDCA8E3D2FAA}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {258307D5-A407-4622-BF1A-BDCA8E3D2FAA}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {57DABB69-B1D3-445F-91E7-B0412ABAC218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 56 | {57DABB69-B1D3-445F-91E7-B0412ABAC218}.Debug|Any CPU.Build.0 = Debug|Any CPU 57 | {57DABB69-B1D3-445F-91E7-B0412ABAC218}.Release|Any CPU.ActiveCfg = Release|Any CPU 58 | {57DABB69-B1D3-445F-91E7-B0412ABAC218}.Release|Any CPU.Build.0 = Release|Any CPU 59 | {029C010D-728B-4B87-B54A-08B2BBF49BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 60 | {029C010D-728B-4B87-B54A-08B2BBF49BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU 61 | {029C010D-728B-4B87-B54A-08B2BBF49BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU 62 | {029C010D-728B-4B87-B54A-08B2BBF49BD7}.Release|Any CPU.Build.0 = Release|Any CPU 63 | EndGlobalSection 64 | GlobalSection(SolutionProperties) = preSolution 65 | HideSolutionNode = FALSE 66 | EndGlobalSection 67 | GlobalSection(ExtensibilityGlobals) = postSolution 68 | SolutionGuid = {A28F1460-A9C1-44A4-A7C9-D8C210745F31} 69 | EndGlobalSection 70 | EndGlobal 71 | -------------------------------------------------------------------------------- /remoteapp-tool/RemoteApp Tool_TemporaryKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimmknight/remoteapptool/9c97cbde54af99026146341f083fcfe0750d0510/remoteapp-tool/RemoteApp Tool_TemporaryKey.pfx -------------------------------------------------------------------------------- /remoteapp-tool/RemoteAppAboutWindow.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | 4 | Public Class RemoteAppAboutWindow 5 | 6 | Private Sub RemoteAppAboutWindow_Load(sender As Object, e As EventArgs) Handles MyBase.Load 7 | Me.Text = "About " & My.Application.Info.Title 8 | Me.TitleLabel.Text = My.Application.Info.Title 9 | Me.VersionLabel.Text = "Version " & My.Application.Info.Version.ToString 10 | Me.CopyrightLabel.Text = My.Application.Info.CompanyName.ToString 11 | End Sub 12 | 13 | Private Sub SiteLinkLabel_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles SiteLinkLabel.LinkClicked 14 | System.Diagnostics.Process.Start(SiteLinkLabel.Text) 15 | End Sub 16 | 17 | Private Sub IconLibLinkLabel_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles IconLibLinkLabel.LinkClicked 18 | System.Diagnostics.Process.Start(IconLibLinkLabel.Text) 19 | End Sub 20 | 21 | End Class -------------------------------------------------------------------------------- /remoteapp-tool/RemoteAppFunctions.vb: -------------------------------------------------------------------------------- 1 | Imports System.Text.RegularExpressions 2 | 3 | Module RemoteAppFunction 4 | 5 | Public Sub ValidateInteger(TheTextBox As TextBox) 6 | Dim cloc = TheTextBox.SelectionStart 7 | TheTextBox.Text = Val(TheTextBox.Text) 8 | TheTextBox.Select(TheTextBox.Text.Length, 0) 9 | TheTextBox.Select(cloc, 0) 10 | End Sub 11 | 12 | Public Sub ValidatePort(TheTextBox As TextBox) 13 | Dim cloc = TheTextBox.SelectionStart 14 | If Val(TheTextBox.Text) > 65535 Then 15 | TheTextBox.Text = "65535" 16 | cloc = TheTextBox.Text.Length 17 | End If 18 | 19 | TheTextBox.Text = Val(TheTextBox.Text) 20 | TheTextBox.Select(TheTextBox.Text.Length, 0) 21 | TheTextBox.Select(cloc, 0) 22 | End Sub 23 | 24 | Public Sub ValidateSeconds(TheTextBox As TextBox) 25 | Dim cloc = TheTextBox.SelectionStart 26 | If Val(TheTextBox.Text) > 2147483 Then 27 | TheTextBox.Text = 2147483 28 | cloc = TheTextBox.Text.Length 29 | End If 30 | 31 | TheTextBox.Text = Val(TheTextBox.Text) 32 | TheTextBox.Select(TheTextBox.Text.Length, 0) 33 | TheTextBox.Select(cloc, 0) 34 | End Sub 35 | 36 | Public Sub ValidateAppName(TheTextBox As TextBox) 37 | ValidateTextBoxR(TheTextBox, "[^\p{L}0-9\-_"" ""]") 38 | End Sub 39 | 40 | Private Sub ValidateTextBoxR(TheTextBox As TextBox, regex As String) 41 | Dim cloc = TheTextBox.SelectionStart 42 | Dim rx As New Regex(regex) 43 | If (rx.IsMatch(TheTextBox.Text)) Then 44 | TheTextBox.Text = rx.Replace(TheTextBox.Text, "") 45 | TheTextBox.Select(cloc - 1, 0) 46 | Else 47 | TheTextBox.Select(cloc, 0) 48 | End If 49 | End Sub 50 | 51 | Public Function FixShortAppName(TheText As String) 52 | If TheText <> "" Then 53 | Dim rx As New Regex("[^\p{L}0-9\-_"" ""]") 54 | If (rx.IsMatch(TheText)) Then 55 | TheText = rx.Replace(TheText, "") 56 | End If 57 | End If 58 | TheText = TheText.Trim 59 | Return TheText 60 | End Function 61 | 62 | Public Sub ValidateDNSname(ByVal TheTextBox As TextBox) 63 | ' pattern matches any character that is NOT A-Z (allows upper and lower case alphabets) 64 | Dim rx As New Regex("[^\p{L}LlUu0-9\-\._:]") 65 | If (rx.IsMatch(TheTextBox.Text)) Then 66 | TheTextBox.Text = rx.Replace(TheTextBox.Text, "") 67 | TheTextBox.Select(TheTextBox.Text.Length, 0) 68 | End If 69 | End Sub 70 | 71 | Public Sub ValidateFileType(ByVal TheTextBox As TextBox) 72 | ' pattern matches any character that is NOT A-Z (allows upper and lower case alphabets) 73 | Dim rx As New Regex("[^\p{L}0-9\-_\!\@\#\$\%\^\&\(\)\{\}\[\]\+\=\;\,\']") 74 | If (rx.IsMatch(TheTextBox.Text)) Then 75 | TheTextBox.Text = rx.Replace(TheTextBox.Text, "") 76 | TheTextBox.Select(TheTextBox.Text.Length, 0) 77 | End If 78 | End Sub 79 | 80 | Public Function GetAppBitmap(RemoteAppShortName As String) 81 | On Error Resume Next 82 | Dim AppKey As String = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications" & "\" & RemoteAppShortName 83 | Dim TheRegKey = My.Computer.Registry.LocalMachine.OpenSubKey(AppKey) 84 | Dim TheIcon = ReturnIcon("", 0).ToBitmap 85 | If Not TheRegKey Is Nothing Then 86 | Dim IconPath = TheRegKey.GetValue("IconPath", "") 87 | Dim IconIndex = TheRegKey.GetValue("IconIndex", "") 88 | TheIcon = ReturnIcon(IconPath, IconIndex).ToBitmap 89 | End If 90 | Return TheIcon 91 | End Function 92 | 93 | Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long 94 | 95 | Public Function GetSysDir() As String 96 | Return Environment.SystemDirectory.ToString 97 | End Function 98 | 99 | Public Sub DeleteFiles(FilesArray As ArrayList) 100 | For Each dFile In FilesArray 101 | Dim LockCheck As New LockChecker.LockChecker() 102 | Dim FileLocked As String 103 | Dim SkipFile As Boolean = False 104 | FileLocked = LockCheck.CheckLock(dFile) 105 | While Not (FileLocked = "No locks") 106 | If (MessageBox.Show("The file " + dFile + " is currently locked. Lock information:" + FileLocked + vbNewLine + "Do you want to try again?", "File Locked", MessageBoxButtons.YesNo) = DialogResult.Yes) Then 107 | FileLocked = LockCheck.CheckLock(dFile) 108 | Else 109 | MessageBox.Show("The following file will not be deleted:" + vbNewLine + dFile) 110 | SkipFile = True 111 | FileLocked = "No locks" 112 | End If 113 | End While 114 | If Not (SkipFile) Then 115 | If My.Computer.FileSystem.FileExists(dFile) Then My.Computer.FileSystem.DeleteFile(dFile) 116 | End If 117 | 118 | Next 119 | End Sub 120 | 121 | Public Function GetEXETitle(exePath As String) 122 | Dim pname = System.Diagnostics.FileVersionInfo.GetVersionInfo(exePath).FileDescription 123 | If pname = "" Then pname = Left(My.Computer.FileSystem.GetFileInfo(exePath).Name, My.Computer.FileSystem.GetFileInfo(exePath).Name.Length - 4) 124 | 125 | Return pname 126 | End Function 127 | 128 | End Module 129 | -------------------------------------------------------------------------------- /remoteapp-tool/RemoteAppHostOptions.vb: -------------------------------------------------------------------------------- 1 | Public Class RemoteAppHostOptions 2 | 3 | Private Sub DisconnectTimeTextBox_TextChanged(sender As Object, e As EventArgs) Handles DisconnectTimeTextBox.TextChanged 4 | ValidateSeconds(Me.DisconnectTimeTextBox) 5 | End Sub 6 | 7 | Private Sub IdleTimeTextBox_TextChanged(sender As Object, e As EventArgs) Handles IdleTimeTextBox.TextChanged 8 | ValidateSeconds(Me.IdleTimeTextBox) 9 | End Sub 10 | 11 | Private Sub SaveButton_Click(sender As Object, e As EventArgs) Handles SaveButton.Click 12 | 13 | Dim PolicyKeyStringMS = "SOFTWARE\Policies\Microsoft" 14 | Dim PolicyKeyString = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" 15 | Dim PolicyKey As Microsoft.Win32.RegistryKey 16 | 17 | 'Create policy reg keys 18 | Dim PolicyKeyMS = My.Computer.Registry.LocalMachine.OpenSubKey(PolicyKeyStringMS, True) 19 | Dim PolicyKeyWNT = PolicyKeyMS.CreateSubKey("Windows NT") 20 | Dim PolicyKeyTS = PolicyKeyWNT.CreateSubKey("Terminal Services") 21 | 22 | PolicyKey = My.Computer.Registry.LocalMachine.OpenSubKey(PolicyKeyString, True) 23 | 24 | If Me.DisableAllowListCheckBox.Checked Then 25 | My.Computer.Registry.SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList", "fDisabledAllowList", "1", Microsoft.Win32.RegistryValueKind.DWord) 26 | Else 27 | My.Computer.Registry.SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList", "fDisabledAllowList", "0", Microsoft.Win32.RegistryValueKind.DWord) 28 | End If 29 | 30 | If Me.AllowUnlistedRemoteProgramsCheckBox.Checked Then 31 | PolicyKey.SetValue("fAllowUnlistedRemotePrograms", 1, Microsoft.Win32.RegistryValueKind.DWord) 32 | Else 33 | PolicyKey.DeleteValue("fAllowUnlistedRemotePrograms", False) 34 | End If 35 | 36 | If Me.TimeoutDisconnectedCheckBox.Checked Then 37 | PolicyKey.SetValue("MaxDisconnectionTime", Val(DisconnectTimeTextBox.Text) * 1000, Microsoft.Win32.RegistryValueKind.DWord) 38 | Else 39 | PolicyKey.DeleteValue("MaxDisconnectionTime", False) 40 | End If 41 | 42 | If Me.TimeoutIdleCheckBox.Checked Then 43 | PolicyKey.SetValue("MaxIdleTime", Val(IdleTimeTextBox.Text) * 1000, Microsoft.Win32.RegistryValueKind.DWord) 44 | Else 45 | PolicyKey.DeleteValue("MaxIdleTime", False) 46 | End If 47 | 48 | If Me.LogoffWhenTimoutCheckBox.Checked Then 49 | PolicyKey.SetValue("fResetBroken", "1", Microsoft.Win32.RegistryValueKind.DWord) 50 | Else 51 | PolicyKey.DeleteValue("fResetBroken", False) 52 | End If 53 | 54 | Me.Close() 55 | 56 | End Sub 57 | 58 | Public Sub SetValues() 59 | On Error Resume Next 60 | 61 | Dim PolicyKeyString = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" 62 | Dim PolicyKey = My.Computer.Registry.LocalMachine.OpenSubKey(PolicyKeyString, False) 63 | 64 | Me.DisconnectTimeTextBox.Text = "0" 65 | Me.IdleTimeTextBox.Text = "0" 66 | 67 | If Val(My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList", "fDisabledAllowList", "")) = 1 Then 68 | Me.DisableAllowListCheckBox.Checked = True 69 | Else 70 | Me.DisableAllowListCheckBox.Checked = False 71 | End If 72 | 73 | Dim MaxDisconnectionTime = -1 74 | MaxDisconnectionTime = PolicyKey.GetValue("MaxDisconnectionTime", -1) 75 | If Not MaxDisconnectionTime = -1 Then 76 | Me.TimeoutDisconnectedCheckBox.Checked = True 77 | Me.DisconnectTimeTextBox.Text = MaxDisconnectionTime / 1000 78 | Else 79 | Me.TimeoutDisconnectedCheckBox.Checked = False 80 | End If 81 | 82 | Dim MaxIdleTime = -1 83 | MaxIdleTime = PolicyKey.GetValue("MaxIdleTime", -1) 84 | If Not MaxIdleTime = -1 Then 85 | Me.TimeoutIdleCheckBox.Checked = True 86 | Me.IdleTimeTextBox.Text = MaxIdleTime / 1000 87 | Else 88 | Me.TimeoutIdleCheckBox.Checked = False 89 | End If 90 | 91 | Dim fResetBroken = PolicyKey.GetValue("fResetBroken") 92 | If Not fResetBroken = Nothing Then 93 | Me.LogoffWhenTimoutCheckBox.Checked = True 94 | Else 95 | Me.LogoffWhenTimoutCheckBox.Checked = False 96 | End If 97 | 98 | Dim fAllowUnlistedRemotePrograms = PolicyKey.GetValue("fAllowUnlistedRemotePrograms") 99 | If Not fAllowUnlistedRemotePrograms = Nothing Then 100 | Me.AllowUnlistedRemoteProgramsCheckBox.Checked = True 101 | Else 102 | Me.AllowUnlistedRemoteProgramsCheckBox.Checked = False 103 | End If 104 | 105 | If Me.TimeoutDisconnectedCheckBox.Checked = True Then 106 | Me.DisconnectTimeTextBox.Enabled = True 107 | Else 108 | Me.DisconnectTimeTextBox.Enabled = False 109 | End If 110 | 111 | If Me.TimeoutIdleCheckBox.Checked = True Then 112 | Me.IdleTimeTextBox.Enabled = True 113 | Else 114 | Me.IdleTimeTextBox.Enabled = False 115 | End If 116 | 117 | End Sub 118 | 119 | Private Sub TimeoutDisconnectedCheckBox_CheckedChanged(sender As Object, e As EventArgs) Handles TimeoutDisconnectedCheckBox.CheckedChanged 120 | If Me.TimeoutDisconnectedCheckBox.Checked = True Then 121 | Me.DisconnectTimeTextBox.Enabled = True 122 | Else 123 | Me.DisconnectTimeTextBox.Enabled = False 124 | End If 125 | End Sub 126 | 127 | Private Sub TimeoutIdleCheckBox_CheckedChanged(sender As Object, e As EventArgs) Handles TimeoutIdleCheckBox.CheckedChanged 128 | If Me.TimeoutIdleCheckBox.Checked = True Then 129 | Me.IdleTimeTextBox.Enabled = True 130 | Else 131 | Me.IdleTimeTextBox.Enabled = False 132 | End If 133 | End Sub 134 | 135 | Private Sub CancelEditButton_Click(sender As Object, e As EventArgs) Handles CancelEditButton.Click 136 | Me.Close() 137 | End Sub 138 | 139 | End Class -------------------------------------------------------------------------------- /remoteapp-tool/RemoteAppIconPicker.vb: -------------------------------------------------------------------------------- 1 | Public Class RemoteAppIconPicker 2 | 3 | Dim NoValidate As Boolean = False 4 | 5 | Public Function PickIcon(DefaultPath As String, Optional DefaultIndex As Integer = 0) As RemoteAppLib.IconSelection 6 | Me.FileTypeLabel.Visible = False 7 | Me.FileTypeTextBox.Visible = False 8 | Me.IconIndexLabel.Visible = False 9 | Me.IconIndexTextBox.Visible = False 10 | 11 | Me.Text = "Select Icon" 12 | 13 | Me.IconPathTextBox.Text = DefaultPath 14 | Me.IconIndexTextBox.Text = DefaultIndex.ToString 15 | 16 | LoadIcons() 17 | Dim IconPick As New RemoteAppLib.IconSelection 18 | 19 | If Me.ShowDialog() = Windows.Forms.DialogResult.OK Then 20 | IconPick.IconPath = Me.IconPathTextBox.Text 21 | IconPick.IconIndex = Me.IconIndexTextBox.Text 22 | End If 23 | 24 | Return IconPick 25 | 26 | Me.Dispose() 27 | 28 | End Function 29 | 30 | Public Function ManageFTA(DefaultPath As String, Optional DefaultIndex As Integer = 0, Optional FileType As String = ".xyz", Optional IsEdit As Boolean = False) As RemoteAppLib.FileTypeAssociation 31 | 32 | Dim FTA As New RemoteAppLib.FileTypeAssociation 33 | 34 | Me.FileTypeLabel.Visible = True 35 | Me.FileTypeTextBox.Visible = True 36 | Me.IconIndexLabel.Visible = True 37 | Me.IconIndexTextBox.Visible = True 38 | Me.IconIndexTextBox.ReadOnly = True 39 | 40 | If IsEdit = True Then 41 | FileTypeTextBox.ReadOnly = True 42 | Else 43 | FileTypeTextBox.ReadOnly = False 44 | End If 45 | 46 | Me.Text = "File Type" 47 | 48 | Me.FileTypeTextBox.Text = FileType 49 | Me.IconPathTextBox.Text = DefaultPath 50 | Me.IconIndexTextBox.Text = DefaultIndex 51 | 52 | LoadIcons() 53 | 54 | If Me.ShowDialog = Windows.Forms.DialogResult.OK Then 55 | FTA.Extension = Me.FileTypeTextBox.Text 56 | FTA.IconPath = Me.IconPathTextBox.Text 57 | FTA.IconIndex = Me.IconIndexTextBox.Text 58 | End If 59 | 60 | Me.Dispose() 61 | 62 | Return FTA 63 | 64 | End Function 65 | 66 | Private Function LoadIcons() As Boolean 67 | Me.IconList.Clear() 68 | Me.SmallIcons.Images.Clear() 69 | Dim IconError As Boolean = False 70 | 71 | Me.IconIndexLabel.Visible = True 72 | Me.IconIndexTextBox.Visible = True 73 | 74 | If My.Computer.FileSystem.FileExists(Me.IconPathTextBox.Text) Then 75 | Dim mIcon As New IconLib.MultiIcon 76 | Dim IconIndex As Integer = 0 77 | 78 | Try 79 | mIcon.Load(Me.IconPathTextBox.Text) 80 | Me.IconIndexTextBox.ReadOnly = True 81 | Catch Ex As Exception 82 | IconError = True 83 | NoValidate = True 84 | Me.OKButton.Enabled = True 85 | MessageBox.Show("There was an error loading icons from:" & vbCrLf & Me.IconPathTextBox.Text & vbCrLf & "Icons may still be usable, but you can not select one using the icon picker.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) 86 | Me.IconIndexTextBox.Text = "0" 87 | Me.IconIndexTextBox.ReadOnly = False 88 | End Try 89 | 90 | If Not IconError Then 91 | NoValidate = False 92 | For Each sIcon In mIcon 93 | Dim IconKey = IconIndex 94 | Dim IconItem As New ListViewItem(IconKey) 95 | Dim fiImage As IconLib.IconImage = sIcon.Item(0) 96 | For Each iImage In sIcon 97 | If iImage.Icon.Width = 32 Then 98 | Select Case iImage.ColorsInPalette 99 | Case 0 100 | fiImage = iImage 101 | Case Else 102 | If iImage.ColorsInPalette > fiImage.ColorsInPalette Then fiImage = iImage 103 | End Select 104 | If iImage.ColorsInPalette = 0 Then fiImage = iImage 105 | End If 106 | 107 | Next 108 | 109 | Dim TheBitmap = fiImage.Icon.ToBitmap 110 | 111 | Me.SmallIcons.Images.Add(IconKey, TheBitmap) 112 | IconItem.ImageKey = IconKey 113 | 114 | IconList.Items.Add(IconItem) 115 | IconIndex += 1 116 | Next 117 | If Not NoValidate Then Me.OKButton.Enabled = False 118 | End If 119 | End If 120 | Return IconError 121 | End Function 122 | 123 | Private Sub IconList_SelectedIndexChanged(sender As Object, e As EventArgs) Handles IconList.SelectedIndexChanged 124 | CheckSelection() 125 | End Sub 126 | 127 | Private Sub CheckSelection() 128 | If Me.IconList.SelectedItems.Count > 0 Then 129 | 'something is selected 130 | If Not FileTypeTextBox.Text = "" Then Me.OKButton.Enabled = True 131 | Me.IconIndexTextBox.Text = Me.IconList.SelectedItems(0).Text 132 | 133 | Else 134 | 'nothing is selected 135 | If Not NoValidate Then Me.OKButton.Enabled = False 136 | Me.IconIndexTextBox.Text = "0" 137 | End If 138 | End Sub 139 | 140 | Private Sub BrowseButton_Click(sender As Object, e As EventArgs) Handles BrowseButton.Click 141 | If My.Computer.FileSystem.FileExists(Me.IconPathTextBox.Text) Then _ 142 | Me.FileBrowserIcon.InitialDirectory = My.Computer.FileSystem.GetParentPath(Me.IconPathTextBox.Text) 143 | If FileBrowserIcon.ShowDialog() = Windows.Forms.DialogResult.OK Then 144 | Me.IconPathTextBox.Text = FileBrowserIcon.FileName 145 | LoadIcons() 146 | End If 147 | End Sub 148 | 149 | Private Sub FileTypeTextBox_TextChanged(sender As Object, e As EventArgs) Handles FileTypeTextBox.TextChanged 150 | ValidateFileType(FileTypeTextBox) 151 | If Me.FileTypeTextBox.Text = "" Then Me.OKButton.Enabled = False Else If Me.IconList.SelectedItems.Count = 1 Then Me.OKButton.Enabled = True 152 | End Sub 153 | 154 | Private Sub IconIndexTextBox_TextChanged(sender As Object, e As EventArgs) Handles IconIndexTextBox.TextChanged 155 | ValidateInteger(IconIndexTextBox) 156 | End Sub 157 | 158 | End Class -------------------------------------------------------------------------------- /remoteapp-tool/add-window.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimmknight/remoteapptool/9c97cbde54af99026146341f083fcfe0750d0510/remoteapp-tool/add-window.ico -------------------------------------------------------------------------------- /remoteapp-tool/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 52 | -------------------------------------------------------------------------------- /remoteapplib/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | -------------------------------------------------------------------------------- /remoteapplib/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /remoteapplib/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /remoteapplib/RemoteAppLib.vb: -------------------------------------------------------------------------------- 1 | Public Class RemoteAppCollection 2 | 3 | Inherits System.Collections.CollectionBase 4 | 5 | Public Sub Add(RemoteApp As RemoteApp) 6 | List.Add(RemoteApp) 7 | End Sub 8 | 9 | Public Sub Remove(RemoteApp As RemoteApp) 10 | List.Remove(RemoteApp) 11 | End Sub 12 | End Class 13 | 14 | Public Class RemoteApp 15 | 16 | Public Name As String 17 | Public FullName As String 18 | Public Path As String 19 | Public VPath As String 20 | Public IconPath As String 21 | Public IconIndex As Integer = 0 22 | Public CommandLine As String = "" 23 | Public CommandLineOption As Integer = 1 24 | Public TSWA As Boolean = False 25 | Public FileTypeAssociations As FileTypeAssociationCollection 26 | 27 | End Class 28 | 29 | Public Class FileTypeAssociation 30 | Public Extension As String 31 | Public IconPath As String 32 | Public IconIndex As String 33 | End Class 34 | 35 | Public Class FileTypeAssociationCollection 36 | Inherits System.Collections.CollectionBase 37 | 38 | Public Sub Add(FileTypeAssociation As FileTypeAssociation) 39 | List.Add(FileTypeAssociation) 40 | End Sub 41 | 42 | Public Sub Remove(FileTypeAssociation As FileTypeAssociation) 43 | List.Remove(FileTypeAssociation) 44 | End Sub 45 | 46 | Public Function GetFlatFileTypes() As String 47 | GetFlatFileTypes = "" 48 | If List.Count > 0 Then 49 | For Each listItem As FileTypeAssociation In List 50 | GetFlatFileTypes += ",." & listItem.Extension 51 | Next 52 | GetFlatFileTypes = GetFlatFileTypes.Substring(1) 53 | End If 54 | End Function 55 | End Class 56 | 57 | Public Class IconSelection 58 | Public IconPath As String 59 | Public IconIndex As String 60 | End Class 61 | 62 | 63 | Public Class SystemRemoteApps 64 | Private Legacy32bit As Boolean = False 65 | Private RegistryPath As String = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications" 66 | Private BaseKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(RegistryPath) 67 | Private BaseKeyWrite As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(RegistryPath, True) 68 | 69 | Public Sub Init() 70 | Dim RegistryPathCV As String = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\" 71 | Dim cvKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(RegistryPathCV, True) 72 | Dim tsKey As Microsoft.Win32.RegistryKey = cvKey.CreateSubKey("Terminal Server") 73 | Dim tsaaKey As Microsoft.Win32.RegistryKey = tsKey.CreateSubKey("TSAppAllowList") 74 | Dim appKey As Microsoft.Win32.RegistryKey = tsaaKey.CreateSubKey("Applications") 75 | End Sub 76 | 77 | Public Function GetAll() As RemoteAppCollection 78 | 79 | Dim SystemAppCollection As New RemoteAppCollection 80 | 81 | For Each App As String In BaseKey.GetSubKeyNames 82 | Dim RemoteApp As New RemoteApp 83 | RemoteApp = GetApp(App) 84 | SystemAppCollection.Add(RemoteApp) 85 | Next 86 | 87 | BaseKey.Close() 88 | 89 | Return SystemAppCollection 90 | 91 | End Function 92 | 93 | Function GetApp(Name As String) As RemoteApp 94 | Dim App As New RemoteApp 95 | 96 | Dim AppKey As Microsoft.Win32.RegistryKey = BaseKey.OpenSubKey(Name) 97 | 98 | If AppKey Is Nothing Then Return Nothing 99 | 100 | App.Name = Name 101 | App.FullName = AppKey.GetValue("Name", "") 102 | App.Path = AppKey.GetValue("Path", "") 103 | App.VPath = AppKey.GetValue("VPath", "") 104 | App.CommandLine = AppKey.GetValue("RequiredCommandLine", "") 105 | App.CommandLineOption = AppKey.GetValue("CommandLineSetting", "1") 106 | App.IconPath = AppKey.GetValue("IconPath", "") 107 | App.IconIndex = AppKey.GetValue("IconIndex", 0) 108 | App.TSWA = AppKey.GetValue("ShowInTSWA", 0) 109 | 110 | Dim FTAKey As Microsoft.Win32.RegistryKey = AppKey.OpenSubKey("Filetypes") 111 | If Not FTAKey Is Nothing Then 112 | Dim FTACol As New FileTypeAssociationCollection 113 | 114 | For Each FTAValueName As String In FTAKey.GetValueNames 115 | Dim FTA As New FileTypeAssociation 116 | Dim FTAValue = FTAKey.GetValue(FTAValueName).ToString.Split(",") 117 | FTA.Extension = FTAValueName 118 | FTA.IconPath = FTAValue(0) 119 | FTA.IconIndex = Val(FTAValue(1)) 120 | 121 | FTACol.Add(FTA) 122 | 123 | Next 124 | 125 | App.FileTypeAssociations = FTACol 126 | End If 127 | 128 | Return App 129 | 130 | End Function 131 | 132 | Public Sub SaveApp(RemoteApp As RemoteApp) 133 | BaseKeyWrite.CreateSubKey(RemoteApp.Name) 134 | 135 | Dim AppKey As Microsoft.Win32.RegistryKey = BaseKey.OpenSubKey(RemoteApp.Name, True) 136 | 137 | AppKey.SetValue("Name", RemoteApp.FullName, Microsoft.Win32.RegistryValueKind.String) 138 | 139 | AppKey.SetValue("Path", RemoteApp.Path, Microsoft.Win32.RegistryValueKind.String) 140 | AppKey.SetValue("VPath", RemoteApp.VPath, Microsoft.Win32.RegistryValueKind.String) 141 | AppKey.SetValue("RequiredCommandLine", RemoteApp.CommandLine, Microsoft.Win32.RegistryValueKind.String) 142 | AppKey.SetValue("CommandLineSetting", RemoteApp.CommandLineOption, Microsoft.Win32.RegistryValueKind.DWord) 143 | AppKey.SetValue("IconPath", RemoteApp.IconPath, Microsoft.Win32.RegistryValueKind.String) 144 | AppKey.SetValue("IconIndex", RemoteApp.IconIndex, Microsoft.Win32.RegistryValueKind.DWord) 145 | AppKey.SetValue("ShowInTSWA", RemoteApp.TSWA, Microsoft.Win32.RegistryValueKind.DWord) 146 | 147 | If Not RemoteApp.FileTypeAssociations Is Nothing Then 148 | If Not AppKey.OpenSubKey("Filetypes") Is Nothing Then AppKey.DeleteSubKeyTree("Filetypes") 149 | AppKey.CreateSubKey("Filetypes") 150 | Dim FTAKey = AppKey.OpenSubKey("Filetypes", True) 151 | For Each fta As FileTypeAssociation In RemoteApp.FileTypeAssociations 152 | FTAKey.SetValue(fta.Extension, fta.IconPath & "," & fta.IconIndex.ToString, Microsoft.Win32.RegistryValueKind.String) 153 | Next 154 | End If 155 | 156 | End Sub 157 | 158 | Public Sub DuplicateApp(Name As String) 159 | Dim NewApp = GetApp(Name) 160 | 161 | Dim NewName = NewApp.Name 162 | 163 | While GetApp(NewName) IsNot Nothing 164 | NewName = NewName & " copy" 165 | End While 166 | 167 | NewApp.Name = NewName 168 | 169 | SaveApp(NewApp) 170 | End Sub 171 | 172 | Public Sub RenameApp(RemoteAppOldName As String, RemoteAppNewName As String) 173 | Dim App As New RemoteApp 174 | Dim SystemApps As New SystemRemoteApps 175 | 176 | App = SystemApps.GetApp(RemoteAppOldName) 177 | DeleteApp(RemoteAppOldName) 178 | App.Name = RemoteAppNewName 179 | SaveApp(App) 180 | End Sub 181 | 182 | Public Sub DeleteApp(Name As String) 183 | BaseKeyWrite.DeleteSubKeyTree(Name) 184 | End Sub 185 | 186 | Public Property WoW6432Node As Boolean 187 | Get 188 | Return Legacy32bit 189 | End Get 190 | Set(value As Boolean) 191 | Legacy32bit = value 192 | Dim PathStart As String = "SOFTWARE" 193 | If Legacy32bit = True Then PathStart = "SOFTWARE\Wow6432Node" 194 | RegistryPath = PathStart & "\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications" 195 | End Set 196 | End Property 197 | 198 | End Class -------------------------------------------------------------------------------- /remoteapplib/RemoteAppLib.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {785B6808-B2FE-4C18-9D63-6DAB46482374} 8 | Library 9 | RemoteAppLib 10 | RemoteAppLib 11 | 512 12 | Empty 13 | v4.0 14 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | true 22 | true 23 | bin\Debug\ 24 | 25 | 26 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | false 32 | true 33 | true 34 | bin\Release\ 35 | 36 | 37 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 38 | 39 | 40 | On 41 | 42 | 43 | Binary 44 | 45 | 46 | Off 47 | 48 | 49 | On 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 80 | --------------------------------------------------------------------------------