There is a 39 KB file in the free Steam game The Murder of Sonic The Hedgehog, called
1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle
, that is located in
F:\Program Files (x86)\Steam\steamapps\common\Themurderofsonicthehedgehog\The Murder of Sonic The Hedgehog\The Murder of Sonic The Hedgehog_Data\StreamingAssets\aa\StandaloneWindows64
.
Since the path has more than 259 characters, I can get Resolve-Path -LiteralPath
to work when the full path is prefixed with \\?\
. For example,
$longPath = "\\?\F:\Program Files (x86)\Steam\steamapps\common\Themurderofsonicthehedgehog\The Murder of Sonic The Hedgehog\The Murder of Sonic The Hedgehog_Data\StreamingAssets\aa\StandaloneWindows64\1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle"
Resolve-Path -LiteralPath $longPath
Is there some way to resolve the path with only the file specified like this:
cd "F:\Program Files (x86)\Steam\steamapps\common\Themurderofsonicthehedgehog\The Murder of Sonic The Hedgehog\The Murder of Sonic The Hedgehog_Data\StreamingAssets\aa\StandaloneWindows64\"
Resolve-Path -LiteralPath 1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle
which presently gives the error:
Resolve-Path : Cannot find path
'1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle' because it does not
exist.
At line:1 char:1
+ Resolve-Path -LiteralPath 1f3e56ae019cd278e6abd86e2a64eb7c_unitybuilt ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (1f3e56ae019cd27...b159399c.bundle:String) [Resolve-Path], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand
There is a 39 KB file in the free Steam game The Murder of Sonic The Hedgehog, called
1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle
, that is located in
F:\Program Files (x86)\Steam\steamapps\common\Themurderofsonicthehedgehog\The Murder of Sonic The Hedgehog\The Murder of Sonic The Hedgehog_Data\StreamingAssets\aa\StandaloneWindows64
.
Since the path has more than 259 characters, I can get Resolve-Path -LiteralPath
to work when the full path is prefixed with \\?\
. For example,
$longPath = "\\?\F:\Program Files (x86)\Steam\steamapps\common\Themurderofsonicthehedgehog\The Murder of Sonic The Hedgehog\The Murder of Sonic The Hedgehog_Data\StreamingAssets\aa\StandaloneWindows64\1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle"
Resolve-Path -LiteralPath $longPath
Is there some way to resolve the path with only the file specified like this:
cd "F:\Program Files (x86)\Steam\steamapps\common\Themurderofsonicthehedgehog\The Murder of Sonic The Hedgehog\The Murder of Sonic The Hedgehog_Data\StreamingAssets\aa\StandaloneWindows64\"
Resolve-Path -LiteralPath 1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle
which presently gives the error:
Resolve-Path : Cannot find path
'1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle' because it does not
exist.
At line:1 char:1
+ Resolve-Path -LiteralPath 1f3e56ae019cd278e6abd86e2a64eb7c_unitybuilt ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (1f3e56ae019cd27...b159399c.bundle:String) [Resolve-Path], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand
Share
Improve this question
edited Mar 21 at 23:06
mklement0
442k68 gold badges710 silver badges926 bronze badges
asked Mar 20 at 6:51
Carly314Carly314
233 bronze badges
3
|
1 Answer
Reset to default 0If feasible, you can bypass your problem by enabling support for long paths by default, without the need to use the \\?\
prefix, for which there are two options:
Migrate to PowerShell (Core) 7 (the modern, cross-platform, install-on-demand edition of PowerShell).
- That said, while this edition is largely backward-compatible with Windows PowerShell (the legacy, ships-with-Windows, Windows-only edition of PowerShell whose latest and last version is 5.1), there are enough differences that warrant careful analysis and planning before undertaking such a migration.
Assuming you are an administrator, you can enable long-path support system-wide, via the registry, as described in this answer. Enabling it via GPO (Group Policy Object) is an option too.
Otherwise:
The long-path opt-in prefix,
\\?\
fundamentally only works with full (absolute), normalized paths (normalized meaning that there must be no.
or..
path components).Thus, you need to prepend
\\?\<full-path-to-current-dir>\
to your relative path to make it work, though that somewhat defeats the purpose of usingResolve-Path
; it will, however, still tell you whether the resulting path exists.There are caveats:
Due to an apparent bug (which has been fixed in PowerShell (Core) 7), non-existence of the specified path results in quiet failure, i.e. in no output[1] instead of the usual non-terminating error. This also applies to using the
Convert-Path
cmdlet (see below).When given a
\\?\
-prefixed path, theSystem.Management.Automation.PathInfo
instance returned byResolve-Path
additionally prepends the provider prefix identifying theFileSystem
provider,Microsoft.PowerShell.Core\FileSystem::
in its.Path
property.This surprising behavior also affects PowerShell (Core) 7, though there you can avoid by simply not using the
\\?\
prefix, given that it is never needed..Path
is the property used when such an instance is stringified (e.g. with.ToString()
or inside"..."
, an expandable string), resulting in the potentially unwanted extra prefix.To avoid that, use the
.ProviderPath
property, or, equivalently, useConvert-Path
, whose purpose is to directly return the provider-native path, as a string.
The use of the automatic
$PWD
variable below assumes that the current location (as reflected in$PWD
and reported byGet-Location
) is a file system location, which is typically, but not necessarily true.- If you need to guard against a provider other than the
FileSystem
provider underlying the current location, you can use(Get-Location -PSProvider FileSystem)
in lieu of$PWD
.
- If you need to guard against a provider other than the
Therefore:
# Get the full path of the current directory and prefix it with '\\?\', if necessary.
$pathPrefix = '\\?\' + ($PWD.ProviderPath -replace '^\\\\[?]\\')
Resolve-Path -LiteralPath "$pathPrefix\1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle"
# To directly get the resolved path as a file system-native path string:
Convert-Path -LiteralPath "$pathPrefix\1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle"
Note:
For brevity, an expandable string (string interpolation) is used to synthesize the full path, but you may choose to use
Join-Path
instead, i.e.:(Join-Path $pathPrefix 1f3e56ae019cd278e6abd86e2a64eb7c_unitybuiltinshaders_85695fb1f6d830835b9e5284b159399c.bundle)
[1] Technically, the enumerable null is returned (the [System.Management.Automation.Internal.AutomationNull]::Value
singleton), which is PowerShell's way of signaling that a command produced no output; in expression contexts, this value behaves like $null
.
cd
using the\\?\
prefix?cd -LiteralPath '\\?\F:\.....'
– Santiago Squarzon Commented Mar 20 at 12:36