Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the default application for opening a particular file type on Windows

I'm developing an application targeting .NET Framework 2.0 using C# for which I need to be able to find the default application that is used for opening a particular file type.

I know that, for example, if you just want to open a file using that application you can use something like:

System.Diagnostics.Process.Start( "C:\...\...\myfile.html" ); 

to open an HTML document in the default browser, or

System.Diagnostics.Process.Start( "C:\...\...\myfile.txt" ); 

to open a text file in the default text editor.

However, what I want to be able to do is to open files that don't necessarily have a .txt extension (for example), in the default text editor, so I need to be able to find out the default application for opening .txt files, which will allow me to invoke it directly.

I'm guessing there's some Win32 API that I'll need to P/Invoke in order to do this, however a quick look with both Google and MSDN didn't reveal anything of much interest; I did find a very large number of completely irrelevant pages, but nothing like I'm looking for.

like image 938
Bart Read Avatar asked Oct 02 '08 13:10

Bart Read


People also ask

How do I remove the default application of a file type in Windows?

Press Windows + I on the keyboard to open the Settings app. Select Apps in the left navigation pane, and then click “Default apps” on the right. You'll see a list of default apps. Scroll down to the bottom and click the Reset button.

What is Windows default application?

Windows keeps a list of apps that it always uses to open certain types of media or links. These are called default programs. For example, when you double-click an MP4 file, Windows opens it in your default video player.


2 Answers

All current answers are unreliable. The registry is an implementation detail and indeed such code is broken on my Windows 8.1 machine. The proper way to do this is using the Win32 API, specifically AssocQueryString:

using System.Runtime.InteropServices;  [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)] public static extern uint AssocQueryString(     AssocF flags,      AssocStr str,       string pszAssoc,      string pszExtra,      [Out] StringBuilder pszOut,      ref uint pcchOut );   [Flags] public enum AssocF {     None = 0,     Init_NoRemapCLSID = 0x1,     Init_ByExeName = 0x2,     Open_ByExeName = 0x2,     Init_DefaultToStar = 0x4,     Init_DefaultToFolder = 0x8,     NoUserSettings = 0x10,     NoTruncate = 0x20,     Verify = 0x40,     RemapRunDll = 0x80,     NoFixUps = 0x100,     IgnoreBaseClass = 0x200,     Init_IgnoreUnknown = 0x400,     Init_Fixed_ProgId = 0x800,     Is_Protocol = 0x1000,     Init_For_File = 0x2000 }  public enum AssocStr {     Command = 1,     Executable,     FriendlyDocName,     FriendlyAppName,     NoOpen,     ShellNewValue,     DDECommand,     DDEIfExec,     DDEApplication,     DDETopic,     InfoTip,     QuickTip,     TileInfo,     ContentType,     DefaultIcon,     ShellExtension,     DropTarget,     DelegateExecute,     Supported_Uri_Protocols,     ProgID,     AppID,     AppPublisher,     AppIconReference,     Max } 

Relevant documentation:

  • AssocQueryString
  • ASSOCF
  • ASSOCSTR

Sample usage:

static string AssocQueryString(AssocStr association, string extension) {     const int S_OK = 0;     const int S_FALSE = 1;      uint length = 0;     uint ret = AssocQueryString(AssocF.None, association, extension, null, null, ref length);     if (ret != S_FALSE)     {         throw new InvalidOperationException("Could not determine associated string");     }      var sb = new StringBuilder((int)length); // (length-1) will probably work too as the marshaller adds null termination     ret = AssocQueryString(AssocF.None, association, extension, null, sb, ref length);     if (ret != S_OK)     {         throw new InvalidOperationException("Could not determine associated string");      }      return sb.ToString(); } 
like image 167
Ohad Schneider Avatar answered Sep 17 '22 14:09

Ohad Schneider


You can check under registry section HKEY_CLASSES_ROOT for the extension and action details. Documentation for this is on MSDN. Alternatively, you can use the IQueryAssociations interface.

like image 23
curtisk Avatar answered Sep 18 '22 14:09

curtisk