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)
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.
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.
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.
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+
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