 |
|
 |
An alternative way in vb.net (one third more compact + some minor changes):
Imports System.Security.Permissions Imports System.Security.AccessControl Imports System.IO
<RegistryPermission(Global.System.Security.Permissions.SecurityAction.Demand, Unrestricted:=True)> _ Public Class FileAssociator
#Region " Objects and variables "
Private m_Extension As String
Private Const strErrSingleAss As String = "The extension association key doesn't exist, use Create()." Private Const strErrMultiAss As String = "One of the association keys doesn't exist, use Create()." Private Const strErrProgID As String = "The extension's program association key ({0}) doesn't exist, use Create()." Private Const strDefIcon As String = "\DefaultIcon" Private Const strShellCommand As String = "\Shell\Open\Command" Private Const strOpenWith As String = "\OpenWithList"
#End Region
#Region " Properties "
Public ReadOnly Property Extension As String Get Return Me.m_Extension End Get End Property
Private ReadOnly Property ProgID() As String Get If KeyExists(Me.m_Extension, True) Then Return Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString End If Return String.Empty End Get End Property
Public ReadOnly Property Exists() As Boolean Get If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension) Is Nothing Then If Not Me.ProgID Is Nothing Then If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID) Is Nothing Then Return True End If End If End If Return False End Get End Property
Public Property ID() As String Get If Me.Exists Then If KeyExists(Me.m_Extension, False) Then Return Me.ProgID Else Throw New Exception(String.Format(strErrProgID, Me.ProgID)) End If Else Throw New Exception(strErrMultiAss) End If Return String.Empty End Get Set(ByVal value As String) If Me.Exists Then If KeyExists(Me.m_Extension, False) Then Dim beforeID As String = Me.ProgID
Registry.Util.RenameSubKey(Microsoft.Win32.Registry.ClassesRoot, beforeID, value) Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", value, Microsoft.Win32.RegistryValueKind.String) Else Throw New Exception(String.Format(strErrProgID, Me.ProgID)) End If Else Throw New Exception(strErrMultiAss) End If End Set End Property
Public Property Description() As String Get If Me.Exists Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID, True) Then Return Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString Else Throw New Exception(String.Format(strErrProgID, Me.ProgID)) End If Else Throw New Exception(strErrSingleAss) End If Else Throw New Exception(strErrMultiAss) End If Return String.Empty End Get Set(ByVal value As String) If Me.Exists Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID, False) Then Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", value, Microsoft.Win32.RegistryValueKind.String) Else Throw New Exception(String.Format(strErrProgID, Me.ProgID)) End If Else Throw New Exception(strErrSingleAss) End If Else Throw New Exception(strErrMultiAss) End If End Set End Property
Public Property DefaultIcon() As ProgramIcon Get If Me.Exists Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID, True) Then If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strDefIcon, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("") Is Nothing Then Return New ProgramIcon(Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strDefIcon, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString) End If Else Throw New Exception(String.Format(strErrProgID, strDefIcon)) End If Else Throw New Exception(strErrSingleAss) End If Else Throw New Exception(strErrMultiAss) End If Return Nothing End Get Set(ByVal value As ProgramIcon) If Me.Exists Then If value.IsValid Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID, False) Then Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strDefIcon, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", value.IconPath, Microsoft.Win32.RegistryValueKind.String) Else Throw New Exception(String.Format(strErrProgID, strDefIcon)) End If Else Throw New Exception(strErrSingleAss) End If Else 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.") End If Else Throw New Exception(strErrMultiAss) End If End Set End Property
Public Property Executable() As ExecApplication Get Dim execApp As ExecApplication = Nothing If Me.Exists Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID & strShellCommand, True) Then Dim strPath As String = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strShellCommand, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("").ToString execApp = New ExecApplication(strPath.Substring(0, (strPath.LastIndexOf(Microsoft.VisualBasic.ChrW(37)) - 1))) Else Throw New Exception(String.Format(strErrProgID, strShellCommand)) End If Else Throw New Exception(strErrSingleAss) End If Else Throw New Exception(strErrMultiAss) End If Return execApp End Get Set(ByVal value As ExecApplication) If Me.Exists Then If value.IsValid Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID & strShellCommand, False) Then Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strShellCommand, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).SetValue("", (value.Path + " %1"), Microsoft.Win32.RegistryValueKind.String) Else Throw New Exception(String.Format(strErrProgID, "Executable")) End If Else Throw New Exception(strErrSingleAss) End If Else 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.") End If Else Throw New Exception(strErrMultiAss) End If End Set End Property
Public Property OpenWith() As OpenWithList Get If Me.Exists Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID & strOpenWith, False) Then Dim list As New List(Of String) For Each file As String In Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.ProgID & strOpenWith, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetSubKeyNames list.Add(file) Next Return New OpenWithList(list) Else Throw New Exception(String.Format(strErrProgID, "Executable")) End If Else Throw New Exception(strErrSingleAss) End If Else Throw New Exception(strErrMultiAss) End If Return Nothing End Get Set(ByVal value As OpenWithList) If Me.Exists Then If KeyExists(Me.m_Extension, False) Then If KeyExists(Me.ProgID & strOpenWith, False) Then Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(Me.ProgID & strOpenWith) Dim key As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(Me.ProgID & strOpenWith, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree) For Each file As String In value.List key.CreateSubKey(file) Next key.Close() Else Throw New Exception(String.Format(strErrProgID, "Executable")) End If Else Throw New Exception(strErrSingleAss) End If Else Throw New Exception(strErrMultiAss) End If End Set End Property
#End Region
#Region " Public Methods and functions "
Public Sub Create(ByVal progID As String, ByVal description As String, ByVal defaultIcon As ProgramIcon, ByVal execApp As ExecApplication, ByVal openWith As OpenWithList)
If Not progID Is Nothing Then If (defaultIcon.IsValid AndAlso execApp.IsValid) Then Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree).SetValue("", progID) Dim key As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(progID, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree) If (Not (description) Is Nothing) Then key.SetValue("", description, Microsoft.Win32.RegistryValueKind.String) End If If ((Not defaultIcon Is Nothing) AndAlso defaultIcon.IsValid) Then key.CreateSubKey("DefaultIcon").SetValue("", defaultIcon.IconPath, Microsoft.Win32.RegistryValueKind.String) Else Throw New Exception("The default icon you entered is either null or doesn't exist...") End If If ((Not execApp Is Nothing) AndAlso execApp.IsValid) Then key.CreateSubKey("Shell\Open\Command").SetValue("", (execApp.Path & " ""%1"""), Microsoft.Win32.RegistryValueKind.String) Else Throw New Exception("The executable application you entered is either null or not an .exe format...") End If If Not openWith Is Nothing Then key = key.CreateSubKey("OpenWithList", Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree) For Each file As String In openWith.List key.CreateSubKey(file) Next End If key.Flush() key.Close() Else Throw New Exception("Either the icon or executable application object is invalid...") End If Else Throw New Exception("The program ID you entered is null...") End If
End Sub
Public Sub Delete()
If Me.Exists Then If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Me.m_Extension, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl) Is Nothing Then Try Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(Me.ProgID) Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(Me.m_Extension) Catch ex As Exception Throw New Exception("Failed to delete all keys used in the '" & Me.m_Extension & "' file association, error: " & ex.Message) End Try End If Else Throw New Exception("One of your association keys doesn't exist, use Create().") End If
End Sub
#End Region
#Region " Private Methods and functions "
Private Function KeyExists(ByVal key As String, ByVal checkValueSet As Boolean) As Boolean
If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(key, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl) Is Nothing Then If checkValueSet Then If Not Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(key, Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl).GetValue("") Is Nothing Then Return True End If Else Return True End If End If
Return False
End Function
#End Region
#Region " Construction "
Public Sub New(ByVal extension As String)
If Not String.IsNullOrEmpty(extension) Then Me.m_Extension = extension Else Throw New NullReferenceException("extension") End If
End Sub
#End Region
#Region " Classes "
Public Class ProgramIcon
Private m_IconPath As String
Public ReadOnly Property IconPath As String Get Return Me.m_IconPath End Get End Property
Public Sub New(ByVal iconPath As String)
Me.m_IconPath = iconPath.Trim
End Sub
Public ReadOnly Property IsValid() As Boolean Get Dim getInfo As FileInfo = New FileInfo(Me.m_IconPath)
If (getInfo.Exists AndAlso (getInfo.Extension = ".ico")) Then Return True Else Return False End If End Get End Property
End Class
Public Class OpenWithList
Private m_List As List(Of String)
Public ReadOnly Property List As List(Of String) Get If Me.m_List Is Nothing Then Me.m_List = New List(Of String) End If Return Me.m_List End Get End Property
Public Sub New(ByVal openWithPaths As List(Of String)) For Each file As String In openWithPaths Dim fInfo As New FileInfo(file) Me.List.Add(fInfo.Name) Next
End Sub
End Class
Public Class ExecApplication
Private m_Path As String
Public ReadOnly Property Path As String Get Return Me.m_Path End Get End Property
Public Sub New(ByVal appPath As String)
Me.m_Path = appPath.Trim
End Sub
Public ReadOnly Property IsValid() As Boolean Get Dim fInfo As FileInfo = New FileInfo(Me.m_Path)
If fInfo.Exists Then Return True Else Return False End If End Get End Property
End Class
#End Region
End Class
Michael Bakker
|
|
|
|
 |
|
 |
I have my visual Studio Project,
I added the using reference you noted above to my code,
I copied the DLL to my source location
In the project i then went Project -> Add Reference selected the browse tab and added the DLL to the project.
Upon compile i get this message...
'The type or namespace name 'AF_Lib' could not be found (are you missing a using directive or an assembly reference?)
-- Help!
Chris
|
|
|
|
 |
|
|
 |
|
 |
Hey,
It really does look very good and useful! =) Thanks for this!
Anthony
Check out my desktop conversion software for Windows - www.universalconverter.net
|
|
|
|
 |
|
 |
Thanks for the comment, no problem 
|
|
|
|
 |
|
 |
What does the openwithlist do? What happens if you specify more than one string here? What are they used for? You might want to elaborate on that in your article, because it's not obvious (not to me, anyway).
Normally, a file can be associated with a lot of different files and have different keywords, such as "Open", "Edit", "Print" etc. (These keywords show up in the context menu when you right click a file.
How do you do you associate the "Open" keyword with one program, and the "Edit" keyword with another program (e.g. NotePad)????
/Johnny J.
|
|
|
|
 |
|
 |
One more question:
What is the ID used for? Is it just to distinguish one association from another, and should it thus be unique? Or does it have any other purpose?
/Johnny J.
|
|
|
|
 |
|
 |
This library creates 2 registry keys, one for the extension and one for the program that uses the extension. The program's key contains stuff like the DefaultIcon and path to the program. The extension key's value contains the name of the program key, so that whenever a file with the association key is clicked, it opens the program it's associated to.
You can then use Enviroment.GetCommandLineArgs() (or the args[] argument of a Console application's Main method) to get the file clicked when the program starts up- windows sends the file as an argument.
|
|
|
|
 |
|
 |
In Windows, when you open a file that has no program association it's asks you if you want to choose a program from the list of default programs or browse for one.
The OpenWithList makes it so the program association(s) you set show up in that list.
|
|
|
|
 |
|