GetEnvironmentVariable () и SetEnvironmentVariable () для переменной PATH - PullRequest
13 голосов
/ 19 августа 2011

Я хочу расширить текущую переменную PATH с помощью программы на C #. Здесь у меня есть несколько проблем:

  1. Использование GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine) заменяет заполнители (то есть '%SystemRoot%\system32' заменяется текущим путем 'C:\Windows\system32'). Обновляя переменную PATH, я не хочу заменять местозаполнитель путем.

  2. После SetEnvironmentVariable больше не открывается программа из окна команд (т.е. calc.exe в окне команд не работает). Я использую следующий код:

String oldPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("PATH", oldPath + ";%MYDIR%", EnvironmentVariableTarget.Machine);

После редактирования и изменения переменной PATH в Windows все снова работает. (Мне нужно, чтобы изменения были внесены, в противном случае оно не перезаписывается)

Ответы [ 6 ]

5 голосов
/ 12 октября 2011

Вы можете использовать реестр для чтения и обновления:

string keyName = @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
//get non-expanded PATH environment variable            
string oldPath = (string)Registry.LocalMachine.CreateSubKey(keyName).GetValue("Path", "", RegistryValueOptions.DoNotExpandEnvironmentNames);

//set the path as an an expandable string
Registry.LocalMachine.CreateSubKey(keyName).SetValue("Path", oldPath + ";%MYDIR%",    RegistryValueKind.ExpandString);
1 голос
/ 06 ноября 2011

Вы можете попробовать этот микс. Он получает переменные Path из реестра и добавляет «NewPathEntry» в Path, если его там еще нет.

static void Main(string[] args)
    {
        string NewPathEntry = @"%temp%\data";
        string NewPath = "";
        bool MustUpdate = true;
        string RegKeyName = @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
        string path = (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey(RegKeyName).GetValue
            ("Path", "", Microsoft.Win32.RegistryValueOptions.DoNotExpandEnvironmentNames);
        string[] paths = path.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string subPath in paths)
        {
            NewPath += subPath + ";";
            if (subPath.ToLower() == NewPathEntry.ToLower())
            {
                MustUpdate = false;
            }
        }
        if (MustUpdate == true)
        {
            Environment.SetEnvironmentVariable("Path", NewPath + NewPathEntry, EnvironmentVariableTarget.Machine);
        }
    }
1 голос
/ 19 августа 2011

Вы можете использовать WMI для извлечения необработанных значений (хотя не уверены в их обновлении):

ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_Environment WHERE Name = 'PATH'");
foreach (ManagementBaseObject managementBaseObject in searcher.Get())
     Console.WriteLine(managementBaseObject["VariableValue"]);

Проверка Ссылка WMI в MSDN

0 голосов
/ 17 апреля 2012

Использование Registry.GetValue расширит заполнители, поэтому я рекомендую использовать Registry.LocalMachine.OpenSubKey, а затем получить значение из вложенного ключа с параметрами, установленными, чтобы не расширять переменные среды. После того, как вы изменили путь по своему вкусу, используйте реестр, чтобы снова установить значение. Это не позволит Windows «забыть» ваш путь, как вы упомянули во второй части вашего вопроса.

const string pathKeyName = @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
var pathKey = Registry.LocalMachine.OpenSubKey(pathKeyName);
var path = (string)pathKey.GetValue("PATH", "", RegistryValueOptions.DoNotExpandEnvironmentNames);
// Manipulate path here, storing in path
Registry.SetValue(String.Concat(@"HKEY_LOCAL_MACHINE\", pathKeyName), "PATH", path);
0 голосов
/ 31 октября 2011

Во время работы над приложением у нас была возможность использовать Oracle InstantClient из пользовательской папки. Чтобы использовать InstantClient, нам пришлось изменить переменную пути среды и добавить эту папку до , вызывая любые связанные с Oracle функциональные возможности. Вот метод, который мы используем для этого:

    /// <summary>
    /// Adds an environment path segments (the PATH varialbe).
    /// </summary>
    /// <param name="pathSegment">The path segment.</param>
    public static void AddPathSegments(string pathSegment)
    {
        LogHelper.Log(LogType.Dbg, "EnvironmentHelper.AddPathSegments", "Adding path segment: {0}", pathSegment);
        string allPaths = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
        if (allPaths != null)
            allPaths = pathSegment + "; " + allPaths;
        else
            allPaths = pathSegment;
        Environment.SetEnvironmentVariable("PATH", allPaths, EnvironmentVariableTarget.Process);
    }

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

0 голосов
/ 10 октября 2011

Вы можете пройти через реестр ...

string keyName = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
//get raw PATH environment variable
string path = (string)Registry.GetValue(keyName, "Path", "");

//... Make some changes

//update raw PATH environment variable
Registry.SetValue(keyName, "Path", path);
...