如何在程序中设置系统的环境变量?(200分)

  • 主题发起人 主题发起人 han
  • 开始时间 开始时间
H

han

Unregistered / Unconfirmed
GUEST, unregistred user!
我检索到问题http://www.delphibbs.com/delphibbs/dispq.asp?lid=831565
与我的类似,但是没有得到解决。
我的问题是:
如何设置系统的环境变量,并让其马上生效。如果用函数SetEnvironmentVariable的话,
所设置的环境变量只在当前进程生效,而不会改变系统的环境变量。
如果用修改注册表的方法,则需要注销后重新登录才能生效。
总之我的目的是,在dos下执行我的程序myapp.exe后,再输入命令set MyEnvVariable,就会看到
myapp所设置的环境变量MyEnvVariable的值,而不是看到提示“环境变量 MyEnvVariable 没有定义”。

解决后马上给分。
 
呵呵,,让我看看,,,,
 
先说你用的是什么系统?因为调用一些API函数是与操作系统相关的!!
 
这个比较困难吧?好像没有的
我也找了好久,没有找到怎么改
 
To HeyTommy,我用的是win2000 Server
 
再加100分!
 
:),给分吧:
代码:
{*********************************************}
{ Set Global Environment Function             }
{ Coder : Kingron,2002.8.6                    }
{ Bug Report : Kingron@163.net                }
{ Test OK For Windows 2000 Advance Server     }
{ Parameter:                                  }
{ Name : The environment name                 }
{ Value: The environment Value                }
{ Ex: SetGlobalEnvironment('MyVar','OK')      }
{*********************************************}
function SetGlobalEnvironment(const Name,Value:string):boolean;
const
  REG_LOCATION='System/CurrentControlSet/Control/Session Manager/Environment';
var
  R:DWORD;
begin
  with TRegistry.Create do
  try
    RootKey :=HKEY_LOCAL_MACHINE;
    Result :=OpenKey(REG_LOCATION,True);
    if Result then
    begin
      WriteString(Name,Value);
      SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,integer(Pchar('Environment')));
//      SendMessageTimeOut(HWND_BROADCAST,WM_SETTINGCHANGE,0,integer(Pchar('Environment')),SMTO_NORMAL,1000,R);
    end;
  finally
    Free;
  end;
end;
 
Kingron

我收藏下来试试先。
 
to Kingron
出现编译错误:
[Error] datetime.dpr(21): Undeclared identifier: 'WM_SETTINGCHANGE'

应该use哪个unit?
 
唉!use Messages
 
还是不行,我的程序如下。
program datetime;

{$APPTYPE CONSOLE}

uses
SysUtils,Windows,Registry,Messages;

function SetGlobalEnvironment(const Name,Value:string):boolean;
const
REG_LOCATION='System/CurrentControlSet/Control/Session Manager/Environment';
var
R:DWORD;
begin
with TRegistry.Create do
try
RootKey :=HKEY_LOCAL_MACHINE;
Result :=OpenKey(REG_LOCATION,True);
if Result then
begin
WriteString(Name,Value);
SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,integer(Pchar('Environment')));
//SendMessageTimeOut(HWND_BROADCAST,WM_SETTINGCHANGE,0,integer(Pchar('Environment')),SMTO_NORMAL,1000,R);
end;
finally
Free;
end;
end;

var
DatetimeStr:String;
TempStr:String;
Flag:TReplaceFlags;
begin
{ TODO -oUser -cConsole Main : Insert code here }
TempStr:=DatetimeToStr(now());
Flag:=[rfReplaceAll, rfIgnoreCase];
TempStr:=StringReplace(TempStr,' ','_',Flag);
TempStr:=StringReplace(TempStr,':','-',Flag);
DatetimeStr:=TempStr;
//Writeln(DatetimeStr);
//SetEnvironmentVariable('ora92',PChar(DatetimeStr));
SetGlobalEnvironment('datetime',PChar(DatetimeStr));
writeln(GetEnvironmentVariable('datetime'));

end.
 
测试情况如下:
J:/Projects/Delphi Projects/Little tools/显示时间并设置相应的环境变量>datetime


J:/Projects/Delphi Projects/Little tools/显示时间并设置相应的环境变量>set dateti
me
环境变量 datetime 没有定义


查看注册表,发现此环境变量已经修改,只是没有在当前的DOS窗口中生效。
 
我Kao,这是你的程序没有接受WM_SETTINGCHANGE消息。你自己不处理,你的程序当然不知道了!
你在你的窗口过程里面处理WM_SETTINGCHANGE消息,然后进行处理即可!不明白的清自己看
MS SDK帮助,上面说的很详细,很明白!

实际上,你可以这样测试:
首先,运行cmd.exe,然后用set MyVar看不到MyVar环境变量,关闭控制台
之后,你运行程序,调用
SetGlobalEnvironment('MyVar','TestOK');
然后重新运行Cmd.exe,用Set MyVar就会发现环境变量已经设置好了,证明我的代码是正确的。

你没有理解环境变量的含义,每一个程序都有一个环境变量块,而且是互相独立的,我的代码是
设置全局的系统变量,如果你的程序需要的话,自己使用SetEnvirionment设置即可。这算我的
一个小BUG吧。我修正一下。

你在控制台里面运行,永远不会成功的,因为控制台没有处理WM_SETTINGCHANGE消息,不相信
的话,你可以用控制面板来测试!因此你不要在这个方面钻牛角尖了。但是你的程序是可以正常
运行的。没有关系。

修改后的代码如下:
在 WriteString(Name,Value); 后面添加下面一行即可:
SetEnvironmentVariable(pchar(Name),pchar(Value));
还有问题,概不做答
 
program datetime;

{$APPTYPE CONSOLE}

uses
SysUtils,
Windows,
Registry,
Messages;

{*********************************************}
{ Set Global Environment Function }
{ Coder : Kingron,2002.8.6 }
{ Bug Report : Kingron@163.net }
{ Test OK For Windows 2000 Advance Server }
{ Parameter: }
{ Name : The environment name }
{ Value: The environment Value }
{ Ex: SetGlobalEnvironment('MyVar','OK') }
{*********************************************}

function SetGlobalEnvironment(const Name, Value: string): boolean;
resourcestring
REG_LOCATION = 'System/CurrentControlSet/Control/Session Manager/Environment';
begin
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
Result := OpenKey(REG_LOCATION, True);
if Result then
begin
WriteString(Name, Value); { Write Registry for Global Environment }
SetEnvironmentVariable(pchar(Name), pchar(Value));
{ Send Message To All Top Window for Refresh }
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, integer(Pchar('Environment')));
end;
finally
Free;
end;
end; { SetGlobalEnvironment }

var
DatetimeStr : string;
TempStr : string;
Flag : TReplaceFlags;
begin
{ TODO -oUser -cConsole Main : Insert code here }
TempStr := DatetimeToStr(now());
Flag := [rfReplaceAll, rfIgnoreCase];
TempStr := StringReplace(TempStr, ' ', '_', Flag);
TempStr := StringReplace(TempStr, ':', '-', Flag);
DatetimeStr := TempStr;
//Writeln(DatetimeStr);
//SetEnvironmentVariable('ora92',PChar(DatetimeStr));
SetGlobalEnvironment('datetime', PChar(DatetimeStr));
writeln(GetEnvironmentVariable('datetime'));
Readln;
end.
 
你的程序确实是对的,不过不能解决我的问题。
我现在就是想要在控制台下运行我的程序,我的程序修改环境变量,这个环境变量马上在
当前的控制台窗口生效。
发送消息的方法不行,或许还有其他方法。
大虾们,再帮我钻钻牛角尖,300分等着你!
 
用命令set datetime='abc'就可以实现,为什么自己写程序里就不能实现呢?
 
to Kingron:
可能是我的问题没说清楚。
斑竹,把我的分给Kingron一百分吧,不过本问题要继续,分值300。
 
跟你说了,每一个程序又一个环境变量块,你在DOS控制台运行你的程序,那么你的程序是作为
一个新的进程打开的,并且会把DOS控制台的环境变量发送给你的程序,根据MS SDK的说明,你可以
设置子进程的环境变量块,但是不能设置父进程的环境变量块,你的要求没有办法做到的!

你可以考虑变换一个角度来解决你的问题,例如利用临时文件之类的。
 
to Kingron,MS SDK文档的哪一部分有上述说明?
 
后退
顶部