简体   繁体   English

C#Reload Systems环境变量

[英]C# Reload Systems environment variables

When i'm starting a C# Process, the system environment variables are changed by some other processes. 当我启动C#进程时,系统环境变量会被其他一些进程更改。 So i want to reload the environment into my process, because this application starts also child processes which need to have the udated environment. 所以我想将环境重新加载到我的进程中,因为这个应用程序也启动了需要拥有过时环境的子进程。 This is the way I'm trying to get and set the environment variables: 这是我试图获取和设置环境变量的方式:

Dictionary<String,String> uservars= new Dictionary<String,String>();
  Dictionary<String, String> sysvars = new Dictionary<String, String>();
  foreach (System.Collections.DictionaryEntry de in System.Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine))
    sysvars.Add(de.Key.ToString().ToUpper(),de.Value.ToString());

  foreach (System.Collections.DictionaryEntry de in System.Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User))
  {
    uservars.Add(de.Key.ToString().ToUpper(), de.Value.ToString());
  }
  Dictionary<string, string> newdict = new Dictionary<string, string>();
  foreach (KeyValuePair<String, String> kvp in uservars)
  {
    if (sysvars.ContainsKey(kvp.Key))
    {
      newdict.Add(kvp.Key, kvp.Value + ";" + sysvars[kvp.Key]);
      sysvars.Remove(kvp.Key);
    }
    else
      newdict.Add(kvp.Key, kvp.Value);
  }
  foreach (KeyValuePair<string, string> kvp in sysvars)
    newdict.Add(kvp.Key, kvp.Value);

  foreach (KeyValuePair<string, string> kvp in newdict)
  {
    System.Environment.SetEnvironmentVariable(kvp.Key, kvp.Value);
  }

The problem is, that the environment variables I get with System.Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User) are the same like the Variables when my application has started. 问题是,我在System.Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User)中获得的环境变量与我的应用程序启动时的变量相同。 But that are not the update variables. 但那不是更新变量。

Is there any way to get these variables directly from the system. 有没有办法直接从系统中获取这些变量。

There are 3 sets of environment variables - the global variables from the machine, the user's saved variables and the variables of the current process 有3组环境变量 - 来自机器的全局变量,用户保存的变量和当前过程的变量

Environment.SetEnvironmentVariable(key, value) Sets the variables of the current process, it does not change the global or user's variables, to read the current process variables you need to use Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process) Environment.SetEnvironmentVariable(key, value)设置当前进程的变量,它不会更改全局或用户的变量,以读取您需要使用的当前进程变量Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process)

When you run a child process your process environment variables are copied into the child process environment variable. 运行子进程时,您的进程环境变量将复制到子进程环境变量中。

Update (and answer to the comment): 更新(并回答评论):

I think you misunderstand how environment variables work, they can only be used to pass data from a parent process to a child process during the process creation, they can not be used to pass data between processes. 我认为您误解了环境变量的工作原理,它们只能用于在创建流程期间将数据从父流程传递到子流程,它们不能用于在流程之间传递数据。

This is how environment variables work: 这是环境变量的工作方式:

Each process has it's own private copy of the environment variables, each process can change that private copy whenever it wants, it's a private copy that has no effect what so ever on the rest of the system. 每个进程都有自己的环境变量私有副本,每个进程可以随时更改该私有副本,它是一个私有副本,对系统的其余部分没有任何影响。

When one process starts another process the parent's private environment variables are copies to the new child process, after that operation the new child process has a private copy of the environment variable that is no longer connected to the parent process. 当一个进程启动另一个进程时,父进程的私有环境变量是新子进程的副本,在该操作之后,新的子进程具有不再连接到父进程的环境变量的私有副本。

There are machine and user environment variables stored in the registry, those are values that are passed the the first process on boot (and, to save reboots, if you send the right notifications windows explorer will load them when starting a new process) changing a process's environment variables does not change the user/machine settings, changing the user/machine setting does not effect any running process. 存储在注册表中的机器和用户环境变量,这些是在引导时传递给第一个进程的值(并且,为了保存重新启动,如果发送正确的通知,Windows资源管理器将在启动新进程时加载它们)更改进程的环境变量不会更改用户/计算机设置,更改用户/计算机设置不会影响任何正在运行的进程。

For example, run two command (cmd.exe) windows, change the environment in one using the SET command, then run the SET command in the other window and see that nothing has changed. 例如,运行两个命令(cmd.exe)窗口,使用SET命令将环境更改为一个,然后在另一个窗口中运行SET命令,看看没有任何更改。

So, there is no such thing as the "system's current environment", if one process changes its environment there is no way for another process to discover and read this change (except to use APIs that let debuggers read other process memory, but you really don't want to go there). 所以,没有“系统的当前环境”这样的东西,如果一个进程改变了它的环境,那么另一个进程就无法发现和读取这个改变(除了使用允许调试器读取其他进程内存的API,但你真的不想去那里)。

I believe if you broadcast the WM_SETTINGCHANGED message prior to creating the new process, it will inherit the new environment settings. 我相信如果您在创建新进程之前广播WM_SETTINGCHANGED消息,它将继承新的环境设置。 So you'll need to pInvoke the Windows SDK PostMessage() or SendMessage() function. 因此,您需要pInvoke Windows SDK PostMessage()或SendMessage()函数。 Simply pass 0 for the LPARAM and WPARAM parameters. 只需为LPARAM和WPARAM参数传递0即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM