Initial commit

This commit is contained in:
Kim
2019-09-29 22:45:23 +10:00
commit f1f7664b91
82 changed files with 53821 additions and 0 deletions

2
RDP2MSILib/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
bin/
obj/

View File

@@ -0,0 +1,13 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,35 @@
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' General Information about an assembly is controlled through the following
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
' Review the values of the assembly attributes
<Assembly: AssemblyTitle("RDP2MSIlib")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("RDP2MSIlib")>
<Assembly: AssemblyCopyright("Copyright © 2016")>
<Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)>
'The following GUID is for the ID of the typelib if this project is exposed to COM
<Assembly: Guid("af9953ef-de9f-4f06-a876-91395e89bfd1")>
' Version information for an assembly consists of the following four values:
'
' Major Version
' Minor Version
' Build Number
' Revision
'
' You can specify all the values or you can default the Build and Revision Numbers
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.0")>
<Assembly: AssemblyFileVersion("1.0.0.0")>

View File

@@ -0,0 +1,63 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'This class was auto-generated by the StronglyTypedResourceBuilder
'class via a tool like ResGen or Visual Studio.
'To add or remove a member, edit your .ResX file then rerun ResGen
'with the /str option, or rebuild your VS project.
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RDP2MSIlib.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
End Module
End Namespace

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,73 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.RDP2MSIlib.My.MySettings
Get
Return Global.RDP2MSIlib.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

364
RDP2MSILib/RDP2MSILib.vb Normal file
View File

@@ -0,0 +1,364 @@
Imports System.Reflection.Assembly
Public Class RDP
Private rdpFilePath As String
Public Property rdpPath As String
Get
Return rdpFilePath
End Get
Set(value As String)
rdpFilePath = value
ReadRDPfile()
End Set
End Property
Private ProductName As String ' Full remoteapp name as read from RDP file
Public FlatFileTypes As String = ""
Public PerUser As Boolean = False
Private ProductBaseFileName As String ' RDP filename minus the file extension
Public ProductPublisher As String
Public ProductVersion As String = "1.0.0.0"
Public ProductUpgradeRandom As Boolean = False
Public ProductRemoteTag As String = "remote"
Public ShortcutInStart As Boolean = True
Public ShortcutSubfolderInStart As Boolean = True
Public ShortcutOnDesktop As Boolean = True
Private rdpFileContents As String
Private hasIcon As Boolean
Private rdpInTemp As Boolean
Public Sub CreateMSI(Optional DestinationPath As String = "")
'Check for wix, exit if not available
If Not WixInstalled() Then Exit Sub
'Get RDP file parent folder path
Dim rdpParentFolder = My.Computer.FileSystem.GetParentPath(rdpFilePath)
'Get the RDP filename and filename minus extension
Dim rdpFileName = My.Computer.FileSystem.GetFileInfo(rdpFilePath).Name
ProductBaseFileName = System.IO.Path.GetFileNameWithoutExtension(rdpFileName)
'If DestinationPath not defined then set the path to the same as the rdp file
If DestinationPath = "" Then DestinationPath = rdpParentFolder & "\" & ProductBaseFileName & ".msi"
'Set iconpath (whether it exists or not)
Dim IconFilePath = rdpParentFolder & "\" & ProductBaseFileName & ".ico"
'Check for icon, set "HasIcon" to true if found
hasIcon = My.Computer.FileSystem.FileExists(IconFilePath)
'Get RemoteApp names (short and full) from RDP file contents
Dim RemoteAppFullName = ReadRDPProperty("remoteapplicationname")
Dim RemoteAppShortName = ReadRDPProperty("remoteapplicationprogram")
'Define wix temp file paths
Dim TempPath = Environment.GetEnvironmentVariable("TEMP")
Dim wxsPath = TempPath & "\" & ProductBaseFileName & ".wxs"
Dim wixobjPath = TempPath & "\" & ProductBaseFileName & ".wixobj"
Dim wixpdbPath = TempPath & "\" & ProductBaseFileName & ".wixpdb"
Dim msiPath = TempPath & "\" & ProductBaseFileName & ".msi"
Dim rdpTempPath = TempPath & "\" & ProductBaseFileName & ".rdp"
Dim icoTempPath = TempPath & "\" & ProductBaseFileName & ".ico"
'Define temp files to delete
Dim FilesToDelete As List(Of String) = New List(Of String)(New String() {wxsPath, wixobjPath, wixpdbPath})
'Check if rdp file is already in TEMP folder
If rdpParentFolder = TempPath Then rdpInTemp = True
'if RDP file not in temp, copy to temp
If Not rdpInTemp Then
My.Computer.FileSystem.CopyFile(rdpFilePath, rdpTempPath, True)
FilesToDelete.Add(rdpTempPath)
If hasIcon Then
My.Computer.FileSystem.CopyFile(IconFilePath, icoTempPath, True)
FilesToDelete.Add(icoTempPath)
End If
End If
'Save WXS file containing generated WXS string
My.Computer.FileSystem.WriteAllText(wxsPath, GenerateWXSString(), False)
Dim CandlePath = WixPath() & "\candle.exe "
Dim LightPath = WixPath() & "\light.exe "
'Run Candle.exe and Light.exe to process wxs file
Dim CandleExitCode = RunWait(CandlePath, "-out """ & wixobjPath & """ """ & wxsPath & """")
'If Not CandleExitCode = 0 Then Exit Sub
Dim LightExitCode = RunWait(LightPath, "-out """ & msiPath & """ """ & wixobjPath & """")
'If Not LightExitCode = 0 Then Exit Sub
'Move MSI file to destination and delete temp files
My.Computer.FileSystem.MoveFile(msiPath, DestinationPath, True)
DeleteFiles(FilesToDelete)
End Sub
Public Function WixInstalled() As Boolean
If WixPath() = "" Then
WixInstalled = False
Else
WixInstalled = True
End If
End Function
Private Function WixPath()
Dim searchExe = "\candle.exe"
WixPath = ""
If Not Environment.GetEnvironmentVariable("WIX") = "" Then
WixPath = Environment.GetEnvironmentVariable("WIX") & "bin"
ElseIf My.Computer.FileSystem.DirectoryExists(My.Application.Info.DirectoryPath & "\wix\" & searchExe) Then
WixPath = My.Application.Info.DirectoryPath & "\wix"
ElseIf My.Computer.FileSystem.DirectoryExists(My.Application.Info.DirectoryPath & "\wix\bin\" & searchExe) Then
WixPath = My.Application.Info.DirectoryPath & "\wix\bin"
End If
End Function
Private Sub DeleteFiles(FilesArray As List(Of String))
For Each dFile In FilesArray
If My.Computer.FileSystem.FileExists(dFile) Then My.Computer.FileSystem.DeleteFile(dFile)
Next
End Sub
Private Sub ReadRDPfile()
'Check if RDP file exists
If Not My.Computer.FileSystem.FileExists(rdpFilePath) Then Exit Sub
'Check that RDP file is an RDP file
If Not rdpFilePath.ToLower.EndsWith(".rdp") Then Exit Sub
'Read RDP file into variable
rdpFileContents = My.Computer.FileSystem.ReadAllText(rdpFilePath)
'Check RDP file contains a remoteapplicationname value
'If ReadRDPProperty("remoteapplicationname") = "" Then Exit Sub
'Check if RDP file contains a server address
If ReadRDPProperty("full address") = "" Then Exit Sub
'Read variables
ProductName = ReadRDPProperty("remoteapplicationname")
If ProductName = "" Then
ProductName = System.IO.Path.GetFileNameWithoutExtension(rdpFilePath)
End If
If ProductPublisher Is Nothing Then ProductPublisher = ProductName
End Sub
Public Function ProductUpgradeCode()
' random or generated - maybe allow caller to define?
Dim UpgradeCode As String
'Check if ProductUpgradeRandom is true, create a random productcode if so, otherwise generate it from the productname
If Not ProductUpgradeRandom Then
UpgradeCode = GenerateGUIDfromString(ProductName)
Else
Dim Rnd = New Random()
UpgradeCode = GenerateGUIDfromString(Rnd.Next)
End If
Return UpgradeCode
End Function
Public Function MakeProgID(AppName) As String
Dim rx As New System.Text.RegularExpressions.Regex("[^a-zA-Z0-9_]")
MakeProgID = rx.Replace(AppName, "_")
End Function
Private Function GenerateWXSString()
Dim Rnd = New Random()
If ProductPublisher = "" Then ProductPublisher = ProductName
Dim RegRoot = "HKLM"
If PerUser = True Then RegRoot = "HKCU"
Dim AppFilesGuid = GenerateGUIDfromString("AppFiles" & ProductUpgradeCode())
Dim AppStartShortcutsGuid = GenerateGUIDfromString("AppStartShortcuts" & ProductUpgradeCode())
Dim AppDeskShortcutsGuid = GenerateGUIDfromString("AppDeskShortcuts" & ProductUpgradeCode())
Dim ProgID As String = MakeProgID(ProductBaseFileName)
Dim wxsString = "<?xml version=""1.0""?>" & vbCrLf
wxsString += "<?define ProductVersion = """ & ProductVersion & """?>" & vbCrLf
wxsString += "<?define ProductUpgradeCode = """ & ProductUpgradeCode() & """?>" & vbCrLf
wxsString += "<?define AppFilesGuid = """ & AppFilesGuid & """?>" & vbCrLf
wxsString += "<?define AppStartShortcutsGuid = """ & AppStartShortcutsGuid & """?>" & vbCrLf
wxsString += "<?define AppDeskShortcutsGuid = """ & AppDeskShortcutsGuid & """?>" & vbCrLf
wxsString += "<?define ProductName = """ & ProductName & """?>" & vbCrLf
wxsString += "<?define ProductPublisher = """ & ProductPublisher & """?>" & vbCrLf
wxsString += "<?define ProductBaseFileName = """ & ProductBaseFileName & """?>" & vbCrLf
wxsString += "<?define RegRoot = """ & RegRoot & """?>" & vbCrLf
If Not FlatFileTypes = "" Then wxsString += "<?define ProductProgID = """ & ProgID & """?>" & vbCrLf
If Not ProductRemoteTag = "" Then ProductRemoteTag = " (" & ProductRemoteTag & ")"
wxsString += "<?define ProductRemoteTag = """ & ProductRemoteTag & """?>" & vbCrLf
wxsString += "<Wix xmlns=""http://schemas.microsoft.com/wix/2006/wi"">" & vbCrLf
wxsString += " <Product Id=""*"" UpgradeCode=""$(var.ProductUpgradeCode)"" " & vbCrLf
wxsString += " Name=""$(var.ProductName)$(var.ProductRemoteTag)"" Version=""$(var.ProductVersion)"" Manufacturer=""$(var.ProductPublisher)"" Language=""1033"">" & vbCrLf
wxsString += " <Package InstallerVersion=""200"" Compressed=""yes"" Comments=""Windows Installer Package"""
If Not PerUser Then
wxsString += " InstallScope=""perMachine"""
Else
wxsString += " InstallPrivileges=""limited"""
End If
wxsString += "/>" & vbCrLf
wxsString += " <Media Id=""1"" Cabinet=""rdp2msi.cab"" EmbedCab=""yes""/>" & vbCrLf
If Not PerUser Then wxsString += " <Property Id=""AllUSERS"" Value=""1""/>" & vbCrLf
wxsString += " <Upgrade Id=""$(var.ProductUpgradeCode)"">" & vbCrLf
wxsString += " <UpgradeVersion Minimum=""$(var.ProductVersion)"" OnlyDetect=""yes"" Property=""NEWERVERSIONDETECTED""/>" & vbCrLf
wxsString += " <UpgradeVersion Minimum=""0.0.0"" Maximum=""$(var.ProductVersion)"" IncludeMinimum=""yes"" IncludeMaximum=""no"" " & vbCrLf
wxsString += " Property=""OLDERVERSIONBEINGUPGRADED""/> " & vbCrLf
wxsString += " </Upgrade>" & vbCrLf
wxsString += " <Condition Message=""A newer version of this software is already installed."">NOT NEWERVERSIONDETECTED</Condition>" & vbCrLf
wxsString += " <Property Id=""MstscProperty"" Value=""mstsc.exe""/>" & vbCrLf
wxsString += " <Directory Id=""TARGETDIR"" Name=""SourceDir"">" & vbCrLf
If Not PerUser Then
wxsString += " <Directory Id=""ProgramFilesFolder"">" & vbCrLf
Else
wxsString += " <Directory Id=""LocalAppDataFolder"">" & vbCrLf
End If
wxsString += " <Directory Id=""INSTALLDIR"" Name=""RemotePackages"">" & vbCrLf
wxsString += " <Component Id=""ApplicationFiles"" Guid=""$(var.AppFilesGuid)"">" & vbCrLf
wxsString += " <File Id=""rdpFile1"" Source=""$(var.ProductBaseFileName).rdp""/>" & vbCrLf
If hasIcon Then wxsString += " <File Id=""rdpIcon1"" Source=""$(var.ProductBaseFileName).ico""/>" & vbCrLf
'# Begin filetype association code
If Not FlatFileTypes = "" Then
For Each FileType In FlatFileTypes.Replace(".", "").Split(",")
wxsString += " <File Id=""$(var.ProductProgID)." & FileType & ".ico"" Source=""$(var.ProductBaseFileName)." & FileType & ".ico"" />" & vbCrLf
wxsString += " <ProgId Id=""remote.$(var.ProductProgID)." & FileType & "file"" Description=""$(var.ProductName) " & FileType & " file"" Icon=""$(var.ProductProgID)." & FileType & ".ico"">" & vbCrLf
wxsString += " <Extension Id=""" & FileType & """ ContentType=""application/" & FileType & """>" & vbCrLf
wxsString += " <Verb Id=""open"" Command=""Open"" TargetProperty='MstscProperty' Argument='/REMOTEFILE:""%1"" ""[INSTALLDIR]$(var.ProductBaseFileName).rdp""' />" & vbCrLf
wxsString += " </Extension>" & vbCrLf
wxsString += " </ProgId>" & vbCrLf
'wxsString += " <RegistryValue Root=""$(var.RegRoot)"" Key=""SOFTWARE\Classes\remote.$(var.ProductProgID)." & FileType & "file"" Name=""FriendlyTypeName"" Value=""$(var.ProductName) " & FileType & " file"" Type=""string"" />"
Next
End If
'# End FTA code
wxsString += " </Component>" & vbCrLf
wxsString += " </Directory>" & vbCrLf
wxsString += " </Directory>" & vbCrLf
If ShortcutInStart Then
wxsString += " <Directory Id=""ProgramMenuFolder"">" & vbCrLf
If ShortcutSubfolderInStart Then wxsString += " <Directory Id=""ProgramMenuSubfolder"" Name=""$(var.ProductName)$(var.ProductRemoteTag)"">" & vbCrLf
wxsString += " <Component Id=""ApplicationStartShortcuts"" Guid=""$(var.AppStartShortcutsGuid)"">" & vbCrLf
wxsString += " <Shortcut Id=""rdpStartShortcut1"" Name=""$(var.ProductName)$(var.ProductRemoteTag)"" Description=""$(var.ProductName)$(var.ProductRemoteTag)"" " & vbCrLf
wxsString += " Target=""[INSTALLDIR]$(var.ProductBaseFileName).rdp"" WorkingDirectory=""INSTALLDIR"""
If hasIcon Then
wxsString += " Icon=""rdpStartIcon.rdp"" IconIndex=""0"">" & vbCrLf
wxsString += " <Icon Id=""rdpStartIcon.rdp"" SourceFile=""$(var.ProductBaseFileName).ico"" />" & vbCrLf
wxsString += " </Shortcut>" & vbCrLf
Else
wxsString += "/>" & vbCrLf
End If
wxsString += " <RegistryValue Root=""$(var.RegRoot)"" Key=""Software\RDP2MSI\$(var.ProductName)"" " & vbCrLf
wxsString += " Name=""installed"" Type=""integer"" Value=""1"" KeyPath=""yes""/>" & vbCrLf
wxsString += " <RemoveFolder Id=""ProgramMenuSubfolder"" On=""uninstall""/>" & vbCrLf
wxsString += " </Component>" & vbCrLf
If ShortcutSubfolderInStart Then wxsString += " </Directory>" & vbCrLf
wxsString += " </Directory>" & vbCrLf
End If
If ShortcutOnDesktop Then
wxsString += " <Directory Id=""DesktopFolder"">" & vbCrLf
wxsString += " <Component Id=""ApplicationDesktopShortcuts"" Guid=""$(var.AppDeskShortcutsGuid)"">" & vbCrLf
wxsString += " <Shortcut Id=""rdpDesktopShortcut1"" Name=""$(var.ProductName)$(var.ProductRemoteTag)"" Description=""$(var.ProductName)$(var.ProductRemoteTag)"" " & vbCrLf
wxsString += " Target=""[INSTALLDIR]$(var.ProductBaseFileName).rdp"" WorkingDirectory=""INSTALLDIR"""
If hasIcon Then
wxsString += " Icon=""rdpDeskIcon.rdp"" IconIndex=""0"">" & vbCrLf
wxsString += " <Icon Id=""rdpDeskIcon.rdp"" SourceFile=""$(var.ProductBaseFileName).ico"" />" & vbCrLf
wxsString += " </Shortcut>" & vbCrLf
Else
wxsString += "/>" & vbCrLf
End If
wxsString += " <RegistryValue Root=""$(var.RegRoot)"" Key=""Software\RDP2MSI\$(var.ProductName)"" " & vbCrLf
wxsString += " Name=""installed"" Type=""integer"" Value=""1"" KeyPath=""yes""/>" & vbCrLf
wxsString += " </Component>" & vbCrLf
wxsString += " </Directory>" & vbCrLf
End If
wxsString += " </Directory>" & vbCrLf
wxsString += " <InstallExecuteSequence>" & vbCrLf
wxsString += " <RemoveExistingProducts After=""InstallValidate""/>" & vbCrLf
wxsString += " </InstallExecuteSequence>" & vbCrLf
wxsString += " "
wxsString += " <Feature Id=""DefaultFeature"" Level=""1"">" & vbCrLf
wxsString += " <ComponentRef Id=""ApplicationFiles""/>" & vbCrLf
If ShortcutInStart Then wxsString += " <ComponentRef Id=""ApplicationStartShortcuts""/>" & vbCrLf
If ShortcutOnDesktop Then wxsString += " <ComponentRef Id=""ApplicationDesktopShortcuts""/>" & vbCrLf
wxsString += " </Feature>" & vbCrLf
If hasIcon Then
wxsString += "<Icon Id=""rdpARPIcon.rdp"" SourceFile=""$(var.ProductBaseFileName).ico"" />" & vbCrLf
wxsString += "<Property Id=""ARPPRODUCTICON"" Value=""rdpARPIcon.rdp"" />" & vbCrLf
End If
wxsString += " </Product>" & vbCrLf
wxsString += "</Wix>" & vbCrLf
Return wxsString
End Function
Public Function ReadRDPProperty(rdpProperty As String) As String
Dim rdpFileLines = Split(rdpFileContents, vbLf)
Dim rdpValue = ""
For Each rdpLine In rdpFileLines
rdpLine = Replace(rdpLine, vbCr, "")
rdpLine = Replace(rdpLine, "|", "")
Dim rdpLineSplit = Split(rdpLine, ":", 3)
If rdpLineSplit(0) = rdpProperty Then
rdpValue = rdpLineSplit(2)
End If
Next
Return rdpValue
End Function
Private Function GenerateGUIDfromString(TheString As String)
Dim TheHash = getMD5Hash(TheString)
Dim MyGuid As Guid = New Guid(TheHash)
Return MyGuid.ToString
End Function
Private Function getMD5Hash(ByVal strToHash As String) As String
Dim md5Obj As New System.Security.Cryptography.MD5CryptoServiceProvider()
Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
bytesToHash = md5Obj.ComputeHash(bytesToHash)
Dim strResult As String = ""
Dim b As Byte
For Each b In bytesToHash
strResult += b.ToString("x2")
Next
Return strResult
End Function
Private Function RunWait(App As String, Parameters As String) As Integer
Dim proc As New Process
proc.StartInfo.CreateNoWindow = True
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo.FileName = App
proc.StartInfo.Arguments = Parameters
proc.Start()
proc.WaitForExit()
Return proc.ExitCode
End Function
End Class

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E1CB5F9C-230F-4967-8F19-335F8E4A4906}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>RDP2MSIlib</RootNamespace>
<AssemblyName>RDP2MSIlib</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>RDP2MSIlib.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>RDP2MSIlib.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="RDP2MSILib.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>