web-dev-qa-db-ja.com

Windowsで環境変数に制限があるのはなぜですか?

1024文字制限の技術的な理由

過去3年間Linuxを使用して以来、Windows 7 Proに関する多くの問題が私の日常業務で悩んでいます。最も不可解なのは、ファイル名の制限と環境変数forgettingです。 MSDNが結合システムENVの制限は1024であると言っていることを理解していますが、なぜですか大きなユーザーパス変数セットを持っています。しばらくオンにしない限り、問題なく動作します。その後、突然再起動するまでPATH値の認識が停止します。

この課せられた制限を引き起こすENV値は、ウィンドウにどのように格納されますか?その値は通常の使用でどのように破損しますか?

MSDN https://support.Microsoft.com/en-us/kb/906469

更新完全を期すために、上記の問題が発生した状況について説明します。私は通常、システム設定の環境ダイアログでUser Env PATHを設定します。 msbuild、vstest.console.exe、tf.exeなど、開発中に実行したもの。私はConEmuでPowerShell v4をほぼ独占的に使用しています。数時間または1日の稼働時間の後、これらのコマンドは認識されたとおりに突然応答を停止します。 Envダイアログまたはコマンドラインで値をリセットまたは変更しても、機能は復元されません。 $ env:PATHをエコーすると、正しい値が表示されます。私が見つけた唯一の解決策は再起動でした。

12
DouglasCodes

1024文字制限の技術的理由

参照する制限は1024バイトではありません。あなたがそれにリンクした記事で説明したように、修正プログラムが利用可能なバグでした。

この記事では、制限は2048バイトであると明示的に述べていますCreateEnvironmentBlock関数の場合

さらに、このバグは2つの古いバージョンのWindows(XPとServer 2003)に固有のものでした。

アプリケーションがCreateEnvironmentBlock関数を呼び出してMicrosoft Windows Server 2003ベースまたはMicrosoft Windows XPベースのコンピューターの環境変数を取得すると、返されるパス環境変数は1,024バイトに切り捨てられます。この現象は、環境変数の最大サイズが2,048バイトであっても発生します。この問題により、アプリケーションが正しい環境変数を取得できなくなります。

ソース 返されたパス環境変数は、Windows Server 2003ベースまたはWindows XPベースのコンピューターでは1,024バイトに切り捨てられます


それで、2048文字の制限はありますか?

実際の制限は32,760文字です。ただし、実際にその理論上の最大値を達成することはほとんどありません。

  • 環境変数はバッチプロセッサのコマンドラインバッファに合わせる必要があるため、バッチファイルはコマンドラインの最大長によって制約されます。

    Microsoft Windowsを実行しているコンピューターXP以降では、コマンドプロンプトで使用できる文字列の最大長は8191文字です。

    コマンドプロンプトは、親プロセスから継承され、独自の8191文字の制限よりも長い環境変数を無視します。

  • 環境レジストリキーを設定すると、そのレジストリキーを解析し、そこから環境ブロックを構築するコードに2048文字の制限があります。

以下に記載されているソース。


その値(PATH)は通常の使用でどのように破損しますか?

後で説明するように、これはシステムPATHが1920文字より長くなるように変更された場合に発生する可能性があります。

これがなぜ起こっているのかを正確に診断するのに十分な情報が質問に含まれていません。


ユーザーPATH変数セットが大きい

PATH環境変数には特定の制限があります。

ユーザーPATH変数をシステムPATH変数と正常にマージするには、システムPATH変数が1920文字未満である必要があります。

Windows Server 2003では、システムPATHが1920文字を渡すと、ユーザーPATH環境変数は、システム全体ではなく、それとマージされてプロセスPATH環境変数を設定することがなくなります。 PATH(より大きい場合でも)は、プロセスPATH変数に含まれます。

ソース エコー%PATH%はシステムのみ、またはユーザー変数にも展開されますか? 回答 David Heffernan


ファイルパスの制限は何ですか?

最大パス長の制限

Windows APIでは(次の段落で説明するいくつかの例外はあります)、パスの最大長はMAX_PATHで、260文字として定義されています。

  • ローカルパスは、ドライブ文字、コロン、バックスラッシュ、バックスラッシュで区切られた名前コンポーネント、終端のnull文字の順に構成されています。

  • たとえば、ドライブDの最大パスはD:\some 256-character path string<NUL> どこ <NUL>は、現在のシステムコードページの非表示の終了null文字を表します。 (キャラクター <および>はここでは視覚的にわかりやすくするために使用されており、有効なパス文字列の一部にすることはできません。)

    注:Windows APIのファイルI/O関数は、名前をNTスタイルの名前に変換する一環として「/」を「\」に変換します。ただし、次のセクションで詳しく説明する「\?\」プレフィックスを使用する場合を除きます。

Windows APIには、32,767文字の最大合計パス長の拡張パスを許可するUnicodeバージョンも備えた多くの関数があります。

  • このタイプのパスは、バックスラッシュで区切られたコンポーネントで構成され、それぞれがlpMaximumComponentLength関数のGetVolumeInformationパラメーターで返される値までです(この値は通常255文字です)。拡張パスを指定するには、「\?\」プレフィックスを使用します。たとえば、「\?\ D:\ very long path」です。

注:実行時にシステムによって "\?\"プレフィックスがより長い文字列に拡張され、この拡張が全長に適用されるため、最大パスは32,767文字です。

ソース ファイル、パス、名前空間の命名


環境変数の最大長はいくつですか?

環境変数の理論上の最大長は、約32,760文字です。ただし、実際にその理論上の最大値を達成することはほとんどありません。

  • すべての環境変数は、32767文字の制限がある単一の環境ブロックに一緒に存在する必要があります。

  • しかし、その数はすべての環境変数の名前と値の合計であるため、すべての環境変数を削除し、Xと呼ばれる単一の変数に32,760文字の非常に大きな値を設定すると、理論上の最大長に達すると思います。

  • もちろん、実際には、環境ブロックをブロック内の他のすべての変数と共有する必要があるため、32,760文字の文字列を使用したSetEnvironmentVariableへのランダムな呼び出しは成功しそうにありません。

しかし、それだけが実際的な制限ではありません。

  • また、変数の設定方法にも依存します。つまり、環境変数設定テクニックがSetEnvironmentVariable呼び出しに到達する前に通過するコードです。

  • バッチファイルを使用している場合、環境変数はバッチプロセッサのコマンドラインバッファに収まる必要があるため、コマンドラインの最大長に制約されます。

  • 一方、環境レジストリキーを設定している可能性があります。その場合、そのレジストリキーを解析し、そこから環境ブロックを構築するコードで2048文字の制限に達します。

  • ダイアログボックスには、環境変数をインタラクティブに設定するための制限もあります。環境変数の数値は、たまたま頭の上ではわかりません。

ソース 環境変数の最大長は? Raymond Chen(Microsoft従業員)による。


コマンド・プロンプト (Cmd.exe)コマンドライン文字列の制限

Microsoft Windowsを実行しているコンピューターではXP以降、コマンドプロンプトで使用できる文字列の最大長は8191文字です。MicrosoftWindows 2000またはWindows NT 4.0を実行しているコンピューターでは、最大長コマンドプロンプトで使用できる文字列の2047文字です。

この制限は、コマンドライン、他のプロセスによって継承される個々の環境変数(PATH変数など)、およびすべての環境変数の展開に適用されます。コマンドプロンプトを使用してバッチファイルを実行する場合、この制限はバッチファイルの処理にも適用されます。

次のリストは、この制限がコマンドプロンプトで実行するコマンドとバッチファイルで使用するコマンドにどのように適用されるかを示す例です。

  • コマンドプロンプトでは、コマンドプロンプトで使用する次のコマンドラインの全長に、2047文字または8191文字を含めることはできません(オペレーティングシステムに応じて)。

    cmd.exe /k ExecutableFile.exe parameter1, parameter2 ... parameterN
    
  • バッチファイルでは、バッチファイルで使用する次のコマンドラインの全長に、2047文字または8191文字(オペレーティングシステムに応じて)を超えることはできません。

    cmd.exe /k ExecutableFile.exe parameter1, parameter2 ... parameterN
    

    この制限は、コマンドプロンプトを使用してバッチファイルを実行するときに、バッチファイルに含まれるコマンドラインに適用されます。

  • コマンドプロンプトで、EnvironmentVariable2とEnvironmentVariable3を展開した後のEnvironmentVariable1の全長には、2047文字または8191文字を含めることはできません(オペレーティングシステムに応じて)。

    c:> set EnvironmentVariable1=EnvironmentVariable2EnvironmentVariable3
    
  • バッチファイルでは、コマンドラインで環境変数を展開した後の次のコマンドラインの合計長に、2047文字または8191文字(オペレーティングシステムに応じて)を超えることはできません。

    ExecutableFile.exe parameter1 parameter2
    
  • Win32の環境変数の制限は32,767文字ですが、コマンドプロンプトは、親プロセスから継承され、2047または8191文字の独自の制限(オペレーティングシステムに応じて)を超える環境変数を無視します。 SetEnvironmentVariable function を参照してください。

ソース コマンドプロンプト(Cmd.exe)コマンドライン文字列の制限

29
DavidPostill