35

How to open an file's Properties dialog by a button

private void button_Click(object sender, EventArgs e)
{
    string path = @"C:\Users\test\Documents\tes.text";
    // how to open this propertie
}

Like windows right click on a file and you can open the Properties of the file.

For example if want the System properties

Process.Start("sysdm.cpl");    

But how do I get the Properties dialog for a file path?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
User6996
  • 2,953
  • 11
  • 44
  • 66

5 Answers5

57

Solution is:

using System.Runtime.InteropServices;

[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHELLEXECUTEINFO
{
    public int cbSize;
    public uint fMask;
    public IntPtr hwnd;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpVerb;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpFile;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpParameters;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpDirectory;
    public int nShow;
    public IntPtr hInstApp;
    public IntPtr lpIDList;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpClass;
    public IntPtr hkeyClass;
    public uint dwHotKey;
    public IntPtr hIcon;
    public IntPtr hProcess;
}

private const int SW_SHOW = 5;
private const uint SEE_MASK_INVOKEIDLIST = 12;
public static bool ShowFileProperties(string Filename)
{
    SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
    info.cbSize = Marshal.SizeOf(info);
    info.lpVerb = "properties";
    info.lpFile = Filename;
    info.nShow = SW_SHOW;
    info.fMask = SEE_MASK_INVOKEIDLIST;
    return ShellExecuteEx(ref info);        
}

// button click
private void button1_Click(object sender, EventArgs e)
{
    string path = @"C:\Users\test\Documents\test.text";
    ShowFileProperties(path);
}
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
User6996
  • 2,953
  • 11
  • 44
  • 66
  • 1
    I'm doing something similar with a command-line app, and while it runs fine in a GUI with a button click, via a command-line it just autocloses the app as soon as it calls it. Is there some way to get the code to wait for the properties window to close before closing the command-line window that called it? I tried changing `.fMask` to `SEE_MASK_INVOKEIDLIST + SEE_MASK_NOCLOSEPROCESS` (and added it's integer value, 64, as well), but nothing changed. – J. Scott Elblein Dec 30 '14 at 07:37
  • @J.ScottElblein I got the window to open and stay open after my application quits by simply putting a Thread.Sleep(500) after the ShowFileProperties call. Looks like the application has to be running until the window is created. Maybe this could be improved by actually waiting for a window with title containing properties. – MemphiZ Mar 14 '16 at 13:30
  • @J.ScottElblein Like this: https://gist.github.com/Memphizzz/ed69d2500c422019609c – MemphiZ Mar 14 '16 at 13:41
12

Call Process.Start, passing a ProcessStartInfo containing the name of the file, and with the ProcessStartInfo.Verb set to properties. (For more info, see the description of the unmanaged SHELLEXECUTEINFO structure, which is what ProcessStartInfo wraps, and in particular the lpVerb member.)

itowlson
  • 73,686
  • 17
  • 161
  • 157
  • 8
    Could expand on why you think it's hacky? ProcessStartInfo/ShellExecuteEx is the standard way of invoking shell actions like "open", "print" and "show properties." There used to be a more direct way, SHObjectProperties, but this was removed beginning in Vista, so ShellExecuteEx remains the documented method as far as I know... open to corrections! – itowlson Dec 20 '09 at 20:02
  • 1
    check the .Verbs property of the PSI beforehand. I was trying this on an .exe, maybe shell doesn't like this, but likes it on other file types. – Epu Oct 07 '11 at 14:12
  • 2
    It doesnt work, not on exe, jpeg,mp3 or anything else! none of these have a verb named propertise! or show propertise! – Hossein Mar 11 '15 at 02:38
7

Various file properties are available from the FileInfo class:

FileInfo info = new FileInfo(path);
Console.WriteLine(info.CreationTime);
Console.WriteLine(info.Attributes);
...
Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
0

Solution is to use ShellExecute () api.

How to invoke this api using C# : http://weblogs.asp.net/rchartier/442339

This works fine for me without CharSet attribute both in Debug and Release mode.

AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38
0

To simplify handling Shell32 stuff and such, you could also use Vanara like:

using Vanara.PInvoke;
using System.Runtime.InteropServices;
// ...
void ShowProperties(string filepath)
{
    var info = new Shell32.SHELLEXECUTEINFO();

    info.cbSize = Marshal.SizeOf(info);
    info.lpVerb = "properties";
    info.lpFile = filepath;
    info.nShellExecuteShow = ShowWindowCommand.SW_SHOW;
    info.fMask = Shell32.ShellExecuteMaskFlags.SEE_MASK_INVOKEDLIST;

    Shell32.ShellExecuteEx(ref i);
}

and call it like:

ShowProperties(@"C:\The\Path\To\The\File.txt");
Chris Tophski
  • 930
  • 1
  • 6
  • 23