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);
}
}
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