パスの最大長の制限
Windows API では (次の段落で説明するいくつかの例外を除いて)、パスの最大長は MAX_PATH です。この値は 260 文字と定義されています。 ローカル パスの構成は、ドライブ文字、コロン、円記号、円記号で区切られた名前コンポーネント、終端の null 文字という順序です。 たとえば、ドライブ D の最も長いパスは "D:\256 文字のパス文字列<NUL>" です。"<NUL>" は現在のシステム コードページに対する非表示の終端 null 文字を表します。 (ここでは視覚的にわかりやすくするために <> という文字を使用していますが、有効なパス文字列に含めることはできません。)
たとえば、長いファイル名を持つ git リポジトリを、長い名前のフォルダーに複製する場合、この制限に抵触する可能性があります。
Note
Windows API のファイル I/O 関数は、名前を NT スタイルの名前に変換する際に、"/" を "\" に変換します。ただし、次のセクションで説明するように、プレフィックスとして "\\?\" が使用されている場合は例外です。
Windows API の多くの関数には、拡張パスに対応する Unicode バージョンもあり、その場合は最大合計パス長として 32,767 文字が許容されます。 この種類のパスは円記号で区切られたコンポーネントで構成されます。各コンポーネントの最大長は、GetVolumeInformation 関数の lpMaximumComponentLength パラメーターで返される値 (通常は 255 文字) です。 拡張パスを指定するには、"\\?\" プレフィックスを使用します。 たとえば、"\\?\D:\very long path" などです。
Note
最大パスの 32,767 文字は概算値です。"\\?\" プレフィックスは実行時にシステムによって長い文字列に拡張される可能性があり、この拡張は合計長に適用されるためです。
"\\?\" プレフィックスは、汎用命名規則 (UNC) に従って構築されたパスにも使用できます。 UNC を使用してこのようなパスを指定するには、"\\?\UNC\" プレフィックスを使用します。 たとえば、"\\?\UNC\server\share" など ("server" はコンピューターの名前、"share" は共有フォルダーの名前) です。 これらのプレフィックスは、パス自体のパーツとしては使用されません。 これらは、パスを最小限の変更でシステムに渡す必要があることを示しています。つまり、パスの区切り記号としてスラッシュを使用することも、現在のディレクトリを表すピリオドや親ディレクトリを表す二重ドットを使用することもできません。 相対パスでは "\\?\" プレフィックスを使用できないため、相対パスは常に MAX_PATH 文字の合計までの長さに制限されます。
ファイル システムでは、パスとファイル名が WCHAR の不透明なシーケンスとして処理されるため、Windows ファイル I/O API 関数で使用するために、パスとファイル名の文字列に対して Unicode 正規化を実行する必要はありません。 アプリケーションに必要な正規化はすべて、関連する Windows ファイル I/O API 関数の呼び出しとは別に、この点を考慮して実行する必要があります。
API を使用してディレクトリを作成する場合、指定するパスは、8.3 の長さのファイル名を追加できる長さにしておく必要があります (つまり、ディレクトリ名の長さは、MAX_PATH の値から 12 を引いた値を超えることはできません)。
シェルとファイル システムでは、要件が異なります。 Windows API で作成されるパスが、シェルのユーザー インターフェイスでは適切に解釈できないものであるという可能性もあります。
Windows 10 バージョン 1607 以降で長いパスを有効にする
Windows 10 バージョン 1607 以降では、多くの一般的な Win32 ファイルおよびディレクトリ関数で MAX_PATH 制限が廃止されています。 ただしアプリでは、新しい動作をオプトインする必要があります。
アプリケーションごとに新しい長いパスの動作を有効にするには、2 つの条件を満たす必要があります。 レジストリ値が設定されていることと、アプリケーション マニフェストに longPathAware
要素が含まれていることです。
長いパスを有効にするためのレジストリ設定
重要
このレジストリ設定の有効化は、新しい機能を利用できるように変更されたアプリケーションにのみ影響することに注意してください。 開発者は、下のアプリケーション マニフェスト設定の説明に従い、アプリが長いパスに対応することを宣言する必要があります。 これは、すべてのアプリケーションに影響する変更ではありません。
レジストリ値 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD)
が存在し、1
に設定されている必要があります。 このレジストリ値は、影響を受ける Win32 ファイルまたはディレクトリ関数 (関数の一覧については、以下を参照してください) の最初の呼び出しの後に、システムによって (プロセスごとに) キャッシュされます。 プロセスの存続中には、レジストリ値の再読み込みは行われません。 キーを設定する前に開始済みのプロセスが存在する可能性があるため、システム上のすべてのアプリにキー値を認識させるには、再起動が必要になる場合があります。
このコードを .reg
ファイルにコピーすることで設定することも、昇格された権限でターミナル ウィンドウから PowerShell コマンドを使用することもできます。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
Note
このレジストリ設定は、Computer Configuration > Administrative Templates > System > Filesystem > Enable Win32 long paths
でグループ ポリシーを使用して制御することもできます。
長いパスの機能を宣言するためのアプリケーション マニフェストの更新
アプリケーション マニフェストに、longPathAware
要素を含める必要があります。
<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>
MAX_PATH 制限のない関数
長いパスの動作をオプトインした場合に MAX_PATH 制限がなくなるディレクトリ管理関数は、CreateDirectoryW、CreateDirectoryExW、GetCurrentDirectoryW、RemoveDirectoryW、SetCurrentDirectoryW です。
長いパスの動作をオプトインした場合に MAX_PATH 制限がなくなるファイル管理関数は、CopyFileW、CopyFile2、CopyFileExW、CreateFileW、CreateFile2、CreateHardLinkW、CreateSymbolicLinkW、DeleteFileW、FindFirstFileW、FindFirstFileExW、FindNextFileW、GetFileAttributesW、GetFileAttributesExW、SetFileAttributesW、GetFullPathNameW、GetLongPathNameW、MoveFileW、MoveFileExW、MoveFileWithProgressW、ReplaceFileW、SearchPathW、FindFirstFileNameW、FindNextFileNameW、FindFirstStreamW、FindNextStreamW、GetCompressedFileSizeW、GetFinalPathNameByHandleW です。