いつもお世話になっております。
現在、以下のような処理を考えいます。
1.batファイル内で環境変数設定
2.batファイル内からあるexeを実行
3.exe内にて1で作成した環境変数へ値を設定
4.batファイルにてexeが設定した値を使用して、処理実行
<方針?>
exeにて処理した値を、ファイルなどに残しておきたくない。
しかし、exeで実行した結果は、必要なため使用したい
以下の点を知っていたため、上記方針による処理が可能である
思い、上の処理を考えました。
・batファイルで環境変数を設定(SETコマンド実行)した場合、
設定した環境変数はbat処理内のみで有効となる
・通常プロセス間で環境変数は共有できない
しかし、以下のような問題点がありました。
<問題点>
exeで環境変数を設定するがbatファイルないの環境変数に
反映されない
exe内で環境変数への値の設定方法
・systemコマンドでSETコマンドを実行
・getenv、_putenvを実行
・envp引数にて環境変数の取得、設定
いずれの方式でも、batで設定した環境変数の取得ができず、
また、exeで設定した値の反映ができませんでした。
そのため、質問したい事項は以下の2点です。
<質問事項>
・batファイルとbat内で実行したexeで環境変数を共有できるか
・共有できない場合、その他の代案はなにかあるか
開発環境は、Windows2000+VC6
大変申し訳ありませんが、ご存知の方がいらっしゃいましたら
ご教授ください。
よろしくお願いいたします。
> ・batファイルとbat内で実行したexeで環境変数を共有できるか
bat 内部で set した環境変数は exe にて読み取れる
exe 内部で putenv した環境変数は bat に戻せない(仕様)
> ・共有できない場合、その他の代案はなにかあるか
代案は詳細要望がわからんと答えられん
普通は EXE の終了コードを ERRORLEVEL で受け取るだけで十分だったりする
任意の文字列を受け取りたいというのなら CMD.EXE では無理
SFU/cygwin でも導入して eval ~command~ とでもするかな
確か実行ファイルの環境変数は起動した環境の環境変数のコピーだったと思います。
なので実行ファイルの環境変数を変更しても起動した環境の環境変数は変えられない
はずです。結論として環境変数でデータを返す事はできない。
(tetrapodさんの結論と一緒ですね)
exeから起動環境にデータを返す方法はファイルに書き出して返す以外
で考えられるのは返却値くらい?
というか受け取り側の条件がわからないと何ともいえないですけど。
受け取り側がレジストリからデータを引き出せるならレジストリ経由
と言うのも有りだろうし。レジストリならすぐには見つからないだろうし、
受け取ったら消せば良いかなと。
なにせ、実行ファイル自体は終わってしまっているから
通常のプロセス間通信は出来ない。
実行ファイルが次に実行ファイルを起動してデータの引渡しを
確認後、自分は終了すると言うのならプロセス間通信で
何とかなるかもしれません。
いったいどんな事を実現する為にこういうことを考えたのかが
解れば、別の手段の提案もありえるかと思いますけれど、
提示された情報が少ないのでそれを期待するのは無理なのでは?
EXEから呼び出し側Batに戻る事は諦めて、続きの処理をEXEの子プロセスとし
て生成してしまえば環境変数の引継ぎは出来ませんか?
目的によっては使えない方法ですが…。
>EXEから呼び出し側Batに戻る事は諦めて
call なにがし.exe
で、呼び出し側に戻せますよ。
> call なにがし.exe
callはbatからbatを呼ぶときに戻ってこられるようにするための物で、exeに使うよう
なものでは無いはずです。
「EXEから呼び出し側Batに戻る事は諦めて」は「EXEから環境変数を上書きし
て呼び出し側Batに戻る事は諦めて」というつもりで書きました。
誤解させたならすいません。
1.bat--------------
@echo off
echo 1::DATA=%DATA%
SET DATA=BAT1
echo 1::DATA=%DATA%
2.exe
echo 1::DATA=%DATA%
cmd /C 3.bat
echo 1::DATA=%DATA%
call 3.bat
echo 1::DATA=%DATA%
pause
2.c--------------
#include <stdio.h>
#include <stdlib.h>
int main(int a,char** b){
char *enp;
enp=getenv(DATA);
printf(2::DATA=%s\n,enp?enp:");
_putenv(DATA=EXE2);
enp=getenv(DATA);
printf(2::DATA=%s\n,enp?enp:NLL);
system(3.bat);/*環境変数を引き継ぐなら何でも良い*/
enp=getenv(DATA);
printf(2::DATA=%s\n,enp?enp:NLL);
}
3.bat--------------
@echo off
echo 3::DATA=%DATA%
SET DATA=BAT3
echo 3::DATA=%DATA%
実行例--------------
1::DATA=
1::DATA=BAT1
2::DATA=BAT1←親プロセスからは引き継げている
2::DATA=EXE2
3::DATA=EXE2←親プロセスからは引き継げている
3::DATA=BAT3
2::DATA=EXE2←子プロセスでの結果が残っていない
1::DATA=BAT1←子プロセスでの結果が残っていない
3::DATA=BAT1←親プロセスからは引き継げている
3::DATA=BAT3
1::DATA=BAT1←子プロセスでの結果が残っていない
3::DATA=BAT1←親プロセスからは引き継げている
3::DATA=BAT3
1::DATA=BAT3←batをcall(プロセスを変えない)した場合は残っている
この例だとexeやbatが使いまわせませんが、ラベルを駆使すれば何とか…。
見栄え悪いし面倒だしわかり難いしと色々駄目なので、他の方法を薦めます。
いつもお世話になっております。
返事・報告が遅くなり申し訳ありません。
tetrapod様,PATIO様,麩様,悠様 いろいろとご回答ありがとうございました。
結果から言うと、環境変数の共有はできませんでしたが、
exeにて実行した結果を環境変数へ設定することで
対応することができました。
以下がその方法になります。
FOR /F usebackq tokens=1,2,3* %i IN (~test.exe~) DO @set Ret1=%i & @set Ret2
=%j & @set Ret3=%k
上記の方法で、batファイルにてexeから返却された値(複数の値)を
処理できました。
今回の場合、exeの処理結果をファイルに残せないものでした。
またexeはbatから呼び出され、bat内でexeの処理結果を使用するという
特殊なことをしていたため、環境変数を利用できないかと考えていました。
(このことを伝えていれば別な解放があったのかもしれませんね。。)
結果として、上記手法で対応ができました。
ご面倒をお掛けして申し訳ありませんでした。
また、ご協力いただきありがとうございました。