0

これはとても単純に思えますが、そのような苦痛であることが判明しました。

Windows 7では、以下をコマンドプロンプトに貼り付けて、ProgramFiles(x32)いずれかに設定するか%programfiles%、設定%programfiles(x86)%内容をエコーすることができます。

%comspec% /c if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%") && set Program && echo %programfiles(x32)% && pause

ただし、これと同じコマンドをショートカットに入れると、次のようになります。

ProgramFiles(x32)を表示するコマンドプロンプトが以前に設定されましたが、後続のエコーでは表示されません

何が起こっている?

4

1 に答える 1

2

まず、コマンドプロンプトからコードを実行するという観点から始めます。そのコンテキストでのコードには4つの問題があります。

1)これで大きな違いはないと思いますが、コマンドラインの最後の3つのコマンドを常に実行したいと思います。&&ただし、前のコマンドが成功した場合にのみ次のコマンドを実行する条件演算子を使用しました。&代わりに使いたいと思います。

2)優先順位の問題があります。IF / ELSEステートメントを実行し、それが完了したら、さらに3つのコマンドを実行します。ただし、記述されている3つの追加コマンドは、IFステートメントのELSE句の一部と見なされます。IF/ELSEステートメント全体を囲む追加の括弧のセットが必要です。

(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "ProgramFiles(x32)=%programfiles(x86)%")) & ...

3)その後のすべてを%comspec% /c、CMD.EXEに渡されるコマンドラインの一部にする必要があります。ただし、コマンドラインコンソールでステートメント全体を実行すると、CMD.EXEの呼び出しは。の最初の出現で終了し&ます。行の残りの部分は、CMD.EXEの呼び出しではなく、親コマンドウィンドウによって実行されます。&文字をとしてエスケープするか、^&渡される行全体を引用符で囲む必要があります。

4)%VAR%展開は、行が解析されるときに発生し、コマンド行全体が一度に解析されてから、コマンドが実行されます。したがって、表示される%ProgramFiles(x32)%の値は、コマンドが実行される前の値です。通常、値は定義されておらず、コマンドラインコンテキストを使用しているため、パーセントを含む元の文字列が出力されます。修正は、オプションを使用CALL ECHO %^ProgramFiles(x32)%して遅延拡張を使用するか、有効にして、を使用することです。注意点は、文字列がCMD.EXEに渡され、親コマンドラインで展開されないようにすることです(ProgramFiles(x32)が既に定義されている場合に備えて)。/V:ONECHO !ProgramFiles(x32)!

次のそれぞれは、コマンドプロンプトから探している結果を与えるはずです。

%comspec% /v:on /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause"

%comspec% /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause"

%comspec% /v:on /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) ^& set Program ^& echo !programfiles(x32)!^& pause

%comspec% /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) ^& set Program ^& call echo %^programfiles(x32)%^& pause

ショートカットから実行した場合の状況は少し異なります。ショートカットには親コマンドプロンプトがないため、上記のポイント3)は適用されません。コマンドライン全体が引用符で囲まれている場合でも、&文字をエスケープしないでください。

ポイント1、2、および4は、ショートカットに対して引き続き有効です。

したがって、次のステートメントはすべてショートカットとして機能します。

%comspec% /v:on /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause"

%comspec% /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause"

%comspec% /v:on /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause

%comspec% /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause

2セットのステートメントを比較すると、両方のコンテキストで有効なのはそのうちの2つだけです。次の2つのステートメントは、コマンドラインとショートカットの両方で機能します。

%comspec% /v:on /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause"

%comspec% /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause"

上記の両方のステートメントは、コマンドプロンプトから発行された場合、またはVistaマシンのショートカットとして発行された場合、次の結果をもたらします。

ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x32)=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
C:\Program Files
Press any key to continue . . .
于 2012-08-16T12:40:04.163 に答える