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

Time:11-04

I'm trying to use powershell (or cmd) to open a directory and select a file (or a directory).

The /select explorer command doesn't seem to work with long file paths:

explorer.exe /select,\\?\filepath

I've tried multiple combinations (the whole filepath in quotes, without the \\?\ prefix, etc). And nothing seems to work. It just opens the default "This PC" location.

I know in powershell I can use:

ii filepath

But that doesn't solve the problem, as the ii command opens the destination folder/file rather than opening the parent and selecting said folder/file.

I would really appreciate the help.

(NOTE: I'm launching cmd/powershell through a C# script, .NET Framework 4.7.2. So if there's maybe a way to do it in C# without cmd/powershell, I'd be happy to use that solution)

CodePudding user response:

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

  • Related