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's8dot3name
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:
- To query a given volume's support, run the following from an elevated session, using
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.
- Unfortunately, even with default long-path support enabled,
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 exceeds259
characters), as shown in theNew-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.
- Curiously, the short version of the path returned retains this prefix, but
Even though
,
is normally a metacharacter in PowerShell (array constructor), when calling external programs, such asexplorer.exe
, it does not act as such, so there is no strict need to pass the arguments as"/select,$shortPathVersion"
or/select`,$shortPathVersion