Вопрос по environment-variables, .net, c# – Как установить системную переменную среды в C #?

6

я пытаюсь установить системную переменную среды в моем приложении, но получитьSecurityException, Я проверил все, что я нашел в Google - без успеха. Вот мой код (обратите внимание, что ям администратора моего ПК и запускаю VS2012 от имени администратора):

Попытка 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(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true))
{

  Contract.Assert(envKey != null, @"HKLM\System\CurrentControlSet\Control\Session Manager\Environment is missing!");
  envKey.SetValue("TEST1", "TestValue");
}

Попытка 3 Также я попытался достать свойприложение с правами администратора.

Есть ли у вас другие предложения?

Вы можете'просто пойти и получить разрешение. Вы должны быть повышены. И это нужно сделать во время запуска процесса. David Heffernan

Ваш Ответ

1   ответ
22

документация говорит вам, как это сделать.

призваниеSetEnvironmentVariable не влияет на системные переменные окружения. Чтобы программно добавить или изменить системные переменные среды, добавьте их вHKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment ключ реестра, затем транслироватьWM_SETTINGCHANGE сообщение сlParam установить на строку"Environment", Это позволяет приложениям, таким как оболочка, забирать ваши обновления.

Итак, вам нужно записать в параметр реестра, в который вы уже пытаетесь записать. А потом транслироватьWM_SETTINGCHANGE сообщение, как описано выше. Вам нужно будет работать с повышенными правами, чтобы это удалось.

Пример кода:

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(
                @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
                true))
            {
                Contract.Assert(envKey != null, @"registry key is missing!");
                envKey.SetValue("TEST1", "TestValue");
                SendNotifyMessage((IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE,
                    (UIntPtr)0, "Environment");
            }
        }
    }
}

Однако, хотя этот код работает, платформа .net предоставляет функциональные возможности для гораздо более простого выполнения той же задачи.

Environment.SetEnvironmentVariable("TEST1", "TestValue", 
    EnvironmentVariableTarget.Machine);

документация за три аргументаEnvironment.SetEnvironmentVariable перегрузка говорит:

Если целью является EnvironmentVariableTarget.Machine, переменная среды сохраняется в HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ Control \ Session Manager \ Ключ среды локального компьютера.реестр. Он также копируется во все экземпляры проводника. Затем переменная среды наследуется любыми новыми процессами, которые запускаются из проводника.

Если целью является Пользователь или Машина, другие приложения уведомляются о заданной операции с помощью сообщения Windows WM_SETTINGCHANGE.

Я не понимаю этот вопрос. David Heffernan
Если бы была такая вещь, это сделало бы UAC бессмысленным.т это. Если вы хотите выполнять задачи администратора, вам нужно стать администратором. Там'от этого не уйти David Heffernan
@ Ученик, которого я не знаюне думаю, чтоправильное различие. Оба приведенных выше примера кода написаны на C #, оба делают одно и то же, оба используют WinAPI для выполнения реальной работы. Я нене думаю, что этоРеально игнорировать существование WinAPI при кодировании такого рода задач в Windows. В конечном итоге любое решение проблемы приводит к записи в этот раздел реестра и отправке широковещательного сообщения. David Heffernan
Как я уже сказал, вам нужно запустить это повышенное. Когда вы это сделаете, вы обнаружите, что это работает. Я тестировал этот код, вы знаете! David Heffernan

Похожие вопросы