開発者は言うまでもなく、Windows PCの多くのユーザーは、長い(260文字を超える、MAX_PATH)ファイルまたはディレクトリパスを操作するときの問題に精通しています。
この記事では、さまざまなプラットフォーム(WinApi、.Net Framework、.Net Core)でアプリケーションを開発し、Windows 10(Anniversary Update)で長いパスのネイティブサポートをアクティブにするときに、この残りを取り除く方法について説明します。
APIアプリケーションを獲得する
Win APIを使用してファイルを処理するアプリケーションでは、MAX_PATH制限を取り除くためのレシピは太古から知られています-ディレクトリまたはファイルを操作し、\\?\プレフィックスでパスを開始するには、末尾が「W」の関数のUnicodeバージョンを使用する必要がありました これにより、最大32767文字のパスを使用できるようになりました。
Windows 10(1607)では、ファイルを操作するための関数の動作が変更されました。システムレベルでMAX_PATH制約チェックを無効にできるようになりました。
これは、次の機能に影響を与えました。
ディレクトリを操作するには: CreateDirectoryW、CreateDirectoryExW、GetCurrentDirectoryW、RemoveDirectoryW、SetCurrentDirectoryW。 そして、ファイルを扱うために: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。
これにより、\\?\プレフィックスを使用する必要がなくなり、Win APIを介して直接または間接的に実行されるアプリケーションに、長いパスを再構築せずにサポートする機会が与えられます。 この機能を有効にする方法については、記事の最後で説明します。
.Net Framework
.Net FrameworkはWin APIを使用してファイルを処理しますが、以前の変更では結果が得られませんでした。 BCLコードには、ディレクトリ名とファイル名の許容性に関する事前チェックが組み込まれていますが、Win API関数の呼び出しにさえ到達せず、よく知られている例外をスローします。 コミュニティの一般的な需要(UserVoiceで4,500以上)により、バージョン4.6.2で、パス長の制限チェックがBCLコードから切り離され、オペレーティングシステムとファイルシステムに与えられました!
提供するものは次のとおりです。
- プレフィックス「\\?\」を使用する場合、Win APIのように長いパスを使用できます。
Directory.CreateDirectory("\\\\?\\" + long_dir_name);
- 長いWindows 10(1607)ファイル名のネイティブサポートを有効にすると、プレフィックスを使用する必要さえありません!
有効にする方法:
- アプリケーションをビルドするときは、.Net Framework 4.6.2をターゲットとして使用してください。
- たとえば、アプリケーションが.Net 4.0で既にビルドされている場合、構成ファイルを使用します。
<?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> <runtime> <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" /> </runtime> </configuration>
.Netコア
ここでは、長いパスのサポートが2015年11月に発表されました。 どうやら、プロジェクトのオープンソースの性質は、下位互換性に対する厳密な必要性の欠如に影響を与えたようです。
有効にする方法:
すべてが箱から出して動作します。 .Net Frameworkの実装とは異なり、プレフィックス「\\?\」を追加する必要はありません-必要に応じて自動的に追加されます。
ここに例を見ることができます。
Windows 10でロングパスサポートを有効にする方法(1607)
この機能はデフォルトで無効になっています。 これは、この機能が実験的であり、完全なサポートのためにさまざまなサブシステムとアプリケーションを改良する必要があるためです。
次のレジストリキーパラメーターを作成または変更することにより、長いパスの組み込みサポートを有効にできます。HKLM\ SYSTEM \ CurrentControlSet \ Control \ FileSystemパラメーターLongPathsEnabled(タイプ:REG_DWORD)1-有効な値に対応します。
または、グループポリシー(Win + R \ gpedit.msc)を使用して、[ コンピューターの構成]> [管理用テンプレート]> [システム]> [ファイルシステム]> [NTFS長いパスを有効にする]。 ローカライズ版でもあります: コンピュータの構成>管理用テンプレート>システム>ファイルシステム> Win32ロングパスを有効にします。
さらに、ソースはマニフェストに同意しません(または誤解されましたが、現時点では確認する方法がありません)。 たとえば、 MSDNのドキュメントには、マニフェストを個々のアプリケーションの長いパスのサポートをアクティブにする代替方法として使用できると記載されており、 MSDNブログでは、これがポリシーのアクティブ化後の2番目の必須ステップであると述べています。
ただし、これらはこのオプションのタスクの形式に収束します。
<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>
残念ながら、現時点では、パスを操作する特性があるため、CMDでは機能しませんが、PowerShellではすべて機能するはずです。
PS
これで私の短い金曜日の投稿は終わりです。Windows10(1607)でのロングパスサポートの完全性の問題、またはWindowsエディション、ファイルシステム、APIのさまざまな組み合わせを使用するときのパフォーマンスの問題は除外します。 新しい事実と実験結果が利用可能になると、投稿が更新されます。
ご清聴ありがとうございました!