Совместное использование переменных среды между языками - PullRequest
0 голосов
/ 31 октября 2019

Я пишу приложение, составленное из нескольких модулей, написанных на разных языках (например, Java, C #, C ++). Я испытываю странное поведение, когда переменные среды, которые я устанавливаю в одном модуле (например, C #), не распространяются на другие модули. Насколько я понимаю, проблема связана с тем, что переменные среды в Windows доступны через структуру _environ в библиотеке времени выполнения, а не через дескриптор процесса, следовательно, библиотеки, использующие разные среды выполнения, имеют разные переменные среды.

В частности, для C # эта проблема возникает, только если я компилирую и запускаю код в Release, тогда как компиляция кода в Debug работает просто отлично.

Приведенный ниже код воспроизводит проблему с двумя очень простыми модулями. написано на C # и C ++. Я скомпилировал код с VS2015 Professional. Код C # был скомпилирован с помощью среды выполнения v4.0 и .NET Framework v4.5.2

C # исполняемый файл

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("cpp_lib.dll", CharSet = CharSet.Unicode)]
        public static extern void print_path();

        static void Main(string[] args)
        {
            var path = Environment.GetEnvironmentVariable("PATH");
            path += ";D:\\Temp";
            Environment.SetEnvironmentVariable("PATH", path);
            // Print the path from C#
            Console.WriteLine("Path from C#: " + Environment.GetEnvironmentVariable("PATH"));
            // Print the path from c++
            print_path();
        }
    }
}

Библиотека C ++

#include <iostream>
#include <Windows.h>

extern "C" {

  __declspec(dllexport) void print_path() {
    std::cout << "PATH seen in C++: " << getenv("PATH") << std::endl;
  }

}

Как уже было сказано, при запускекод в Debug по тому же пути печатается из C # и C ++, но выполнение кода в Release приводит к тому, что в PATH, напечатанном из c ++, отсутствует папка D: \ Temp

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Оказывается, Windows предоставляет больше функций для получения переменных окружения. Из документации "getenv и _putenv используют копию среды, на которую указывает глобальная переменная _environ, для доступа к среде." , тогда как GetEnvironmentVariable "Извлекает содержимое указанной переменной из блока средывызывающий процесс. " Из этих операторов GetEnvironmentVariable выглядит как самая безопасная альтернатива, и замена getenv на GetEnvironmentVariable действительно решит проблему.

Ссылки:

https://social.msdn.microsoft.com/Forums/en-US/c27a6623-6f57-4c7e-be9b-6dd35d362872/sharing-environment-variables-across-languages?forum=windowsgeneraldevelopmentissues

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getenv-wgetenv?view=vs-2019

https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getenvironmentvariable

1 голос
/ 31 октября 2019

Переменные среды пользователя являются отдельными процессами, а изменения не распространяются на другие процессы.

Чтобы изменить системные переменные среды в вашем примере PATH. Вам нужно изменить значение в разделе реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment и затем передать сообщение WM_SETTINGCHANGE. Приложения, желающие увидеть изменения, должны будут обрабатывать трансляцию.

Источник: https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables

...