最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

windows - How to resolve a path with more than 259 characters in Powershell when specifying a file in the current directory? - S

programmeradmin3浏览0评论

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
  • There are two ways of reducing the length of the folders. 1) Make a folder shared which will make it accessible at the root of the file system 2) Create a Mapped Drive using one of the subfolders. – jdweng Commented Mar 20 at 11:33
  • 1 Have you tried to cd using the \\?\ prefix? cd -LiteralPath '\\?\F:\.....' – Santiago Squarzon Commented Mar 20 at 12:36
  • 260 Character Limit, Get-ChildItem stackoverflow/a/54909306/6654942 – js2010 Commented Mar 20 at 13:18
Add a comment  | 

1 Answer 1

Reset to default 0

If 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 using Resolve-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, the System.Management.Automation.PathInfo instance returned by Resolve-Path additionally prepends the provider prefix identifying the FileSystem 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, use Convert-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 by Get-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.

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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论