Opening a Folder in Explorer and Selecting a File

Opening a folder in explorer and selecting a file

Use this method:

Process.Start(String, String)

First argument is an application (explorer.exe), second method argument are arguments of the application you run.

For example:

in CMD:

explorer.exe -p

in C#:

Process.Start("explorer.exe", "-p")

Open a folder in Windows Explorer and select a file works second time only

Rather than the explorer command line Chrome most probably uses the more flexible SHOpenFolderAndSelectItems Shell API.

This answer contains the required p/invoke/implementation.

How to open Explorer with a specific file selected?

Easiest way without using Win32 shell functions is to simply launch explorer.exe with the /select parameter. For example, launching the process

explorer.exe /select,"C:\Folder\subfolder\file.txt"

will open a new explorer window to C:\Folder\subfolder with file.txt selected.

If you wish to do it programmatically without launching a new process, you'll need to use the shell function SHOpenFolderAndSelectItems, which is what the /select command to explorer.exe will use internally. Note that this requires the use of PIDLs, and can be a real PITA if you are not familiar with how the shell APIs work.

Here's a complete, programmatic implementation of the /select approach, with path cleanup thanks to suggestions from @Bhushan and @tehDorf:

public bool ExploreFile(string filePath) {
if (!System.IO.File.Exists(filePath)) {
return false;
}
//Clean up file path so it can be navigated OK
filePath = System.IO.Path.GetFullPath(filePath);
System.Diagnostics.Process.Start("explorer.exe", string.Format("/select,\"{0}\"", filePath));
return true;
}

Reference: Explorer.exe Command-line switches

Opening explorer and selecting a file (with a long file path) through cmd or powershell

Caveats:

  • The following solution works only on volumes where short (8.3) file names are enabled - they are by default, but the feature can be turned off , via the fsutil.exe utility's 8dot3name subcommand, either system-wide or on a per-volume basis.

    • To query a given volume's support, run the following from an elevated session, using C: as an example:
      • fsutil 8dot3name query C:
  • It is unclear to me how the above relates to UNC paths. Also, I presume, even the short version of a path can hypothetically exceed the overall path length limit of 259 characters, if the path is very deeply nested.

  • At the file-system API level you can configure a system to support paths longer than 259 characters by default, without requiring the long-path opt-in prefix \\?\. This can be achieved via Group Policy or the registry - see this answer for more information.

    • Unfortunately, even with default long-path support enabled, explore.exe apparently does not support paths longer than 259 characters.

I think Jonathan gave the crucial pointer: Pass the short (8.3) version of the file path to work around explore.exe's seeming non-support for paths longer than 259 characters.

# Create a sample file with a long path (longer than 259 chars.)
$longFilePath = (New-Item -Force ("\\?\$HOME\_tmp" + 'x' * 250)).FullName

# Obtain the short (8.3) version of the long path.
# Note: Be sure to pass a FULL (absolute) path, which must be prefixed with '\\?\',
# unless default long-path support is enabled system-wide (see below).
$shortPathVersion =
(New-Object -ComObject Scripting.FileSystemObject).GetFile($longFilePath).ShortPath

# Pass the short version of the path to explorer.exe
explorer.exe /select,$shortPathVersion

Run Remove-Item -LiteralPath $longFilePath to clean up the sample file later.

Note:

  • In Windows PowerShell - unless default long-path support is enabled system-wide - you need to use the \\?\ prefix for long paths (paths whose length exceeds 259 characters), as shown in the New-Item call above.

    • In PowerShell (Core) 7+ this prefix is no longer necessary - it has long-path support built in; in fact, as of PowerShell 7.2 there are bugs that situationally prevent its use (which is problematic if your code needs to run in both PowerShell editions) - see GitHub issue #10805
  • Unless default long-path support is enabled, the path passed to (New-Object -ComObject Scripting.FileSystemObject).GetFile() needs the \\?\ prefix too - even calling from PowerShell (Core) 7+

    • Curiously, the short version of the path returned retains this prefix, but explorer.exe doesn't seem to have a problem with that.
  • Even though , is normally a metacharacter in PowerShell (array constructor), when calling external programs, such as explorer.exe, it does not act as such, so there is no strict need to pass the arguments as "/select,$shortPathVersion" or /select`,$shortPathVersion

Open Windows Explorer directory, select a specific file (in Delphi)

Yes, you can use the /select flag when you call explorer.exe:

ShellExecute(0, nil, 'explorer.exe', '/select,C:\WINDOWS\explorer.exe', nil,
SW_SHOWNORMAL)

A somewhat more fancy (and perhaps also more reliable) approach (uses ShellAPI, ShlObj):

const
OFASI_EDIT = $0001;
OFASI_OPENDESKTOP = $0002;

{$IFDEF UNICODE}
function ILCreateFromPath(pszPath: PChar): PItemIDList stdcall; external shell32
name 'ILCreateFromPathW';
{$ELSE}
function ILCreateFromPath(pszPath: PChar): PItemIDList stdcall; external shell32
name 'ILCreateFromPathA';
{$ENDIF}
procedure ILFree(pidl: PItemIDList) stdcall; external shell32;
function SHOpenFolderAndSelectItems(pidlFolder: PItemIDList; cidl: Cardinal;
apidl: pointer; dwFlags: DWORD): HRESULT; stdcall; external shell32;

function OpenFolderAndSelectFile(const FileName: string): boolean;
var
IIDL: PItemIDList;
begin
result := false;
IIDL := ILCreateFromPath(PChar(FileName));
if IIDL <> nil then
try
result := SHOpenFolderAndSelectItems(IIDL, 0, nil, 0) = S_OK;
finally
ILFree(IIDL);
end;
end;

Is there any way to open file explorer and select a file from a UWP app?

You can also use the Launcher.LaunchFolderAsync and use the second parameter Folder​Launcher​Options too.

Folder​Launcher​Options can make the file or folder that you want to select that use the ItemsToSelect.

ItemsToSelect is a read-only property, but you can add items to the existing list.

Here's an example, getting a folder using FolderPicker and then selecting all files:

The first is get the folder:

        FolderPicker p = new FolderPicker();
p.FileTypeFilter.Add(".txt");
StorageFolder folder = await p.PickSingleFolderAsync();

And then get all files in the folder

   foreach (var temp in await folder.GetFilesAsync())

I can use FolderLauncherOptions to add the item that I want to select.

        var t = new FolderLauncherOptions();
foreach (var temp in await folder.GetFilesAsync())
{
t.ItemsToSelect.Add(temp);
}

Then open the file explorer

      await Launcher.LaunchFolderAsync(folder, t);

You can see that the explorer will be opened while selecting all files.

You can also add folders to the ItemsToSelect and it will be selected.

See here for more details: https://learn.microsoft.com/en-us/uwp/api/Windows.System.Launcher#Windows_System_Launcher_LaunchFolderAsync_Windows_Storage_IStorageFolder_Windows_System_FolderLauncherOptions_

Launching Windows Explorer and highlighting a file

You can execute explorer.exe with the /select argument:

Shell "explorer.exe /select,""" & Range("A1") & """", vbNormalFocus

Assuming A1 had the path c:\path\to\file.txt, this would look like:

explorer.exe /select,"c:\path\to\file.txt"

Opening Folder or to Selected File in Single, Usable Instance

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



Related Topics



Leave a reply



Submit