The Wayback Machine - https://web.archive.org/web/20090220172338/http://www.codeproject.com:80/KB/vb/VBFileAssociation.aspx
Click here to Skip to main content
5,908,898 members and growing! (15,226 online)
Languages » VB.NET » General     Intermediate License: The Common Development and Distribution License (CDDL)

File Association in VB.NET

By Nickr5

Easily associate your programs with file types (.jpg, .html, .mp3) with just 2 lines of Visual Basic code.
VB 8.0, VB 9.0, VBWindows, .NET, .NET 3.0, .NET 2.0, WinXP, Vista, WinForms, VS2005, Visual Studio, Dev
Version:2
Posted:29 Apr 2007
Updated:3 Feb 2009
Views:56,437
Bookmarked:65 times
Unedited contribution
Announcements
Loading...



Advanced Search
Sitemap
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
16 votes for this Article.
Popularity: 4.40 Rating: 3.65 out of 5
1 vote, 6.3%
1
3 votes, 18.8%
2
1 vote, 6.3%
3
4 votes, 25.0%
4
7 votes, 43.8%
5

Screenshot - VBFileAssociation1.gif

Introduction

There are many features that every commercial application has, but aren't easy to implement, or find out how to implement, for many people.
Look at Undo/Redo, the Office 2007 Ribbon Bar, spell check, associated file types, and lot's of other small, but powerful features.

While many of these aren't actually hard to program, it can be difficult to find out exactly how. More specifically, this article is on how to link a file extension
(or two, three, four, or five...) to your program and have your application display the appropriate content according to the file.

Background

Take a second to open up Windows Explorer. See all the different types of files (jpg, gif, png, txt, html, etc)? Each one has a different icon and opens with
a certain application when you double click on it. Take a guess, how many lines of code does it take to link your application and an extension? 10? 20? 30?

The answer is 2. Just 2 will do it!

How are programs associated?

The registry stores all the file type-app associations. Click on the Start Menu > Run > Type in 'regedit' > Ok.
Now expand the HKEY_CLASSES_ROOT node. At the top of the window are all the extensions that your computer recognizes. Scroll down to .txt and click on it.
Now look at the default value, it probably is 'txtfile'. Scrolling down the tree on the left, find the txtfile node. This contains all the information about
any extensions that have their default value set to txtfile. Right now, we're just interested in opening the file, so open Shell > Open > Command.
If your .txt files open with notepad, then the default value should be "%SystemRoot%\system32\NOTEPAD.EXE %1".
%SystemRoot% is pretty self-explanatory, it's replaced by the folder that contains system32, which contains NOTEPAD.EXE.
%1 is a command-line argument to pass the the program when a txtfile is opened. %1 is replaced by the file's location.

Step 1: Running your Program when a .Hello File is Opened

The first step is to get your application to open when a chosen extension (like .mp3) is double clicked in Windows Explorer.
For this article, we'll use a file extension that shouldn't exist: .Hello. To use this file type, create a new project called 'Hello World'.
The basic idea is this: a .Hello file contains (in plain text) an adjective. When one is opened, a message box will pop-up and say, "Hello, (file contents) World".
If you open the application manually, it will just say, "Hello, World".

Now we have to edit the registry just like you saw with the .txt extension. In the forms Load event, type the following:

  My.Computer.Registry.ClassesRoot.CreateSubKey(".Hello").SetValue("", "Hello", Microsoft.Win32.RegistryValueKind.String)
  My.Computer.Registry.ClassesRoot.CreateSubKey("Hello\shell\open\command").SetValue("", Application.ExecutablePath & _
  " ""%l"" ", Microsoft.Win32.RegistryValueKind.String)

What does all this do? If you don't understand My.Computer.Registry, here's a link to it on MSDN, otherwise look below:

Code

What it does

CreateSubKey(".Hello")

Creates a registry key in ClassesRoot for the .Hello extension. Notice that you must include the beginning period.

.SetValue("", "Hello"...
  1. "" (Or Nothing) sets the default value of the key.

  2. "Hello" is like the "txtfile" we saw earlier, it tells which registry key contains the information about the .Hello extension.

CreateSubKey("Hello" & _ "\shell\open\command")

This creates the "Hello" sub-key and the "store\open\command" subkey that is needed to store the path to the application that will open this file type.

.SetValue("", Application.ExecutablePath & _ " ""%l"" ",...
  1. Again, "" tells the application to set the key's default value.
  2. Application.ExecutablePath tells the code to associate the currently running executable
    with this file type.
  3. " ""%1"" " passes the opened file's location to your program. The quotes around it are
    optional, but if you have more than one argument, you must put them around each.

Now run your application once. It will edit the registry. Your program is now associated with the .Hello file!

You want to create file association for .txt in your program. You create the file association, but it still opens in Notepad.
What's going on? There is another value that needs to be deleted located here:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt
The value name is 'Progid'. This will consist of a string value of the default program to open this filetype. If this value is present,
you will not be able to associate anything with this particular filetype. You must delete the 'Progid' value in order for the association to work.

Now to test it out. Open Notepad, type in an adjective, and save it as a .Hello file (Make sure you don't accidentally save it as a .Hello.txt file).
Open the file in Windows Explorer. Your program will run! But nothing happens...

Step 2: Reading the File Contents

Now I've told you how to associate the files and the article should be over, right? Nope! This wouldn't be any use if you didn't know how to read the
command-line arguments and finish the program! Luckily, this is simple. My.Application.CommandlineArgs returns a ReadonlyCollection(Of String).


When the registry is set correctly and a file is opened in Windows Explorer, the file's path is pass as a command-line argument
(if you think of an application as a method - a subroutine or function - then these are the parameters).
To retrieve the arguments, you use My.Application.CommandlineArgs. It returns a ReadOnlyCollection(Of String).
You can use My.Application.CommandlineArgs(0) to retrieve the file path, or use the code below to convert the collection to an array.


To convert this to an array (which you don't really need to do unless you're not familiar with working with collecions),
add the following to the Application's Load Event:

  'Array to hold the arguments
  Dim strAllArgs(My.Application.CommandLineArgs.Count - 1) As String
  'Counter Variable
  Dim x as integer = 0

  For Each arg as string In My.Application.CommandLineArgs 
           'Write the arguments to an array
            Try
                strAllArgs(x) = arg
            'Catch Exceptions
            Catch ex As Exception
                strAllArgs(x) = "Could not write argument."
                Debug.Writeline(ex.message)
            End Try
            x += 1
  Next

  If My.Application.CommandLineArgs.Count = 0 Then
            ReDim strAllArgs(0) As String
            strAllArgs(0) = Nothing
  End If

The strAllArgs is the new array.

Now, we have to display the message. More code for the Load event:

  msgbox("Hello, " & My.Computer.FileSystem.ReadAllText(strAllArgs(0)) & " World!")

Screenshot - VBFileAssociation2.gif

Using RegistryActions.FileAssociation

(The easier way)

Okay, now you've done it the hard way, time to learn the easy way. Using the included RegistryActions DLL,
you can associate a file type with a variable and a method. Then, you can read the arguments with just one more method!

Imports RegistryActions.FileAssociation

Public Class HelloForm

    Private ftHello As New FileType(".Hello", "Hello", "Hello World Adjective File", "C:\World.ico")

    Private Sub HelloForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
           DoAssociation.Associate(ftHello, Application.ExecutablePath)
           msgbox("Hello, " & My.Computer.FileSystem.ReadAllText(DoAssociation.WriteCommandsToArray(My.Application.CommandLineArgs)(0)) & " World!")
    End Sub

End Class

See the documentation for more on the RegistryActions Namespace.

Beyond...

Explore the HKEY_CLASSES_ROOT hive. Look for additional features you can add, for example when you right click on a file. Find out how to change the default
icon for a file type... And Keep on Programming!

History

Date Change
4/29/07 Article Submitted
4/30/07
  1. Fixed up article so it fits on one page.
  2. Updated demo project.
5/8/07
  1. Explained My.Application.CommandLineArgs.
6/3/07 Added this tip.
6/8/07 Fixed problems in the DLL.
6/26/07 Changed the wordings in some phrases and fixed some errors in the examples.
6/29/07
  1. Fixed links.
  2. No more sidescrolling!
 Msgs 1 to 25 of 40 (Total in Forum: 40) (Refresh)FirstPrevNext
GeneralNICEmemberMikeDaMan259416:56 14 Jan '09  
This 100% Works! Its not even hard to follow! very clean, easy, and best of all working

Thumbs up to you! Wink Smile Big Grin CoolCool
GeneralCode Doesn't Work Under Limited User Account of Vista...memberJagadish Kumar V6:24 24 Dec '08  
Hi,
I Want to be Able to Associate extentions With the Applications from Limited user Accounts of Xp and Vista,

However, The Above Code Doesnt Work..

It Gives the Following Error...
Please Guide me through this....

 System.UnauthorizedAccessException: Access to the registry key 'HKEY_CLASSES_ROOT\.Hello' is denied.
at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck, RegistrySecurity registrySecurity)
at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey)
at Hello_World.RegistryActions.FileAssociation.DoAssociation.Associate(FileType Type, String ExeFile, String ExtraCommands)
at Hello_World.HelloForm.HelloForm_Load(Object sender, EventArgs e)
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


Please Help Cry
GeneralTHis thing sucksmembersteve ass12:10 18 Jun '08  
this code is a piece of u know what
GeneralI can't get it workingmembergalaicra13:14 20 Apr '08  
Hi, I've tried your dll, with the following code:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim fType As New FileType(".fitytest", "filetypetest", "Test of filetypes", "C:\Documents and Settings\Jesper\Skrivebord\free_icons\amc\Standard V.ico")
DoAssociation.Associate(fType, Application.ExecutablePath, """%1""")
End Sub

I've looked in my registry, and it seem to work, but when i open my .fifytest file, windows don't know which program to use. The program aren't shown either.
What have i done wrong?
- galaicra
GeneralRe: I can't get it workingmemberNickr56:59 21 Apr '08  
New FileType(".fitytest"
Try it without the preceding period.
New FileType("fitytest"


Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

Creating Custom Controls: Casino Royale


GeneralBug at this versionmemberAdiKL10:46 19 Nov '07  
Hi - I run my project and your example that uses your dll library and it throws inner exception
I think that the bug is in the constructor of RegistryActions.FileAssociation.DoAssociation.Associate - you check there whether FileType.Description != NULL ????
Can you fix this please ??
And I'll be glad I you can attached your origin code if you dont mind..Smile

Thanks.
Adi

Adi Keidar
GeneralCrusial Bug ! at this versionmemberAdiKL10:44 19 Nov '07  
Hi - I run my project and your example that uses your dll library and it throws inner exception
I think that the bug is in the constructor of RegistryActions.FileAssociation.DoAssociation.Associate - you check there whether FileType.Description != NULL instead of == ????
Can you fix this please ??
And I'll be glad I you can attached your origin code if you dont mind..Smile

Thanks.
Adi
QuestionerrormemberBetaNium6:18 11 Nov '07  
I get this error when I run my program: Value cannot be null.
Parameter name: path .

It's in this line:
MsgBox("Hello, " & My.Computer.FileSystem.ReadAllText(DoAssociation.WriteCommandsToArray(My.Application.CommandLineArgs)(0)) & " World!").

What does that mean?Confused


This is my signature.

AnswerRe: error [modified]memberNickr57:55 11 Nov '07  
It looks like no command-line args were specified. Which would probably be because you didn't run it by opening a file.

Will it work if you double click a file that ends in whichever extension you associated instead of running it via visual stuido? (So if you decided to use the .Hello extension, then open a .Hello file in Windows Explorer)

Edit:
Somehow you are getting your argument passed to the application, but it's empty.
Check this part:
.SetValue("", Application.ExecutablePath & _ " ""%l"" ",...
Make sure you have the %1 (as in one, not the letter L).


Try both of these suggestions and tell me what happens.

-- modified at 13:05 Sunday 11th November, 2007


Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

Creating Custom Controls: Casino Royale

Generalassociat more filesmemberMrRAP9:17 20 Sep '07  
how can i associat more then 1 file at once?

if i select more then 1 file and i click on open i want all paths form all files!

i want the same effect when i select some mp3-files (and click on play) and the mediaplayer opens all files in ONE mediaplayer (like a playlist)?

thx
AnswerRe: associat more filesmemberNickr59:45 20 Sep '07  
You could try a single instance application (see "Open With while the program is already running" for a link)


Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

Creating Custom Controls: Casino Royale

GeneralRe: associat more filesmemberMrRAP4:47 21 Sep '07  
no, if i select more then one file (for example two) and i click right on it (to open both) there are always coming 2 windows: MOVE FILES TO...

if i click on cancle my programm starts.

but why that 2 windows?

thx.
QuestionIconmemberKschuler7:35 21 Aug '07  
Is this code:
My.Computer.Registry.ClassesRoot.CreateSubKey(".Hello").SetValue("", "Hello", Microsoft.Win32.RegistryValueKind.String)
My.Computer.Registry.ClassesRoot.CreateSubKey("Hello\shell\open\command").SetValue("", Application.ExecutablePath & _
" ""%l"" ", Microsoft.Win32.RegistryValueKind.String)


supposed to set it so that now when you view .hello files in windows explorer, the icon of the .hello file will look like your executable's icon? Because I tried this and the icon changes but to an odd looking generic icon. So, how can I set the icon myself?
AnswerRe: IconmemberNickr515:39 21 Aug '07  
Try this:

My.Computer.Registry.ClassesRoot.CreateSubKey("Hello\DefaultIcon").SetValue("", "C:\YOURICONHERE.ico", _
Microsoft.Win32.RegistryValueKind.String)

Smile


Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

Creating Custom Controls: Casino Royale

GeneralRe: IconmemberKschuler3:59 22 Aug '07  
Thanks! That is exactly what I was looking for.
QuestionRe: IconmemberKschuler11:31 29 Aug '07  
I've implemented your code for opening a document and setting the default icon in a project, and it works fine with Windows XP. However, I tried it on a Vista machine and ran into a problem with not having permission to write to the registry. I've been having trouble finding any articles about this issue and was wondering if you have encountered this and, if so, how you overcame it. Any help would be appreciated.
GeneralRe: IconmemberNickr515:15 29 Aug '07  
-Are you having problems with all registry writes/file associations, or just setting a default icon?

-Do you get any error messages? If so, what?

-Try running the program as an administrator.

-Try the suggestion in this post[^].






Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

Creating Custom Controls: Casino Royale

GeneralRe: IconmemberKschuler4:21 30 Aug '07  
I write to the registry to set the file association and then I set the default icon. The error is thrown on the file association registry write. The error message I get is: (my file extention is .fac)
System.UnauthorizedAccessException: Access to the registry key 'HKEY_CLASSES_ROOT\fac\shell\open\command' is denied.
at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck, RegistrySecurity registrySecurity)
at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey)
at FileAccess.Main.SetFileAssociation() in C:\Project Source\FileAccess2\Forms\Main.vb:line 1833
at FileAccess.Main.Main_Load(Object sender, EventArgs e) in C:\Project Source\FileAccess2\Forms\Main.vb:line 20
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


And I am already running the program as an administrator.

I looked into the suggestion you posted, but if I'm understanding it correctly it doesn't look quite right. The registry at that location doesn't have a default icon area, andit seems to just refer back to the registry settings that your article discusses. If you have any other suggestions or ideas, I would really appreciate the advice.

Thank you for your time.


GeneralRe: Icon [modified]memberNickr52:23 31 Aug '07  
This code worked fine for me under XP:

Sub Main()

My.Computer.Registry.ClassesRoot.CreateSubKey(".fac").SetValue("", "TestFacExt", Microsoft.Win32.RegistryValueKind.String)
My.Computer.Registry.ClassesRoot.CreateSubKey("TestFacExt\shell\open\command").SetValue("", "C:\XXX" & _
" ""%1"" ", Microsoft.Win32.RegistryValueKind.String)
Console.ReadLine()
End Sub

If yours is a lot different, then could you post it?

Edit:
If you are using the OpenSubKey() method, then you may be using the wrong overload.

Make sure you set writeable to true: OpenSubKey(name, True)


-- modified at 7:35 Friday 31st August, 2007


-- modified at 13:00 Sunday 11th November, 2007


Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

Creating Custom Controls: Casino Royale

GeneralRe: IconmemberKschuler3:55 4 Sep '07  
That is basically what my code looks like. I don't use an OpenSubKey method though. I just always use the CreateSubKey. Could that be my problem? Here is my code in case there is some difference I am not seeing. (I put my ext in a global variable in case I wanted to change it.)

My.Computer.Registry.ClassesRoot.CreateSubKey("." & gblstrFileExt).SetValue("", gblstrFileExt,Microsoft.Win32.RegistryValueKind.String)
My.Computer.Registry.ClassesRoot.CreateSubKey(gblstrFileExt & "\shell\open\command").SetValue("", Application.ExecutablePath & _
" ""%l"" ", Microsoft.Win32.RegistryValueKind.String)

GeneralRe: Icon [modified]memberNickr55:30 4 Sep '07  
I used the following code and it worked fine:

Private Const gblstrFileExt As String = "randomExt"
Sub Main()
My.Computer.Registry.ClassesRoot.CreateSubKey("." & gblstrFileExt).SetValue("", gblstrFileExt, Microsoft.Win32.RegistryValueKind.String)
My.Computer.Registry.ClassesRoot.CreateSubKey(gblstrFileExt & "\shell\open\command").SetValue("", "xxx" & _
" ""%l"" ", Microsoft.Win32.RegistryValueKind.String)
End Sub


It works fine under XP and Vista (without the UAC) for me. Try running the program with the UAC turned off.

Make sure your program has all necessary permissions.


-- modified at 12:58 Sunday 11th November, 2007


Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

Creating Custom Controls: Casino Royale

AnswerRe: IconmemberMember 441027111:42 8 Jan '09  
For Windows Vista, you have to run your application as administrator in order for you to write to registry
Question"Open With" if the program is already runningmemberSchadenfroh13:17 28 Jun '07  
Thanks for the interesting read first of all.

Is there anyway to read in a file associated with the vb.net program if one only wants one instance of the program running and it has already opened?

For example,

I text file with a ".HELLO" extension is right clicked / open withed or is associated with the VB.NET program already and the program itself is running, anyway to retrieve the info in the text file as like a backgroundworker rather than on load?

thanks
AnswerRe: "Open With" if the program is already runningmembernickr53:02 29 Jun '07  
I think what you want is a single intance application.


Fluent in VB, Attempts to speak C#, Python, English Wink

---
File Association in VB.Net

QuestionRe: "Open With" if the program is already runningmemberMyplace31110:02 7 Jan '09  
With a single instance program how would you go about addressing a file being opend wile the program is open.

Sub aSub handles me.FileAssosiatedOpend(just an example)

To help clarify. If i was making an MP3 player and was playing a song. Then i double click another song. I want the player to start playing that song, Not open another player. How would we do that?

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 3 Feb 2009
Editor:
Copyright 2007 by Nickr5
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project