Windowsに260文字のパス長制限があるのはなぜですか?


390

私は不都合な瞬間にこの問題に数回直面しています:

  • 深いパスを持つオープンソースのJavaプロジェクトで作業しようとしています
  • ソース管理にDeep Fitnesse Wikiツリーを格納する
  • Bazaarを使用してソース管理ツリーをインポートしようとするとエラーが発生する

なぜこの制限が存在するのですか?

なぜまだ削除されていないのですか?

パスの制限にどのように対処しますか?いいえ、LinuxまたはMac OS Xに切り替えることは、この質問に対する有効な回答ではありません;)


8
@Artelius:実際、Windows(少なくともWin2K以降)はジャンクションポイント(en.wikipedia.org/wiki/NTFS_junction_point)をサポートしており、Vista以降はNTシンボリックリンク(en.wikipedia.org/wiki/NTFS_symbolic_link)をサポートしています。とにかく、シンボリックリンクは長いパスやネストされたパスをより親しみやすくするのに役立ちますが、パスの長さの制限に達している場合にシンボリックリンクがどのように役立つかは考えられません。
Ashutosh Mehra

8
この制限が存在しなかったとしても、他にも多くの制限があり、それらのいずれかがいつか迷惑になる可能性があります。重要なのは、この制限がなぜそれほど低いのかということです。8.3の時代の後、メガ/ギガサイズのハードウェアでは、パスは実質的に無制限のサイズで動的に割り当てられた文字列になります。
Roland

12
マイクロソフトは、Windows 10ビルド14352でこの問題にようやく対処しました。–
Warren P

3
はい。アプリのマニフェストを変更して、長いパスを認識させる必要があるようです。
Warren P

3
@PatrickSzalapski残念ながら、それは修正されましたvisualstudio.uservoice.com/forums/121579-visual-studio/...
phuclv

回答:


231

この記事を引用https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

最大パス長の制限

Windows APIでは(次の段落で説明するいくつかの例外はあります)、パスの最大長はMAX_PATHで、260文字として定義されています。ローカルパスは、ドライブ文字、コロン、バックスラッシュ、バックスラッシュで区切られた名前コンポーネント、終端のnull文字の順に構成されています。たとえば、ドライブDの最大パスは "D:\ 256文字のパス文字列 <NUL>"です。 "<NUL>"は、現在のシステムコードページの非表示の終了NULL文字を表します。(文字<>はここでは視覚的にわかりやすくするために使用されており、有効なパス文字列の一部にすることはできません。)

これで、1 + 2 + 256 + 1または[ドライブ] [:\] [パス] [null] = 260であることがわかります。256は、DOS日からの妥当な固定文字列長であると想定できます。DOS APIに戻ると、システムがドライブごとの現在のパスを追跡していることがわかり、26(シンボルを含む32)の最大ドライブ(および現在のディレクトリ)があります。

INT 0x21 AH = 0x47は、「この関数はドライブ文字と最初のバックスラッシュなしでパスの説明を返します。」したがって、システムはCWDをペア(ドライブ、パス)として保存し、ドライブ(1 = A、2 = B、…)を指定してパスを要求することがわかります。0を指定すると、 INT 0x21 AH = 0x15 AL = 0x19によって返されるドライブ。これで、4バイトがパス文字列に格納されないため、なぜ256ではなく260であるかがわかります。

640Kで十分なRAMがあるのに、なぜ256バイトのパス文字列か。


21
Windows APIは、最新のOSでも長さを制限します。Microsoftは、1980年代や1990年代のようにAPIを完全に理解する天才がいないため、現在使用されている何億ものオペレーティングシステムを変更することを恐れています。リスクを変更する価値はありません。 serverfault.com/questions/163419/...
冒険野郎マクガイバー

77
@MacGyver申し訳ありませんが、それはまったくナンセンスです。Microsoftは、保証されていないシステムについてのことを前提としている、何百万という不適切に記述されたアプリケーションを壊したくありません。残念ながら、開発者が依存するようになったのは長い間同じことだったので、今それを変更するとサードパーティのアプリケーションが機能しなくなり、MSが原因となります。
基本的な

25
ところでゲイツはこれまで「640K RAMは皆のために十分である」と述べたという証拠はありませんcomputerworld.com/article/2534312
パトリック・ファブ

11
@Basic Windowsでは260文字の制限が保証されていました。定数は次のように宣言された定数、構造が唯一の260文字の余地がある、Windowsのヘッダファイルで宣言されました。それを変更する方法はありません。
Ian Boyd、

35
@Basic定数は、アプリケーションにコンパイルしても変更されません。私は最後に1994年にビルドされたアプリケーションを実行し、今日でもWindows 10で実行しています。Microsoftは、メモリブロックの特定のバイナリサイズを約束し、プログラマーはそのルールに従いました。Microsoftが定数を変更すると、プログラミングAPIに正しく従った既存のすべてのアプリケーションが機能しなくなります。バイナリ互換性を壊すことはできません。
Ian Boyd

150

NTFSファイルシステムは32k文字までのパスをサポートするため、これは厳密には当てはまりません。win32 api \\?\を使用し、パスに" "を付けると、260文字を超える文字を使用できます。

.Net BCLチームのブログからの長い道のりの詳細な説明。
小さな抜粋は、長いパスの問題を強調しています

もう1つの懸念は、長いパスのサポートを公開することによって生じる一貫性のない動作です。\\?\接頭辞付きの長いパスは、ほとんどのファイル関連のWindows APIで使用できますが、すべてのWindows APIでは使用できません。たとえば、ファイル名がMAX_PATHより長い場合、モジュールを呼び出しプロセスのアドレスにマップするLoadLibraryは失敗します。つまり、MoveFileを使用すると、DLLをそのパスが260文字を超えるような場所に移動できますが、DLLをロードしようとすると失敗します。Windows API全体に同様の例があります。いくつかの回避策がありますが、それらはケースバイケースです。


4
十分に公平ですが、それは多くの場所でP / Invokeを使用する必要があることを意味します。これは、私の考えでは、.Netコードの移植性を低下させます。モノ互換性を維持したい場合はどうなりますか?
ジェフリーキャメロン

1
私のポイントは、本当に望めば長いパスを使用できるということでした。しかし、それは苦痛であり、個人的にはこれも避けたいと思います。
softveda 2009

5
これが選択された答えになるはずです。この制限が存在する理由と、回避策を提供する理由について、ユーザーからの質問に実際に回答します。視認性への
賛成

2
MicrosoftはAPIを修正する必要があるように思えますが、これは優先事項ではないと思います。私は、この制限は、まだWindowsの8に存在していることに驚いた
マス

3
@Mas必要な「修正」は、Windows XPまでさかのぼって行われました。APIのUnicodeバージョンを呼び出すと、「拡張パス」にアクセスできるようになります。Explorerがこれを自動的に処理すると思います。これをサポートする関数の1つを次に示します-msdn.microsoft.com/en-us/library/windows/desktop/…
ナタリーアダムス

108

問題はなぜ制限がまだ存在するのかということです。確かに最新のWindowsではMAX_PATH、より長いパスを許可するようにサイドを増やすことができます。制限が解除されていないのはなぜですか?

  • 削除できない理由は、Windowsが変更されないことを約束しているためです。

Windowsは、APIコントラクトを通じて、標準のファイルAPIが260文字よりも長いパスを返さないことをすべてのアプリケーションに保証しています。

次の正しいコードを検討してください。

WIN32_FIND_DATA findData;

FindFirstFile("C:\Contoso\*", ref findData);

Windows 、プログラムが私のWIN32_FIND_DATA構造を生成することを保証しました

WIN32_FIND_DATA {
   DWORD    dwFileAttributes;
   FILETIME ftCreationTime;
   FILETIME ftLastAccessTime;
   FILETIME ftLastWriteTime;
   //...
   TCHAR    cFileName[MAX_PATH];
   //..
}

私のアプリケーションは定数の値を宣言しませんでしたMAX_PATH、Windows APIは宣言しました。私のアプリケーションはその定義された値を使用しました。

私の構造は正しく定義されており、592合計バイトのみを割り当てます。つまり、260文字数未満のファイル名しか受け取ることができません。Windows は、アプリケーションを正しく記述した場合、アプリケーションは今後も引き続き機能することを約束しました。

Windowsが260文字より長いファイル名を許可すると、既存のアプリケーション(正しいAPIを正しく使用した)が失敗します。

MicrosoftにMAX_PATH定数の変更を要求する人は、まず既存のアプリケーションが失敗しないことを確認する必要があります。たとえば、私はまだWindows 3.11で実行するように作成されたWindowsアプリケーションを所有して使用しています。64ビットWindows 10でも動作します。これにより、下位互換性が得られます。

Microsoft 、完全な32,768パス名を使用する方法を作成ました。しかし、それを行うには新しいAPIコントラクトを作成する必要がありました。まず、シェルAPIを使用してファイルを列挙する必要があります(すべてのファイルがハードドライブまたはネットワーク共有に存在するわけではないため)。

ただし、既存のユーザーアプリケーションを壊してはなりません。アプリケーションの大部分は、ファイル作業にシェルAPIを使用しませ。誰もがFindFirstFile/ FindNextFileを呼び出すだけで、1日にそれを呼び出します。


4
@JosiahKeller実行すると、そのメソッドに最初に定義されたコントラクトが破られ、意図しないメモリが上書きされて、セキュリティホールが開く可能性があります。これを修正する唯一の方法は、新しい改善されたAPI(Unicode対応のバリアントなど)を提供することであり、誰もが新しいAPIを使用してすべてのアプリケーションを再コンパイル/再リリースすることを願っています。
Rowland Shaw

2
@Ryios自分の既存のWindowsアプリケーションがLinuxで動作するとは思いません。
Ian Boyd

9
後方互換性は素晴らしいです。しかし、今日、このような(たいていは厄介な)問題を回避することは、Windows 3.1アプリケーションをサポートすることよりも重要だと思います。長い道のりで問題が発生するのは何人ですか?そして、何人がまだWindows 3.1アプリケーションを使用していますか?Windows XPのサポートもキャンセルされました。それで、なぜ彼らは単にアナウンスをしないのですか?Windows [x]以降のアプリケーションでは、260文字を超えるパスはないと想定しているため、長いパスに遭遇すると期待どおりに動作しませんか?私たちの制限速度はまた、キャリッジを考慮していません。
JuSchu

2
@JuSchu Windows 3.1アプリケーションだけではありません。今日、正しいAPIを使用して記述されたアプリケーションは機能しません。
Ian Boyd


62

Windows 10から、レジストリキーを変更することで制限取り除くことができます。

ヒント Windows 10バージョン1607以降、一般的なWin32ファイルおよびディレクトリ関数からMAX_PATHの制限がなくなりました。ただし、新しい動作にオプトインする必要があります。

レジストリキーを使用すると、新しいロングパス動作を有効または無効にできます。長いパスの動作を有効にするには、レジストリキーをHKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled(Type :)に設定しますREG_DWORD。キーの値は、影響を受けるWin32ファイルまたはディレクトリ関数への最初の呼び出しの後に、システムによって(プロセスごとに)キャッシュされます(リストは以下)。レジストリキーは、プロセスの有効期間中は再読み込みされません。システム上のすべてのアプリがキーの値を認識するためには、キーが設定される前に一部のプロセスが開始されている可能性があるため、再起動が必要になる場合があります。レジストリキーは、のグループポリシーを介して制御することもできますComputer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths。マニフェストを使用して、アプリごとに新しいロングパス動作を有効にすることもできます。

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
        <ws2:longPathAware>true</ws2:longPathAware>
    </windowsSettings>
</application>

15
悲しいことに、最新バージョンのWin10でも、ファイルエクスプローラー自体は長いパス名の処理に問題があります。コンテキストメニューの[パスとしてコピー]でも期待どおりに機能しません。最初の260文字だけをコピーします。フォルダを作成したり、ファイルをコピー/移動/開いたりすることはできません...この変更のポイントは何なのかと不思議に思います。
raymai97 2017年

システム設定がマニフェスト設定から独立しているという主張は間違っていることに注意してください。両方が必要です。ポリシーはシステムレベルで有効にする必要があり、マニフェストはアプリケーションがロングパス対応であることを宣言する必要があります。
Eryk Sun

この変更を行うと、古い32ビットアプリケーションで互換性の問題が発生する可能性があると読みましたが、互換性に関するこの種の問題は一般的なものですか?自分で変更したいのですが。lifehacker.com/...
KDP

32

フォルダをドライブとしてマウントできます。コマンドラインから、パスがある場合は、次を使用してパスC:\path\to\long\folderをドライブ文字にマッピングできますX:

subst x: \path\to\long\folder

このコマンドを実行すると、「無効なパラメーターj:」が表示されます
バリーピッカー

これは、管理者(昇格)コマンドプロンプトから実行する必要があります。
Mrchief 2014年

これはスラッシュで失敗します。バックスラッシュである必要があります。
チェンバレン

1
これがWindows 10のみに当てはまるかどうかはわかりませんが、このコマンドを実行しようとしたときに、上記のように管理者として実行した場合、ドライブが利用できないようです。これは、動作がネットワークドライブのマッピングに似ており、セッション固有であるなどの理由により、管理者として実行してこのコマンドを使用した場合、そのセッションはx:TL; DRを使用できます。ドライブが表示されない場合は、管理者モードでなくてもコマンドを実行する。
ジャディー

substローカルセッション/アカウントです- 「システム全体」にする方法については、superuser.com /
questions / 29072 /…を

18

パス制限に対処する1つの方法は、シンボリックリンクを使用してパスエントリを短くすることです。

例えば:

  1. C:\p長いパスへの短いリンクを保持するディレクトリを作成する
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. C:\p\foo長いパスの代わりにパスに追加する

3
最初にディレクトリを作成する必要がなかったため、手順1は必要ありません。
オハール2015

2
このトリックは、常に多くのアプリケーション試みとしての仕事は、リンクを解決していません
nponeccop

この/jオプションは、ローカルボリュームデバイスまたはローカルボリューム上のパス(Unixバインドマウントなど)のジャンクションマウントポイントを作成します。シンボリックリンクは作成しません。ジャンクションマウントポイントは常にサーバーで評価され、ローカルデバイスをターゲットにする必要があるため、これは重要な違いです。シンボリックリンクはクライアントで評価され、リモートパスをターゲットにする場合があります(ポリシーで許可されている場合)。subst.exeドライブ(つまりDefineDosDeviceW)と同様に、ジャンクションターゲットは通常、約4K文字に制限されています。実際には8K文字で、代替パスと表示パスの間でほぼ均等に分割されます。
Eryk Sun、

12

PowerShellを使用して長いパス名を有効にできます。

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1 

別のバージョンは、Computer Configuration/ Administrative Templates/ System/ でグループポリシーを使用することFilesystemです:

グループポリシーエディター


2
それでも各アプリケーションは、ロングパスを認識することを宣言する必要があります。Microsoftは、アプリケーションマニフェストがOS(システムレベルポリシー)とアプリケーションの間の契約であり、両者が同意する必要があることを明確に説明するのではなく、アプリケーションマニフェストがこの機能を有効にする別の方法であるように見せることで、これをうまく伝えていません。
Eryk Sun、

8

なぜこれがまだ存在する- MSは、優先順位を検討していない、と(少なくともこの例では)彼らのOSを進め超える値の下位互換性。

私が使用する回避策は、標準の人間が読めるバージョンではなく、パス内のディレクトリに「短い名前」を使用することです。したがって、たとえばC:\Program Files\私は次のように使用しC:\PROGRA~1\ ますdir /x


1
レジストリで短いパス名を無効にすることができます(またはファイルシステム自体でしたか?)ので、これは信頼できる回避策ではありません。
rubenvb 2017

3
@rubenvb私は確信して、すべてのWindowsの機能がレジストリで無効にすることができない最も場合はそう¯\ _(ツ)_ /¯
コンラッド

NTFSの場合、システム全体またはボリュームごとに、短い名前の生成を無効にすることができます(多くの場合非効率的であるためです)。そのため、NTFSである必要があるシステムドライブ上のパスに対しても、信頼性の低いアプローチになります。NTFSのファイルとディレクトリに短い名前を手動で設定することは可能ですが、exFATやReFSなど、短い名前をまったくサポートしていない新しいファイルシステムには適用されません。短い名前は、1バイトおよび2バイトのコードページを使用する古いANSI / OEM APIのように、限られたケースでの互換性のために保持される非推奨の機能と考える必要があります。
Eryk Sun、

@eryksun短いパス名の無効化に関する以前のコメントを参照してください。:)あなたがそれが廃止予定であると考えられるべきであると思うからといって、それが実際に廃止されているという意味ではありません。MSはこの機能を廃止する予定はありません。(また、なぜexFAT / ReFSパーティションにWindowsソフトウェアをインストールするのですか?)
Conrad

私は今でも正規化されていないデバイスパス(つまり "\\?\"プレフィックス)のみを使用するように言っています。たとえば、翻訳PATHしてに渡しSearchPathWます。とにかく、ランタイムライブラリはNTの「\\?\」デバイスパスを作成するため、これも効率的です。新しいファイルシステムについては、セキュリティがないため、ポータブルアプリケーション以外のソフトウェアがexFATボリュームにインストールされていることはおそらくありませんが、ReFSを除外しません。ユーザーは、利便性、スペース、またはパフォーマンスの理由から、プログラムを標準以外の場所にインストールします。
Eryk Sun、

7

Windowsでのパスサイズの制限に対処する方法については、7zipを使用してパス長の機密ファイルをパック(およびアンパック)することは、実行可能な回避策のようです。私はこれを使用して、いくつかのIDEインストール(Eclipseプラグインパス、そうですね!)と自動生成されたドキュメントの山を転送しましたが、今のところ1つの問題は発生していません。

Windowsによって設定された260文字の制限(技術的なPoVから)をどのように回避するのか本当にわかりませんが、それは機能します!

SourceForgeページの詳細はこちら

「NTFSは実際には32,000文字までのパス名をサポートできます。」

7-zipもこのような長い名前をサポートしています。

ただし、SFXコードでは無効になっています。一部のユーザーは、長いパスを使用する方法を理解していないため、長いパスを好みません。これが、SFXコードで無効にした理由です。

およびリリースノート

9.32 alpha 2013-12-01

  • 260文字を超えるファイルパス名のサポートの改善。

4.44ベータ2007-01-20

  • 7-Zipは、260文字を超えるファイルパス名をサポートするようになりました。

重要な注意:これを正しく機能させるには、目的のフォルダーにファイルをドラッグアンドドロップするのではなく、7zipの [解凍]ダイアログで宛先パスを直接指定する必要があります。それ以外の場合、「Temp」フォルダは暫定キャッシュとして使用され、Windowsエクスプローラがファイルを「最終的な休止場所」に移動し始めると、同じ260文字の制限に跳ね返ります。詳細については、この質問への回答を参照してください。


3
私は間違っていました。7zipとWinRARはすべてのフォルダとファイルを抽出します。Windowsのフォルダーのプロパティは、制限に違反していないフォルダーとファイルの数のみを報告するだけです。最大パスに達したときに、Windowsエクスプローラーがフォルダーを検出するために深く掘り下げていないかのようです。
Twisted Whisper、2015年

7-zipの長いパスは、shift-delで削除できます。
Laurie Stearn、

短い答え
-7zipを


2

これに対処する別の方法は、ファイルで何をしたいかに応じてCygwinを使用することです(つまり、Cygwinコマンドがニーズに合っているかどうか)。

たとえば、Windowsエクスプローラーではできないファイルのコピー、移動、または名前の変更が可能です。またはもちろん、md5sum、grep、gzipなどのコンテンツを処理します。

また、コーディングしているプログラムの場合、それらをCygwin DLLにリンクすると、長いパスを使用できるようになります(ただし、これはテストしていません)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.