31

Our client (a winforms app) includes a file-browser. I'd like the user to be able to open the selected file using the shell's default handler. How do I do that? I've read that I should use the Win32 API rather than the registry, but I'd prefer a solution that involves only .NET.

Simon
  • 25,468
  • 44
  • 152
  • 266

4 Answers4

69

EDIT: Newer, simpler answer.

You can indeed just use Process.Start(filename). This is specified in the docs for Process.Start:

Starting a process by specifying its file name is similar to typing the information in the Run dialog box of the Windows Start menu. Therefore, the file name does not need to represent an executable file. It can be of any file type for which the extension has been associated with an application installed on the system. For example the file name can have a .txt extension if you have associated text files with an editor, such as Notepad, or it can have a .doc if you have associated.doc files with a word processing tool, such as Microsoft Word. Similarly, in the same way that the Run dialog box can accept an executable file name with or without the .exe extension, the .exe extension is optional in the fileName parameter. For example, you can set the fileName parameter to either "Notepad.exe" or "Notepad".

EDIT: Original, complicated answer:

If you use Process.Start with the file as the "executable" and specify UseShellExecute = true it will just work. For example:

using System;
using System.Diagnostics;

class Test
{
    static void Main()
    {
        ProcessStartInfo psi = new ProcessStartInfo("test.txt");
        psi.UseShellExecute = true;
        Process.Start(psi);
    }
}

That opens test.txt in Notepad.

In fact, UseShellExecute=true is the default, but as it's definitely required I like to specify it explicitly to make that clearer to the reader.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • `Process.Start("C:\temp\test.xlsx");` open a ***xlsx file*** if **Excel is installed**. If not installed, I don't know. – Kiquenet Feb 24 '17 at 09:59
  • 4
    Your old answer is now very relevant for dotnet core apps, where `UseShellExecute=true` is required, again. – Patrick Stalph Oct 10 '18 at 05:48
8

Since this question is the first result in Google, I'm adding this updated answer for .NET Core and .NET 5 upwards. You will need to add UseShellExecute = true.

Process.Start(new ProcessStartInfo(filePath) { UseShellExecute = true });

It's more cumbersome than earlier with .NET Framework, but you can wrap it in a custom method:

    public static void OpenFile(string filePath) 
        => Process.Start(new ProcessStartInfo(filePath) { UseShellExecute = true });
shA.t
  • 16,580
  • 5
  • 54
  • 111
Desmond
  • 406
  • 5
  • 7
7

not sure if its ok

System.Diagnostics.Process.Start(filePath);
Sam
  • 40,644
  • 36
  • 176
  • 219
Jason
  • 479
  • 1
  • 4
  • 6
3

System.Diagnostics.Process provides the .Net native wrapper around shell32.ShellExecute.

See PInvoke.Net for a discussion of both APIs, and MSDN docs on MSDN .

Tetsujin no Oni
  • 7,300
  • 2
  • 29
  • 46