【问题标题】:C# Set environment variable in operative system windows (out of execution)C#在操作系统窗口中设置环境变量(不执行)
【发布时间】:2015-08-07 11:29:39
【问题描述】:

我需要添加一个 Windows 环境变量,就像 Windows 中现有的一样。我的意思是:

当您在 cmd.exe 中运行以下行时:

echo %appdata% //outputs something like C:/Users/blablabla 
// It's saved in windows by default !

我正在制作一个简单的 Winform 应用程序,它可以使用 C# 轻松创建 windows 环境变量

我试过了:

 System.Environment.SetEnvironmentVariable("test", "testvalue", EnvironmentVariableTarget.Machine);

我试过this,但都没有:

    const int HWND_BROADCAST = 0xffff;
    const uint WM_SETTINGCHANGE = 0x001a;

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool SendNotifyMessage(IntPtr hWnd, uint Msg, 
    UIntPtr wParam, string lParam);

    using (var envKey = Registry.LocalMachine.OpenSubKey(
           @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
           true))
            {
                Contract.Assert(envKey != null, @"registry key is missing!");
                envKey.SetValue("artyom", "TestValue");
                SendNotifyMessage((IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE,
                    (UIntPtr)0, "Environment");
            }
    // it is assumed after this , the list should display this value, but nothing happens ! No exceptions, nothing

然后阅读:

msdn docs - Other link here ...

EnvironmentVariableTarget.Machine 似乎根本没有帮助。

如果此过程成功,我将能够在 cmd.exe 中执行此操作

echo %test% // and outputs "testvalue"

请记住,当用户单击按钮并且我在 WinForms 中工作时,我正在测试所有这些代码 是否可以使用 C# 执行此操作?任何帮助表示赞赏,谢谢

【问题讨论】:

  • 其他选项的代码在哪里,包括广播消息?
  • 更新了@RowlandShaw
  • 您在程序中设置的环境变量在程序执行之前已经启动的命令提示符下是不可见的。所以...关闭命令提示符,运行您的软件,打开它并查看它是否存在。对于“机器”环境变量,请以管理员身份运行您的程序。
  • 非常重要的评论@JeroenLandheer!解决了我的部分问题!

标签: c# .net windows winforms environment


【解决方案1】:

您可以尝试添加对 NotifyUserEnvironmentVariableChanged 的​​调用 - 但我认为我的结果好坏参半。

  [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Auto )]
  static extern bool SendNotifyMessage( IntPtr hWnd, uint Msg,UIntPtr wParam, string lParam );

   public static void NotifyUserEnvironmentVariableChanged()
   {
      const int HWND_BROADCAST = 0xffff;
      const uint WM_SETTINGCHANGE = 0x001a;
      SendNotifyMessage( ( IntPtr )HWND_BROADCAST, WM_SETTINGCHANGE, ( UIntPtr )0, "Environment" );
   }

从这里开始:

http://www.codeguru.com/cpp/w-p/win32/tutorials/article.php/c10849/Setting-a-System-Environment-Variable.htm

通过在此键下创建新值或修改已存在的值来添加变量。要删除变量,您只需删除其注册表值,除非您要删除扩展值的一部分,例如 PATH,在这种情况下,您只需删除您想要的部分。

此时,Windows 不会知道您的更改,除非您注销或重新启动。为了解决这个问题,SetEnv 将向系统中的所有窗口广播 WM_SETTINGCHANGE。这允许其他正在运行的应用程序(例如 Explorer.exe)收到您的更改通知。 如果您从命令提示符运行 SetEnv,这不会更新当前 DOS 窗口的环境变量。这主要是因为一个进程(SetEnv)不能改变它的父进程(命令提示符)的环境。但是,您打开的任何新的 DOS/命令提示符都会显示新的变量/值。

广播此消息会导致大约 2-3 秒的轻微延迟(同时打开的窗口会处理它),因此看起来 SetEnv 可能已挂起。事实并非如此。

我相信我已经注意到延迟以及需要打开新命令提示符的问题。

【讨论】:

  • 先生,我欠你一杯咖啡。非常感谢您的描述和您的时间!
  • 代码对你有用吗?只是您必须打开一个新的命令提示符吗?
  • 我之前尝试过的代码就是我所需要的,但我注意到它一直在工作,直到我读到你的答案并打开一个新的命令提示符:)
猜你喜欢
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-13
  • 2018-12-13
  • 2015-01-14
相关资源
最近更新 更多