Windowsには、パス*1の長さが最大260文字までという制限がある。この制限については、以下の公式ページで詳しく解説されている。
learn.microsoft.com
以下、リンク先本文より引用。
Windows API では (次の段落で説明するいくつかの例外を除いて)、パスの最大長は MAX_PATH です。この値は 260 文字と定義されています。
確かにWindowsには上記の制限があるが、例えば外付けドライブで上記の上限を超えたファイルがあった場合、エクスプローラーからファイルを削除することができる。しかし、Remove-Itemではファイルを削除できずエラーになる。
レジストリを修正して最大値を変更する方法もあるが、この記事ではレジストリを修正せずにRemove-Itemでファイルを削除する方法を簡単に書く。なお、この記事ではWindows PowerShell 5.1を使用している。
方法
以下のように、削除するファイルの絶対パスの先頭に\\?\をつける。
$filepath = "(削除するファイルの絶対パス)"
$filepath = "\\?\" + $filepath
Remove-Item $filepath -Recurse -Force
解説
Windowsで使用されているパスの形式
Windowsには複数のパス形式があり、以下の公式ページで詳しく解説されている。
learn.microsoft.com
上記のページから、それぞれのパス形式について簡単にまとめる。
- 従来のDOSパス
- Windowsでよく見かけるパスの形式。
- 例:C:\test\123.txt、..\test\123.txt など
- UNC パス
- ネットワーク上のリソースにアクセスするときによく使用されているパスの形式。
- 例:\\192.168.1.1\test\123.txt、\\server01\test\123.txt など
- DOSデバイスパス*2
- Windowsの内部で使用されているパスの形式。従来のDOSパスやUNCパスの先頭に
\\?\もしくは\\.\をつける。この記事では、このパス形式を使用した。
- 例:\\?\C:\test\123.txt など
なお、相対パスはデバイスパスには使用できない。それについては、先ほどの公式ページでも以下の通り記載されている。
DOS デバイス パスは定義によって完全修飾されており、相対ディレクトリ セグメント (. または ..) で始めることはできません。 現在のディレクトリが使用されることはありません。
なぜパスの長さ制限を回避できるのか
これについては、以下の公式ページで記載されている。
learn.microsoft.com
以下、リンク先本文より引用。
Windows API の多くの関数には、拡張パスに対応する Unicode バージョンもあり、その場合は最大合計パス長として 32,767 文字が許容されます。 この種類のパスは円記号で区切られたコンポーネントで構成されます。各コンポーネントの最大長は、GetVolumeInformation 関数の lpMaximumComponentLength パラメーターで返される値 (通常は 255 文字) です。 拡張パスを指定するには、"\\?\" プレフィックスを使用します。 たとえば、"\\?\D:\very long path" などです。
パスの先頭に\\?\を付けると、拡張パスとして260文字を超える文字列を認識できるようになるとのこと。
また、別の公式ページにも記載がある。
learn.microsoft.com
以下、リンク先本文より引用。
ファイル I/O でパス文字列に "\\?\" というプレフィックスを付けると、文字列の解析を無効にし、それに続く文字列をそのままファイル システムに送信するように Windows API に指示できます。 たとえば、ファイル システムが長いパスとファイル名をサポートする場合、Windows API によって適用される MAX_PATH 制限を超える可能性があります。
これらの情報から、パスの先頭に\\?\を付けると文字列のチェックを行わないため、結果として260文字を超えるパスを認識できるようになることが読み取れる。
おわりに
パスの長さ制限に引っかかることはめったにないが、まれに階層が深すぎるファイルや名前が長すぎるファイルに遭遇することがある。レジストリを修正するのも一つの手だが、私はファイルを削除するだけであればそこまでする必要はないと思う。
なお、Windowsのパスの書き方については以下のページが詳しい。
gigazine.net
正直、Microsoftの公式ページは開発者向けに書かれているためか内容がやや難しい。上記のページではパスの書き方が具体的に書かれているので、参考にどうぞ。