プロが教える店舗&オフィスのセキュリティ対策術

C言語でプログラムを組んで、
以下の2点を実施したいと考えています。
・任意の名前の環境変数を作成したい。
・既存の環境変数(自分が任意に名前をつけて作成した環境変数)を
 削除したい。
実現するにはどうしたらよいでしょうか?
(作成はputenvでよいでしょうか?
削除については調べたのですが分かりませんでした。)
お手数ですがご回答いただけると幸いです。

A 回答 (7件)

★追記アドバイス


・レジストリを操作すると出来そうですよ。
・ただし、設定を反映するには再ログイン、再起動が必要のようです。
・レジストリの操作はここで説明するのはとても大変です。
・やはり、自分でシステム全体の環境変数を操作するライブラリ関数を
 作った方が良いでしょう。→大変ですが……。
・最後に、下の『参考URL』をどうぞ。→『環境変数をシステムに通知する方法 』

参考URL:http://support.microsoft.com/kb/104011/ja
    • good
    • 0
この回答へのお礼

追記アドバイスありがとうございます。

ライブラリ関数作成等、
実施したい内容を具現化するのはなかなか難しそうですね。
質問するにしても知識不足な為、自己調査を行った後、
実施内容を具体的に明示できるようにしたいと考えます。
レジストリ操作は難しそうですね…学習したいと思います。

また新たに質問を投稿するかと思いますが、
その際はまたご回答頂けると幸いです。
Oh-Orangeさんをはじめご回答頂いた皆様ありがとうございました。

お礼日時:2006/12/21 00:49

★回答者 No.3 です。


・やはり、システム全体の環境変数を操作したいのですね。
・『getenv』、『putenv』関数はシステムの環境変数のコピーを操作します。
・『環境変数のエントリー・ポインタ』とはコピーした領域のことです。
・『MS-DOS』時代からシステムの環境変数を操作するのは結構面倒でした。
・『MS-DOS』時代では、システム全体の環境変数のアドレスを取得してから
 環境変数の文字列を独自に操作する関数ライブラリで設定&削除していました。
・『Windows』時代では、アドレスを取得しても変更禁止でエラーになると思います。
・よって、システム全体の環境変数を操作するにはそれ専用の関数があれば
 出来ますが……。今のところ私は知りません。→検索してもすぐには見つかり
 ませんでした。
・回答ではありませんが、とにかく『getenv』、『putenv』関数ではシステムの
 環境変数を操作できませんよ。分かりましたか?
・これ以上アドバイスできません。申し訳ありませんです……。
    • good
    • 0
この回答へのお礼

質問の内容が不足しており伝わりづらかったようで
申し訳ありません。

自分で調べていてご明示頂いた関数では難しそうだと
思っていたのですがハッキリとシステム環境変数・ユーザ環境変数
が操作できないと分かり収穫となりました。
ありがとうございます。

お礼日時:2006/12/21 00:40

★回答者 No.3 です。

回答者 No.2 さんの指摘ありがとう。

●修正した正しい指摘です。
・間違い
 memset( env_name_make, '\0', sizeof(STR_MAX+1) );
 memset( env_name_del, '\0', sizeof(STR_MAX+1) );
 memset( path, '\0', sizeof(PATH_MAX+1) );
・正しい(タイプ1)
 memset( env_name_make, '\0', sizeof(env_name_make) );
 memset( env_name_del, '\0', sizeof(env_name_del) );
 memset( path, '\0', sizeof(path) );
・正しい(タイプ2)
 memset( env_name_make, '\0', STR_MAX );
 memset( env_name_del, '\0', STR_MAX );
 memset( path, '\0', PATH_MAX );
・正しい(タイプ3)
 char env_name_make[ STR_MAX + 1 ] = { 0 };
 char env_name_del[ STR_MAX + 1 ] = { 0 };
 char path[ PATH_MAX + 1 ] = { 0 };
 と宣言すると『memset』関数を使わなくても初期化します。→回答者 No.2 さんと同じ。
※正しく動作させるには、上記のタイプ1~タイプ3のどれかを記述します。
 また、『sizeof』演算子はバッファなどのサイズを求めるため『定数』を指定すると
 整数のバイト数になります。→int型が16ビット環境なら 2バイト、32ビット環境なら 4
 バイトが返されます。よって、sizeof(STR_MAX+1) ではなく sizeof(env_name_make) です。

●追記アドバイス
・『strcat』より、『strcpy』関数を使うと初期化する必要はありませんよ。
    • good
    • 0
この回答へのお礼

ご指摘頂いた内容に対しての補足ありがとうございます。
どのようにすれば良いかを具体的に明示頂けると
単純に実施方法が分かったり、自分の実施方法と比較ができる等
非常に参考になります。

お礼日時:2006/12/21 00:35

あのー


> 間違い:sizeof(STR_MAX+1) ではなく、
> 正しい:sizeof(STR_MAX) で良い。
整定数の sizeof とってどうしようと?

sizeof env_name_make
とするか

memsetの引数に STR_MAXそのまま与えるか
じゃないんでしょうか?

そもそも、

char env_name_make[STR_MAX] = "";
とか
char env_name_make[STR_MAX] = {0};

でいいような気がしますが。
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。
質問の趣旨とは外れましたが、
こういうご指摘を頂けるのは非常にありがたいです。
正しいコーディングを心掛けて実施したいと思います。

お礼日時:2006/12/21 00:27

★指摘!


・上から11行目でエラーを発見!→『/*』が『*』になっています。
・『memset』の部分が危険ですよ。
 間違い:sizeof(STR_MAX+1) ではなく、
 正しい:sizeof(STR_MAX) で良い。
 
 または、
 char env_name_make[STR_MAX + 1];
 char env_name_del[STR_MAX + 1];
 char path[PATH_MAX + 1];
 と宣言します。
・戻り値の『ret』を『unsetenv』で上書きしていますが、良いの?

★原因
・私も、OS は WindowsXP、開発環境は Visual Stadio .NET 2003 を使っています。
・『setenv』、『unsetenv』、『putname』の3つの関数は元々ありませんよ。
・よって、『識別子は、引数依存の照合を使用しても見つかりません。』とエラーとなります。
・つまり、『getenv』、『putenv』の2つしか関数が最初からないってことだ。
・『getenv』は環境変数のエントリー・ポインタを取得します。
・『putenv』は環境変数のエントリー・ポインタに文字列を設定(削除)します。

★回答
・『putname』ではなく『putenv』でしょう。
 putenv( "ENVNAME=string" ); ←環境変数『ENVNAME』に、『string』という値を設定
 putenv( "ENVNAME=" ); ←環境変数『ENVNAME』を削除
 getenv( "ENVNAME" ); ←環境変数『ENVNAME』を取得(ポインタで)
・以上。おわり。分かりましたか?

参考URL:http://www9.plala.or.jp/sgwr-t/index.html

この回答への補足

ご丁寧にご回答頂きありがとうございます。
ご指摘頂いた内容については以下の通りです。
>・上から11行目でエラーを発見
>・戻り値の『ret』を『unsetenv』で上書きしていますが、良いの?
 質問するにあたり余計なコーディングを削除した際の影響です。
 申し訳ありません。戻り値上書きも特に問題ありません。
>・『memset』の部分が危険ですよ。
 ご指摘ありがとうございます。
 見直してみて危険な事をやってることに気付きました。

教えていただいたputenv、getenvを用いて、
環境変数を取得/変更/削除することができました。
但し一点問題がありまして、
「システムのプロパティ」画面の「詳細設定」タグの「環境変数」ボタンを
押下し、環境変数を確認したところユーザ環境変数、システム環境変数
共にプログラムの内容が反映されませんでした。

上記関数を用いてプログラムにて関数を変更しても、
Windows側(上記画面)には反映されないのでしょうか?
(反映されたとしてもプログラム実行中の一時的なものなのでしょうか?)

最終的に実施したい内容として、
上記画面のユーザ環境変数、システム環境変数をプログラムで操作し
その結果を上記画面に反映させたいと考えています。
言葉足らずで申し訳ありません。

補足日時:2006/12/20 11:44
    • good
    • 0

Visual C++ 6 では作成も変更も削除も _putenv( const char *envstring );で出来ます。


削除の場合は*envstringにvarname=とします。
.NETでも同じではないでしょうか

この回答への補足

※回答1の追加質問も合わせて載せてしまいすいません。

以下のようにプログラムを組んだところ、
エラーメッセージが出ました。
・e:\program_test\testprg_c\env_var.cpp(58): error C3861: 'setenv': 識別子は、引数依存の照合を使用しても見つかりません。
・e:\program_test\testprg_c\env_var.cpp(62): error C3861: 'unsetenv': 識別子は、引数依存の照合を使用しても見つかりません。
・e:\program_test\testprg_c\env_var.cpp(65): error C3861: 'putname': 識別子は、引数依存の照合を使用しても見つかりません。
#defineで正しく宣言されていると思うのですが、
解決策が分かりません。
解決策を教えていただけると幸いです。

/*++++++++++++++++++++++++++++++++++++++++++++++++++++
// インクルード
++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
/*++++++++++++++++++++++++++++++++++++++++++++++++++++
// 関数のプロトタイプ
++++++++++++++++++++++++++++++++++++++++++++++++++++*/
extern int env_var();
*++++++++++++++++++++++++++++++++++++++++++++++++++++
// define
++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#define STR_MAX 256
#define PATH_MAX 512
/*++++++++++++++++++++++++++++++++++++++++++++++++++++
// メイン文
++++++++++++++++++++++++++++++++++++++++++++++++++++*/
extern int env_var()
{
// 変数宣言
int ret;// 戻り値(0:正常、-1:異常)
char env_name_make[STR_MAX];// 作成する環境変数名
char env_name_del[STR_MAX];// 削除する環境変数名
char path[PATH_MAX];// ファイルパス
char *varname;// putname使用変数

// 変数初期化
ret = 0;
memset(env_name_make, '\0', sizeof(STR_MAX+1));
memset(env_name_del, '\0', sizeof(STR_MAX+1));
memset(path, '\0', sizeof(PATH_MAX+1));

// 環境変数名、パス設定
strcat(env_name_make, "BBB");
strcat(env_name_del, "AAA");
strcat(path, "C:\\Program Files\\");

// setenv関数(環境変数を作成)
// setenv(const char *name, const char *value, int overwrite);
ret = setenv(env_name_make, path, 0);

// unsetenv関数(環境変数を削除)
// int unsetenv(const char *name);
ret = unsetenv(env_name_del);

// putname関数(環境変数の作成/変更/削除)
putname(varname = env_name_del);

return ret;
}

補足日時:2006/12/20 09:34
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
環境変数を一時的に操作する方法が分かりためになりました。

お礼日時:2006/12/21 00:43

実行環境は?



とりあえず unsetenv
http://www.linux.or.jp/JM/html/LDP_man-pages/man …

この回答への補足

早急なご回答ありがとうございます。
実行環境の記述を忘れていて申し訳ありません。
OSはWindowsXP、開発環境はVisual Stadio .NET 2003を用いています。
教わった関数を試してみます。

補足日時:2006/12/20 01:10
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
以後、質問をより具体的に明示するよう気をつけたいと思います。

お礼日時:2006/12/21 00:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!