Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start windows "run" dialog from C#

I want to start the run dialog (Windows+R) from Windows within my C# code.

I assume this can be done using explorer.exe but I'm not sure how.

like image 595
cyptus Avatar asked Feb 17 '12 15:02

cyptus


3 Answers

Use RunFileDlg:

[DllImport("shell32.dll", EntryPoint = "#61", CharSet = CharSet.Unicode)]
public static extern int RunFileDlg(
    [In] IntPtr hWnd,
    [In] IntPtr icon,
    [In] string path,
    [In] string title,
    [In] string prompt,
    [In] uint flags);

private static void Main(string[] args)
{
    // You might also want to add title, window handle...etc.
    RunFileDlg(IntPtr.Zero, IntPtr.Zero, null, null, null, 0);
}

Possible values for flags:

RFF_NOBROWSE = 1; //Removes the browse button.
RFF_NODEFAULT = 2; // No default item selected.
RFF_CALCDIRECTORY = 4; // Calculates the working directory from the file name.
RFF_NOLABEL = 8; // Removes the edit box label.
RFF_NOSEPARATEMEM = 14; // Removes the Separate Memory Space check box (Windows NT only).

See also How to programmatically open Run c++?

like image 197
ken2k Avatar answered Oct 16 '22 02:10

ken2k


The RunFileDlg API is unsupported and may be removed by Microsoft from future versions of Windows (I'll grant that MS's commitment to backwards compatibility and the fact that this API, though undocumented, appears to be fairly widely known makes this unlikely, but it's still a possibility).

The supported way to launch the run dialog is using the IShellDispatch::FileRun method.

In C#, you can access this method by going to Add Reference, select the COM tab, and select "Microsoft Shell Controls and Automation". After doing this you can launch the dialog as follows:

Shell32.Shell shell = new Shell32.Shell();
shell.FileRun();

Yes, the RunFileDlg API offers more customizability, but this has the advantage of being documented, supported, and therefore unlikely to break in the future.

Note that Shell32 must be run on an STA thread. If you get an exception in your code, add [STAThread] above your method declaration like this, for example:

    [STAThread]
    private static void OpenRun() {
        //Shell32 code here
    }

Any method calling a method that uses Shell32 should also be run on an STA thread.

like image 45
Sven Avatar answered Oct 16 '22 02:10

Sven


Another method would be to emulate the Windows+R key combination.

using System.Runtime.InteropServices;
using System.Windows.Forms;

static class KeyboardSend
{
    [DllImport("user32.dll")]
    private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

    private const int KEYEVENTF_EXTENDEDKEY = 1;
    private const int KEYEVENTF_KEYUP = 2;

    public static void KeyDown(Keys vKey)
    {
        keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
    }

    public static void KeyUp(Keys vKey)
    {
        keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
    }
}

and call:

KeyboardSend.KeyDown(Keys.LWin);
KeyboardSend.KeyDown(Keys.R);
KeyboardSend.KeyUp(Keys.R);
KeyboardSend.KeyUp(Keys.LWin);
like image 34
BlueM Avatar answered Oct 16 '22 01:10

BlueM