问题描述
我试图在我的应用程序中设置一个系统环境变量,但得到一个 SecurityException
.我测试了我在谷歌中找到的所有东西 - 没有成功.这是我的代码(注意,我是我的电脑的管理员并以管理员身份运行 VS2012):
I'm trying to set a system environment variable in my application, but get an SecurityException
. I tested everything I found in google - without success.Here is my code (note, that I'm administrator of my pc and run VS2012 as admin):
尝试 1
new EnvironmentPermission(EnvironmentPermissionAccess.Write, "TEST1").Demand();
Environment.SetEnvironmentVariable("TEST1", "MyTest", EnvironmentVariableTarget.Machine);
尝试 2
new EnvironmentPermission(EnvironmentPermissionAccess.Write, "TEST1").Demand();
using (var envKey = Registry.LocalMachine.OpenSubKey(@"SYSTEMCurrentControlSetControlSession ManagerEnvironment", true))
{
Contract.Assert(envKey != null, @"HKLMSystemCurrentControlSetControlSession ManagerEnvironment is missing!");
envKey.SetValue("TEST1", "TestValue");
}
尝试 3我还尝试让我的应用具有管理员权限.
您还有其他建议吗?
推荐答案
文档告诉你如何做到这一点.
The documentation tells you how to do this.
调用 SetEnvironmentVariable
对系统环境变量没有影响.要以编程方式添加或修改系统环境变量,请将它们添加到 HKEY_LOCAL_MACHINESystemCurrentControlSetControlSession ManagerEnvironment
注册表项,然后使用 广播
设置为字符串 WM_SETTINGCHANGE
消息>lParam"Environment"
.这允许应用程序(例如 shell)获取您的更新.
因此,您需要写入您已经尝试写入的注册表设置.然后广播 WM_SETTINGCHANGE
消息,如上所述.您需要以提升的权限运行才能成功.
So, you need to write to the registry setting that you are already attempting to write to. And then broadcast a WM_SETTINGCHANGE
message as detailed above. You will need to be running with elevated rights in order for this to succeed.
一些示例代码:
using Microsoft.Win32;
using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
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);
static void Main(string[] args)
{
using (var envKey = Registry.LocalMachine.OpenSubKey(
@"SYSTEMCurrentControlSetControlSession ManagerEnvironment",
true))
{
Contract.Assert(envKey != null, @"registry key is missing!");
envKey.SetValue("TEST1", "TestValue");
SendNotifyMessage((IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE,
(UIntPtr)0, "Environment");
}
}
}
}
但是,虽然此代码确实有效,但 .net 框架提供了更简单地执行相同任务的功能.
However, whilst this code does work, the .net framework provides functionality to perform the same task much more simply.
Environment.SetEnvironmentVariable("TEST1", "TestValue",
EnvironmentVariableTarget.Machine);
三个参数 Environment.SetEnvironmentVariable 的 文档
重载说:
The documentation for the three argument Environment.SetEnvironmentVariable
overload says:
如果目标是 EnvironmentVariableTarget.Machine,则环境变量存储在本地计算机注册表的 HKEY_LOCAL_MACHINESYSTEMControlSet001ControlSession ManagerEnvironment 键中.它也被复制到文件资源管理器的所有实例中.然后,从文件资源管理器启动的任何新进程都会继承环境变量.
如果目标是用户或机器,则通过 Windows WM_SETTINGCHANGE 消息通知其他应用程序设置操作.
If target is User or Machine, other applications are notified of the set operation by a Windows WM_SETTINGCHANGE message.
这篇关于如何在 C# 中设置系统环境变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!