An alternative way in vb.net (one third more compact + some minor changes):
<br />
Imports System.Security.Permissions<br />
Imports System.Security.AccessControl<br />
Imports System.IO<br />
<br />
''' <summary><br />
'''Class for associating files with programs and icons.<br />
''' <example><code><br />
''' ' Initializes a new FileAssociator to associate the .ABC file extension.<br />
''' Dim assoc As FileAssociator = New FileAssociator(".abc")<br />
'''<br />
''' ' Creates a new file association for the .ABC file extension. Data is overwritten if it already exists.<br />
''' assoc.Create("SampleApp", "My application's file association", _ <br />
''' New ProgramIcon("C:\Program Files\SampleApp\icon.ico"), _ <br />
''' New ExecApplication("C:\Program Files\SampleApp\app.exe"), _ <br />
''' New OpenWithList(New string() { "SampleApp" }))<br />
''' </code></example><br />
''' </summary><br />
<RegistryPermission(Global.System.Security.Permissions.SecurityAction.Demand, Unrestricted:=True)> _<br />
Public Class FileAssociator<br />
<br />
#Region " Objects and variables "<br />
<br />
Private m_Extension As String<br />
<br />
Private Const strErrSingleAss As String = "The extension association key doesn't exist, use Create()."<br />
Private Const strErrMultiAss As String = "One of the association keys doesn't exist, use Create()."<br />
Private Const strErrProgID As String = "The extension's program association key ({0}) doesn't exist, use Create()."<br />
Private Const strDefIcon As String = "\DefaultIcon"<br />
Private Const strShellCommand As String = "\Shell\Open\Command"<br />
Private Const strOpenWith As String = "\OpenWithList"<br />
<br />
#End Region<br />
<br />
#Region " Properties "<br />
<br />
''' <summary><br />
''' Gets the extension set for this file associator to control when you initialized it.<br />
''' </summary><br />
Public ReadOnly Property Extension As String<br />
Get<br />
Return Me.m_Extension<br />
End Get<br />
End Property<br />
<br />
Private ReadOnly Property ProgID() As String<br />
Get<br />
If KeyExists(Me.m_Extension, True) Then<br />
Return Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString<br />
End If<br />
Return String.Empty<br />
End Get<br />
End Property<br />
<br />
''' <summary><br />
''' Gets a value indicating whether the association keys exist. If the extension key doesn't, the program cannot get the name of the program association key making it appear to not exist.<br />
''' </summary><br />
Public ReadOnly Property Exists() As Boolean<br />
Get<br />
If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension) Is Nothing Then<br />
If Not Me.ProgID Is Nothing Then<br />
If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID) Is Nothing Then<br />
Return True<br />
End If<br />
End If<br />
End If<br />
Return False<br />
End Get<br />
End Property<br />
<br />
''' <summary><br />
''' Gets or sets the program ID for this extension.<br />
''' </summary><br />
Public Property ID() As String<br />
Get<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
Return Me.ProgID<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, Me.ProgID))<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
Return String.Empty<br />
End Get<br />
Set(ByVal value As String)<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
Dim beforeID As String = Me.ProgID<br />
<br />
Registry.Util.RenameSubKey(Microsoft.Win32.Registry.ClassesRoot, beforeID, value)<br />
Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", value, Microsoft.Win32.RegistryValueKind.String)<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, Me.ProgID))<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
End Set<br />
End Property<br />
<br />
''' <summary><br />
''' Gets or sets the description for this file extension and/or it's program association.<br />
''' </summary><br />
Public Property Description() As String<br />
Get<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID, True) Then<br />
Return Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, Me.ProgID))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
Return String.Empty<br />
End Get<br />
Set(ByVal value As String)<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID, False) Then<br />
Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", value, Microsoft.Win32.RegistryValueKind.String)<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, Me.ProgID))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
End Set<br />
End Property<br />
<br />
''' <summary><br />
''' Gets or sets the icon shown on this file extension and/or it's program association.<br />
''' </summary><br />
Public Property DefaultIcon() As ProgramIcon<br />
Get<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID, True) Then<br />
If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strDefIcon, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("") Is Nothing Then<br />
Return New ProgramIcon(Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strDefIcon, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString)<br />
End If<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, strDefIcon))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
Return Nothing<br />
End Get<br />
Set(ByVal value As ProgramIcon)<br />
If Me.Exists Then<br />
If value.IsValid Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID, False) Then<br />
Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strDefIcon, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", value.IconPath, Microsoft.Win32.RegistryValueKind.String)<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, strDefIcon))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception("The value your trying to set to this DefaultIcon variable is not valid. The icon doesn't exist or it's not an .ico file.")<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
End Set<br />
End Property<br />
<br />
''' <summary><br />
''' Gets or sets the executable ran when this file extension is opened.<br />
''' </summary><br />
Public Property Executable() As ExecApplication<br />
Get<br />
Dim execApp As ExecApplication = Nothing<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID & strShellCommand, True) Then<br />
Dim strPath As String = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strShellCommand, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString<br />
execApp = New ExecApplication(strPath.Substring(0, (strPath.LastIndexOf(Microsoft.VisualBasic.ChrW(37)) - 1)))<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, strShellCommand))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
Return execApp<br />
End Get<br />
Set(ByVal value As ExecApplication)<br />
If Me.Exists Then<br />
If value.IsValid Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID & strShellCommand, False) Then<br />
Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strShellCommand, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", (value.Path + " %1"), Microsoft.Win32.RegistryValueKind.String)<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, "Executable"))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception("The value uses to set this variable isn't valid. The file doesn't exist or it's not an .exe file.")<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
End Set<br />
End Property<br />
<br />
''' <summary><br />
''' Gets or sets the list of programs shown in the OpenWith list.<br />
''' </summary><br />
Public Property OpenWith() As OpenWithList<br />
Get<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID & strOpenWith, False) Then<br />
Dim list As New List(Of String)<br />
For Each file As String In Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strOpenWith, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetSubKeyNames<br />
list.Add(file)<br />
Next<br />
Return New OpenWithList(list)<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, "Executable"))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
Return Nothing<br />
End Get<br />
Set(ByVal value As OpenWithList)<br />
If Me.Exists Then<br />
If KeyExists(Me.m_Extension, False) Then<br />
If KeyExists(Me.ProgID & strOpenWith, False) Then<br />
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(Me.ProgID & strOpenWith)<br />
Dim key As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(Me.ProgID & strOpenWith, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree)<br />
For Each file As String In value.List<br />
key.CreateSubKey(file)<br />
Next<br />
key.Close()<br />
Else<br />
Throw New Exception(String.Format(strErrProgID, "Executable"))<br />
End If<br />
Else<br />
Throw New Exception(strErrSingleAss)<br />
End If<br />
Else<br />
Throw New Exception(strErrMultiAss)<br />
End If<br />
End Set<br />
End Property<br />
<br />
#End Region<br />
<br />
#Region " Public Methods and functions "<br />
<br />
''' <summary><br />
''' Create or overwrite a current file association for this FileAssociator's set extension.<br />
''' </summary><br />
''' <param name="progID">The basic application name that uses this file extension.</param><br />
''' <param name="description">The desription of this file extension and/or program that uses it.</param><br />
''' <param name="defaultIcon">The icon to show on the program and it's files.</param><br />
''' <param name="execApp">The application that will be run when the file extension is clicked.</param><br />
''' <param name="openWith">The programs that appear in the OpenWith list.</param><br />
''' <exception cref="Exception">Thrown when an error occurs that will prevent it from working correctly.</exception><br />
Public Sub Create(ByVal progID As String, ByVal description As String, ByVal defaultIcon As ProgramIcon, ByVal execApp As ExecApplication, ByVal openWith As OpenWithList)<br />
<br />
If Not progID Is Nothing Then<br />
If (defaultIcon.IsValid AndAlso execApp.IsValid) Then<br />
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree).SetValue("", progID)<br />
Dim key As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(progID, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree)<br />
If (Not (description) Is Nothing) Then<br />
key.SetValue("", description, Microsoft.Win32.RegistryValueKind.String)<br />
End If<br />
If ((Not defaultIcon Is Nothing) AndAlso defaultIcon.IsValid) Then<br />
key.CreateSubKey("DefaultIcon").SetValue("", defaultIcon.IconPath, Microsoft.Win32.RegistryValueKind.String)<br />
Else<br />
Throw New Exception("The default icon you entered is either null or doesn't exist...")<br />
End If<br />
If ((Not execApp Is Nothing) AndAlso execApp.IsValid) Then<br />
key.CreateSubKey("Shell\Open\Command").SetValue("", (execApp.Path & " ""%1"""), Microsoft.Win32.RegistryValueKind.String)<br />
Else<br />
Throw New Exception("The executable application you entered is either null or not an .exe format...")<br />
End If<br />
If Not openWith Is Nothing Then<br />
key = key.CreateSubKey("OpenWithList", Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree)<br />
For Each file As String In openWith.List<br />
key.CreateSubKey(file)<br />
Next<br />
End If<br />
key.Flush()<br />
key.Close()<br />
Else<br />
Throw New Exception("Either the icon or executable application object is invalid...")<br />
End If<br />
Else<br />
Throw New Exception("The program ID you entered is null...")<br />
End If<br />
<br />
End Sub<br />
<br />
''' <summary><br />
''' Deletes all registry resources used for this file associations.<br />
''' </summary><br />
Public Sub Delete()<br />
<br />
If Me.Exists Then<br />
If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl) Is Nothing Then<br />
Try<br />
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(Me.ProgID)<br />
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(Me.m_Extension)<br />
Catch ex As Exception<br />
Throw New Exception("Failed to delete all keys used in the '" & Me.m_Extension & "' file association, error: " & ex.Message)<br />
End Try<br />
End If<br />
Else<br />
Throw New Exception("One of your association keys doesn't exist, use Create().")<br />
End If<br />
<br />
End Sub<br />
<br />
#End Region<br />
<br />
#Region " Private Methods and functions "<br />
<br />
Private Function KeyExists(ByVal key As String, ByVal checkValueSet As Boolean) As Boolean<br />
<br />
If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(key, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl) Is Nothing Then<br />
If checkValueSet Then<br />
If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(key, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("") Is Nothing Then<br />
Return True<br />
End If<br />
Else<br />
Return True<br />
End If<br />
End If<br />
<br />
Return False<br />
<br />
End Function<br />
<br />
#End Region<br />
<br />
#Region " Construction "<br />
<br />
''' <summary><br />
''' Initializes a new FileAssociator class object for the specified file extension.<br />
''' </summary><br />
''' <param name="extension">the file extension to control (such as .txt).</param><br />
Public Sub New(ByVal extension As String)<br />
<br />
If Not String.IsNullOrEmpty(extension) Then<br />
Me.m_Extension = extension<br />
Else<br />
Throw New NullReferenceException("extension")<br />
End If<br />
<br />
End Sub<br />
<br />
#End Region<br />
<br />
#Region " Classes "<br />
<br />
''' <summary><br />
''' Class that represents an .ico file used by FileAssociator.<br />
''' </summary><br />
Public Class ProgramIcon<br />
<br />
Private m_IconPath As String<br />
<br />
''' <summary><br />
''' Full path to the icon file.<br />
''' </summary><br />
''' <value>String</value><br />
''' <returns>String</returns><br />
Public ReadOnly Property IconPath As String<br />
Get<br />
Return Me.m_IconPath<br />
End Get<br />
End Property<br />
<br />
Public Sub New(ByVal iconPath As String)<br />
<br />
Me.m_IconPath = iconPath.Trim<br />
<br />
End Sub<br />
<br />
''' <summary><br />
''' Determines whether the given file exists ánd is an icon file.<br />
''' </summary><br />
''' <returns>Boolean</returns><br />
Public ReadOnly Property IsValid() As Boolean<br />
Get<br />
Dim getInfo As FileInfo = New FileInfo(Me.m_IconPath)<br />
<br />
If (getInfo.Exists AndAlso (getInfo.Extension = ".ico")) Then<br />
Return True<br />
Else<br />
Return False<br />
End If<br />
End Get<br />
End Property<br />
<br />
End Class<br />
<br />
''' <summary><br />
''' Class that represents a list of executable files used by FileAssociator.<br />
''' </summary><br />
Public Class OpenWithList<br />
<br />
Private m_List As List(Of String)<br />
<br />
''' <summary><br />
''' List of executable files.<br />
''' </summary><br />
''' <returns>List(Of String)</returns><br />
Public ReadOnly Property List As List(Of String)<br />
Get<br />
If Me.m_List Is Nothing Then<br />
Me.m_List = New List(Of String)<br />
End If<br />
Return Me.m_List<br />
End Get<br />
End Property<br />
<br />
Public Sub New(ByVal openWithPaths As List(Of String))<br />
<br />
For Each file As String In openWithPaths<br />
Dim fInfo As New FileInfo(file)<br />
Me.List.Add(fInfo.Name)<br />
Next<br />
<br />
End Sub<br />
<br />
End Class<br />
<br />
''' <summary><br />
''' Reference to an executable file used by FileAssociator.<br />
''' </summary><br />
Public Class ExecApplication<br />
<br />
Private m_Path As String<br />
<br />
''' <summary><br />
''' Full path to the executable file.<br />
''' </summary><br />
''' <returns>String</returns><br />
Public ReadOnly Property Path As String<br />
Get<br />
Return Me.m_Path<br />
End Get<br />
End Property<br />
<br />
Public Sub New(ByVal appPath As String)<br />
<br />
Me.m_Path = appPath.Trim<br />
<br />
End Sub<br />
<br />
''' <summary><br />
''' Gets a value indicating whether this Executable Application is an .exe, and that it exists.<br />
''' </summary><br />
Public ReadOnly Property IsValid() As Boolean<br />
Get<br />
Dim fInfo As FileInfo = New FileInfo(Me.m_Path)<br />
<br />
If fInfo.Exists Then<br />
Return True<br />
Else<br />
Return False<br />
End If<br />
End Get<br />
End Property<br />
<br />
End Class<br />
<br />
#End Region<br />
<br />
End Class<br />
Michael Bakker
|