Получить переменные среды, как определено в Windows (не зависит от процесса) - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь создать приложение Java, которое может редактировать переменные среды (если возможно, даже различать системные переменные и пользовательские переменные), в основном делая то же самое, что и редактор переменных среды в Windows 7, просто с более простым в использованииинтерфейс: Windows 7 Environment Variable EditorИ да, я знаю, что есть приложения, которые делают именно это, но я хочу написать это сам (на практике и для удовольствия).

Однако моя проблема в том, что при получении этих переменных он всегда возвращаетпеременные, установленные в данный момент в этом процессе (см. пример).Есть ли способ получить переменные, как они установлены в Windows?Я попытался запустить новый процесс cmd.exe из Java и выполнить SET , но новый процесс наследует переменные.Чтобы сохранить их, я подумал, что буду использовать команду SETX , но я еще не тестировал ее.

Мне нужно только решение для Windows 7, не нужно, чтобы оно работалос любой другой ОС.

Пример:Путь: 'c: \ apps \ oracle \ clients {...} \ Microsoft SQL Server \ 120 \ DTS \ Binn \'Однако в моем Java-приложении это заканчивается на «java \ jdk1.8.0_181 \ jre \ bin».JDK 1.8 не находится в моей глобальной переменной пути, а только для текущего процесса.

1 Ответ

0 голосов
/ 19 декабря 2018

Я использовал реестр Windows, как и предполагал DodgyCodeException.Чтобы получить к нему доступ, я использовал JNA

Sample Code (используя системные переменные, передайте true для параметра user 'для использования пользовательских переменных):

public static final String USER_VAR_PATH = "Environment";
public static final String SYSTEM_VAR_PATH = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";

public static void main(String[] args) {
    //Get all system environment variables
    for(String systemVariableName : getAllEnvironmetVariables(false).keySet()){
        System.out.println(systemVariableName);
    }

    //print system environment variable 'OS'
    System.out.println(getEnvironmetVariable("OS", false));

    //write to the path variable (append a string)
    String addToPath = "";
    setEnvironmetVariable("Path", getEnvironmetVariable("Path", false) + addToPath, false);
}

public static TreeMap<String, Object> getAllEnvironmetVariables(boolean user){
    HKEY root = user ? WinReg.HKEY_CURRENT_USER : WinReg.HKEY_LOCAL_MACHINE;
    String path = user ? USER_VAR_PATH : SYSTEM_VAR_PATH;
    return Advapi32Util.registryGetValues(root, path);
}

public static String getEnvironmetVariable(String key, boolean user){
    HKEY root = user ? WinReg.HKEY_CURRENT_USER : WinReg.HKEY_LOCAL_MACHINE;
    String path = user ? USER_VAR_PATH : SYSTEM_VAR_PATH;
    try{
        return Advapi32Util.registryGetExpandableStringValue(root, path, key);
    }catch(Exception e){
        return Advapi32Util.registryGetStringValue(root, path, key);
    }
}

public static void setEnvironmetVariable(String key, String value, boolean user){
    HKEY root = user ? WinReg.HKEY_CURRENT_USER : WinReg.HKEY_LOCAL_MACHINE;
    String path = user ? USER_VAR_PATH : SYSTEM_VAR_PATH;
    if(value.contains("%")){
        Advapi32Util.registrySetExpandableStringValue(root, path, key, value);
    }else{
        Advapi32Util.registrySetStringValue(root, path, key, value);
    }
}

Существует два типа значений, используемыхпеременные: REG_SZ и REG_EXPAND_SZ.Оба являются строками, но второй указывает, что он содержит другие переменные (например, %SystemRoot%\...)Моя обработка этих двух типов должна работать, но определенно не чистая.Если есть лучший способ, пожалуйста, скажите мне.

РЕДАКТИРОВАТЬ: Вам нужно JNA и JNA Platform , чтобы это работало.Импорт:

import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;
import com.sun.jna.platform.win32.WinReg.HKEY;
...