Приложение C # / .NET не распознает изменение среды (PATH) - PullRequest
5 голосов
/ 17 ноября 2009

В моем приложении на C # я программно устанавливаю клиент Oracle, если он отсутствует, что требует добавления dir в системную переменную среды PATH. Это все работает нормально, но не вступает в силу, пока пользователь не выйдет из системы / не войдет в Windows или не перезагрузится. Как я могу заставить мое приложение распознавать и использовать новую переменную PATH без этого шага? Даже перезапуск моего приложения был бы лучше, чем требование пользователя выйти / войти.

Предположительно, передача этого изменения другим процессам должна работать. Вот что я попробовал, но безуспешно:

    using System.Runtime.InteropServices;

    private const int HWND_BROADCAST = 0xffff;
    private const int WM_WININICHANGE = 0x001a, WM_SETTINGCHANGE = WM_WININICHANGE, INI_INTL = 1;
    [DllImport("user32.dll")]
    private static extern int SendMessageTimeoutA(int hWnd, uint wMsg, uint wParam, string lParam, int fuFlags, int uTimeout, int lpdwResult);

    int rtnVal = 0;
    SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Environment", 2, 5000, rtnVal);

Мне сказали, что если вы остановите и перезапустите рассматриваемый процесс, он должен получить такие изменения, но перезапуск моего приложения этого не делает. Я предполагаю, что это может быть проблема Oracle, что что-то в Oracle требует логина, чтобы распознать изменения, я не уверен. Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 17 ноября 2009

Ваша проблема в том, что только некоторые приложения прослушивают это сообщение (например, проводник), поэтому оно вообще не будет использоваться вашим приложением. Поскольку среда обычно наследуется, перезапуск приложения изнутри сам по себе не поможет, так как он получит ваш текущий блок Environment. Если пользователь перезапустится из меню «Пуск», оно будет работать (при условии, что WM_SETTINGCHANGE была передана).

Лучше всего использовать Environment.GetEnvironmentVariable, чтобы считать текущее значение из реестра и объединить его с текущей средой. В основном делают

Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine) + ";" + (Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User)));
1 голос
/ 17 ноября 2009

Работает ли Environment.GetEnvironmentVariable ("MYVAR", EnvironmentVariableTarget.Machine) не работает?

Если мое приложение работает с повышенными правами, тогда я могу

 Environment.SetEnvironmentVariable("MYVAR", "cool", EnvironmentVariableTarget.Machine);

//do some other stuff...

Console.WriteLine(Environment.GetEnvironmentVariable("MYVAR", EnvironmentVariableTarget.Machine));

C:\TestApp>>TestApp.exe
cool

Я не знаю, будет ли это работать для других запущенных процессов, но это должно для вашего приложения делать / устанавливать

0 голосов
/ 22 ноября 2009

В нашем проекте мы настраиваем Oracle Instant Client с использованием «install.bat» из архива Instant Client. Например:

install.bat odp.net1x% 1 имя

...