How to open properties dialog for non-lnk files?

Heiko 1,291 Reputation points
2023-01-11T15:38:57.2666667+00:00

I have a WPF app with .NETFramework.

In the following way it is possible to open the properties dialog of an lnk file:

ProcessStartInfo psi = new ProcessStartInfo(@"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Acrobat Reader.lnk");

psi.Verb = "properties";
psi.UseShellExecute = true;
Process.Start(psi);

However, when I try to call this for another file type, e.g. "D:\Test.txt", I get the following exception:

Win32Exception: No application is associated with the specified file. 0x80004005

How to call the properties dialog for such files?

Developer technologies | Windows Presentation Foundation
Windows development | Windows API - Win32
Developer technologies | C#
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 90,686 Reputation points
    2023-01-11T18:54:27.63+00:00

    A way is with ShellExecuteEx :

                SHELLEXECUTEINFO sei = new SHELLEXECUTEINFO();
                sei.cbSize = (uint)Marshal.SizeOf(sei);
                sei.lpVerb = "properties";
                sei.lpFile = @"e:\Test.txt";
                sei.fMask = SEE_MASK_INVOKEIDLIST;
                if (!ShellExecuteEx(ref sei))
                {
                    int nErr = Marshal.GetLastWin32Error();
                }
    

    with

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct SHELLEXECUTEINFO
        {
            public uint cbSize;
            public uint fMask;
            public IntPtr hwnd;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpVerb;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpFile;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpParameters;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpDirectory;
            public int nShow;
            public IntPtr hInstApp;
            public IntPtr lpIDList;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpClass;
            public IntPtr hkeyClass;
            public uint dwHotKey;
            public IntPtr hIcon;
            public IntPtr hProcess;
        }
    
        [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
    
        public const int SEE_MASK_INVOKEIDLIST = 0x0000000C;
    
    
    

1 additional answer

Sort by: Most helpful
  1. Hui Liu-MSFT 48,681 Reputation points Microsoft External Staff
    2023-01-12T07:50:32.2866667+00:00

    As Castorix31 said. You could call Process.Start, passing ProcessStartInfo containing the filename, and setting ProcessStartInfo.Verb as properties. (For details, see the description of the unmanaged SHELLEXECUTEINFO structure, which is what ProcessStartInfo wraps, especially the lpVerb member.)

    You can use Castorix31's first part of code like this.

     public static bool ShowFileProperties(string Filename)
            {
                SHELLEXECUTEINFO sei = new SHELLEXECUTEINFO();
                sei.cbSize = (uint)Marshal.SizeOf(sei);
                sei.lpVerb = "properties";
                sei.lpFile = Filename;
                sei.fMask = SEE_MASK_INVOKEIDLIST;
                if (!ShellExecuteEx(ref sei))
                {
                    int nErr = Marshal.GetLastWin32Error();
                }
                return ShellExecuteEx(ref sei);
            }
    

    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.