 |
|
 |
I wrote this article a long time ago, and it's now out of date and seems messy and short of functionality now that I've been programming for even longer. However, I have no idea how to delete an article...
|
|
|
|
 |
|
 |
An alternative way in vb.net (one third more compact + some minor changes):
Imports System.Security.Permissions
Imports System.Security.AccessControl
Imports System.IO
''' <summary>
'''Class for associating files with programs and icons.
''' <example><code>
''' ' Initializes a new FileAssociator to associate the .ABC file extension.
''' Dim assoc As FileAssociator = New FileAssociator(".abc")
'''
''' ' Creates a new file association for the .ABC file extension. Data is overwritten if it already exists.
''' assoc.Create("SampleApp", "My application's file association", _
''' New ProgramIcon("C:\Program Files\SampleApp\icon.ico"), _
''' New ExecApplication("C:\Program Files\SampleApp\app.exe"), _
''' New OpenWithList(New string() { "SampleApp" }))
''' </code></example>
''' </summary>
<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 "
''' <summary>
''' Gets the extension set for this file associator to control when you initialized it.
''' </summary>
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
''' <summary>
''' 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.
''' </summary>
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
''' <summary>
''' Gets or sets the program ID for this extension.
''' </summary>
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
''' <summary>
''' Gets or sets the description for this file extension and/or it's program association.
''' </summary>
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
''' <summary>
''' Gets or sets the icon shown on this file extension and/or it's program association.
''' </summary>
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
''' <summary>
''' Gets or sets the executable ran when this file extension is opened.
''' </summary>
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
''' <summary>
''' Gets or sets the list of programs shown in the OpenWith list.
''' </summary>
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 "
''' <summary>
''' Create or overwrite a current file association for this FileAssociator's set extension.
''' </summary>
''' <param name="progID">The basic application name that uses this file extension.</param>
''' <param name="description">The desription of this file extension and/or program that uses it.</param>
''' <param name="defaultIcon">The icon to show on the program and it's files.</param>
''' <param name="execApp">The application that will be run when the file extension is clicked.</param>
''' <param name="openWith">The programs that appear in the OpenWith list.</param>
''' <exception cref="Exception">Thrown when an error occurs that will prevent it from working correctly.</exception>
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
''' <summary>
''' Deletes all registry resources used for this file associations.
''' </summary>
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 "
''' <summary>
''' Initializes a new FileAssociator class object for the specified file extension.
''' </summary>
''' <param name="extension">the file extension to control (such as .txt).</param>
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 "
''' <summary>
''' Class that represents an .ico file used by FileAssociator.
''' </summary>
Public Class ProgramIcon
Private m_IconPath As String
''' <summary>
''' Full path to the icon file.
''' </summary>
''' <value>String</value>
''' <returns>String</returns>
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
''' <summary>
''' Determines whether the given file exists ánd is an icon file.
''' </summary>
''' <returns>Boolean</returns>
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
''' <summary>
''' Class that represents a list of executable files used by FileAssociator.
''' </summary>
Public Class OpenWithList
Private m_List As List(Of String)
''' <summary>
''' List of executable files.
''' </summary>
''' <returns>List(Of String)</returns>
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
''' <summary>
''' Reference to an executable file used by FileAssociator.
''' </summary>
Public Class ExecApplication
Private m_Path As String
''' <summary>
''' Full path to the executable file.
''' </summary>
''' <returns>String</returns>
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
''' <summary>
''' Gets a value indicating whether this Executable Application is an .exe, and that it exists.
''' </summary>
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
|
|
|
|
 |
|
 |
try adding,
using AF_Lib; on top of the code
|
|
|
|
 |
|
|
 |
|
 |
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.
|
|
|
|
 |
|