getenvNo.40297
(-L-) さん 23/02/04 17:49
 
getenv( "ProgramFiles" )で拾うと

c:\>set
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)

のProgramFiles(x86)の値が拾われるようなのですが仕様でしょうか。

[ ]
RE:40297 getenvNo.40298
でるもんたいいじま さん 23/02/04 19:08
 
こんにちは。秀丸ユーザーの「でるもんた・いいじま」です。

> getenv( "ProgramFiles" )で拾うと
>
> c:\>set
> ProgramFiles=C:\Program Files
> ProgramFiles(x86)=C:\Program Files (x86)
>
> のProgramFiles(x86)の値が拾われるようなのですが仕様でしょうか。

これは「64bit版のWindows」と「32bitのアプリ」を組み合わせたケース全般での
「仕様」です。

☆ ☆ ☆

こちら↓
https://www.bojankomazec.com/2011/10/32-bit-and-64-bit-versions-of-windows-c.html
に、やや詳しい実験結果が載っています。
(英語のサイト、しかもテストコードはC++、というハンデはご勘弁ください。)

これによると、64bitネイティブ環境での環境変数は
  HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
から取得できるようにも見えるのですが、そこで得られる情報はごくわずかです。

☆ ☆ ☆

ここで、下記のテクニックを使います。

@32bitアプリからは、c:\windows\sysnative\ というパスの下に64bitネイティブの
各種システムツールが見える。それを実行することもできる。

A逆に64bitアプリからは、c:\windows\syswow64\ というパスの下に32bit版の各種
システムツールが見える。こちらもやはり、実行できる。

このAを使って実際に %windir%\syswow64\cmd.exe を起動してみると、環境変数は
次のようになっています。(手元の環境から、64bit版と違いがありそうな部分だけ
抜粋。)

CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
ComSpec=C:\WINDOWS\system32\cmd.exe  ←実体は syswow64 フォルダのほうにある
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_ARCHITEW6432=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 142 Stepping 10, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=8e0a
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files (x86)
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files

特に環境変数 PROCESSOR_ARCHITEW6432 の有無を調べるのは、バッチファイルでは割
と定番だったりします。

今回ご質問の目的だと、まず環境変数 ProgramW6432 を見て、もしそれが未定義であ
れば改めて ProgramFiles を見に行く、という安直なコードで何とかなりそうな気が
します。

秀丸マクロのキーワード「platform」で調べることもできますが、よほど丁寧さが求
められるマクロでない限り、上記の環境変数決め打ちで行けると思います。

☆ ☆ ☆

ここからは秀丸の話を外れて蛇足というか、お節介というか、そういう情報提供にな
ります。

現状、コマンドプロンプトですら64bitネイティブ版と32bit版とが存在して、しかも
外見では区別がつかないので、私が対策として使っている方法をご紹介します。

レジストリエディタで
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor
という場所を開いて、そこに「AutoRun」という名前の文字列値(あるいは「展開可
能な文字列値」)があるかどうか確認します。

既にそこにバッチファイルの名前がある場合は、レジストリはそのままにして、ここ
に書かれているバッチファイルにこれからトリックを仕込みます。逆に、その名前の
値が存在しない場合は新しく作り、これから作るバッチファイルのフルパスを書き込
みます。私の場合は %USERPROFILE%\AutoRun.cmd としています。

ちなみに、値の種類として「文字列値」を選んだ場合でも、%USERPROFILE% の部分を
実パスに書き換えなくて大丈夫です。

最後に、レジストリで指定されている(あるいは先ほど指定した)バッチファイルを
開いて、下記の3行を加えます。
set prompt+=$t $p$g$s
if defined PROCESSOR_ARCHITEW6432 set prompt+=[WoW64] %prompt+%
prompt %prompt+%

※1行目の内容はお好みで書き換えてください。

こうすると次回以降、64bit・32bitどちらのcmd.exeが起動された場合でも、起動直
後にこのバッチファイルを読んでくれます。その結果、32bitのほうのcmd.exeが起動
された時には、プロンプトの冒頭に「[WoW64] 」という文字列が出てくれるようにな
ります。

☆ ☆ ☆

ではでは。長々と失礼いたしました。

[ ]
RE:40298 getenvNo.40299
(-L-) さん 23/02/04 20:47
 
仕様とのコメントありがとうございました。

今回のケースも難しいことはせず、

 (取得したパス)\..\Program Files

と相対パスで一つ上に登ってから、意図するパスに降りていけば良い話なので、すで
にそれで回避しておりました。

[ ]
RE:40299 getenvNo.40300
でるもんたいいじま さん 23/02/04 22:08
 
いいじまです。

> 今回のケースも難しいことはせず、
>  (取得したパス)\..\Program Files
> と相対パスで一つ上に登ってから、

あ、なるほど、確かにそれで行けますね。

重ね重ね、長々と失礼いたしました<(_ _;)>

[ ]