1

I'm trying to create a 'Show' button in my application. I want this to either open Windows Explorer into the selected folder, or open into the folder and highlight the selected file.

I know Process.Start("explorer.exe", fileName) does this, however it opens in a version of Explorer that can't be navigated. Pressing 'Up Directory' for example opens a new window.

The code I've got below does everything I want it to, except that when the path is a file, it opens a new window instance each time the button is clicked. Whereas when the path is a folder, it opens an already existing window if one exists at that path.

I'm hoping I can have the same functionality for file selection. But I can't figure out how to do it.

Any and all help is appreciated!

static void OpenInWin(string path) {
    path = path.Replace("/", "\\");

    ProcessStartInfo pi = new ProcessStartInfo("explorer.exe") {
        WindowStyle = ProcessWindowStyle.Normal,
        UseShellExecute = true
    };

    if (Directory.Exists(path)) { // We are opening a directory
        pi.FileName = path;
        pi.Verb = "open";
    } else {
        pi.Arguments = "/select, \"" + new FileInfo(path).FullName + "\"";
    }

    try {
        Process.Start(pi);
    } catch(Exception e) {
        UnityEngine.Debug.Log(e);
    }
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
stuntboots
  • 71
  • 8

1 Answers1

-1

Method below will get the directory from the path passed, then open that directory. After opening that directory it will focus on the file name (if it exists).

Remember to include using System.Windows.Forms; for SendKeys.

static void OpenInWin(string path)
{
    path = path.Replace("/", "\\");
    FileInfo fileInfo = new FileInfo(path);

    //check if directory exists so that 'fileInfo.Directory' doesn't throw directory not found

    ProcessStartInfo pi = new ProcessStartInfo("explorer.exe")
    {
        WindowStyle = ProcessWindowStyle.Normal,
        UseShellExecute = true,
        FileName = fileInfo.Directory.FullName,
        Verb = "open"
    };

    try
    {
        Process.Start(pi);
        Thread.Sleep(500); // can set any delay here
        SendKeys.SendWait(fileInfo.Name);
    }
    catch (Exception e)
    {
        throw new Exception(e.Message, e);
    }
}


Note: There might be a better way of sending keys to a process. You can experiment with the method below:

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

public static void SendKey()
{
    Process notepad = new Process();
    notepad.StartInfo.FileName = @"C:\Windows\Notepad.exe";
    notepad.Start();

    notepad.WaitForInputIdle();

    IntPtr p = notepad.MainWindowHandle;
    ShowWindow(p, 1);
    SendKeys.SendWait("Text sent to notepad");
}

Edit:

To produce key events without Windows Forms Context, We can use the following method,

[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

sample code is given below:

const int VK_UP = 0x26; //up key
    const int VK_DOWN = 0x28;  //down key
    const int VK_LEFT = 0x25;
    const int VK_RIGHT = 0x27;
    const uint KEYEVENTF_KEYUP = 0x0002;
    const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
   static int press()
   {

//Press the key
        keybd_event((byte)VK_UP, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
        return 0; 

   }

List of Virtual Keys are defined here.

To get the complete picture, please use the below link, http://tksinghal.blogspot.in/2011/04/how-to-press-and-hold-keyboard-key.html

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
Antony
  • 1,221
  • 1
  • 11
  • 18
  • Hey! Thanks for this. Unfortunately I can't test it, as I'm using Unity, which I think only uses .net 2.0? And it seems like System.Windows came later than that? – stuntboots Apr 06 '16 at 22:52
  • 1
    My comment yesterday (after understanding the problem) is your answer today, nice one ;) @stuntboots System.Windows came way before Unity. I have edited the answer to show you how to produce key events without Windows Forms Context. – Jeremy Thompson Apr 07 '16 at 01:24
  • @stuntboots If you move to Unity 5 you can use .Net 3.5 – Antony Apr 07 '16 at 06:58
  • Hiya Antony, I'm actually on Unity 5! How do I change to the upgraded .Net? – stuntboots Apr 07 '16 at 11:31
  • @stuntboots [Target a Version of the .NET Framework](https://msdn.microsoft.com/en-us/library/bb398202.aspx) – Antony Apr 07 '16 at 11:39
  • Isn’t relying on SendKeys and timing for this a little bit dangerous? I’ve had Explorer take **way** longer than 500ms to open before. And the user could have changed focus within the Explorer window prior to the keys being sent. – binki Nov 14 '18 at 16:40