将环境变量值绑定到应用程序

将环境变量值绑定到应用程序

我安装了一个应用程序 (Wolfram Mathematica) 的多个版本。默认情况下,所有版本共享相同的设置目录,这会导致一些冲突和损坏。更改设置目录的唯一方法是MATHEMATICA_USERBASE在启动应用程序之前将环境变量 () 设置为目录。

因此,我正在寻找最简单的方法来告诉 Windows 以不同的环境变量设置启动不同的版本。最简单的方法是什么?

我的尝试

我能想到的最好的办法是创建一个包装器脚本,在启动应用程序之前设置环境变量。这种方法的问题在于,将所有地方重定向到使用此包装器应用程序而不是原始应用程序非常困难。这包括开始菜单条目,也包括所有“打开方式...”上下文菜单条目。因此,我正在寻找一种更有效地将环境变量“绑定”到应用程序的方法,这样就不可能用错误的变量启动应用程序。

答案1

我终于找到了一个似乎只需要付出相当少的努力的解决方案:基本思路是将一个 DLL 注入到目标应用程序中,该 DLL 在启动时设置环境变量。这样可以确保无论应用程序如何启动,都会设置该变量,并且不需要任何包装器应用程序或类似程序。

步骤大致如下:

  1. 创建 DLL:我使用的代码如下(保存为main.cpp

    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <stdlib.h>
    
    BOOL WINAPI DllMain(
        HINSTANCE hinstDLL,  // handle to DLL module
        DWORD fdwReason,     // reason for calling function
        LPVOID lpReserved )  // reserved
    {
        if (fdwReason == DLL_PROCESS_ATTACH)
            putenv("MATHEMATICA_USERBASE=C:\\Users\\lukas\\AppData\\Roaming\\Mathematica_12_0");
    
       return TRUE;
    }
    
    __declspec(dllexport)
    void dummy() {}
    

    主要部分是带有 at 的行,putenv用于设置环境变量,其语法为putenv("VARIABLE=VALUE")。该dummy函数仅在我们可以实际将 DLL 添加到导入表时才需要。接下来使用您最喜欢的编译器编译该文件。我使用了 MSVC,命令如下:

    cl.exe  /Zi /LD /EHsc /nologo /Fe:SetEnviromentVariable.dll main.cpp
    

    如果应用程序是 32 位,请确保 DLL 也是 32 位的;如果应用程序是 64 位,请确保 DLL 也是 64 位的。

  2. 将 DLL 复制到应用程序目录

  3. (可选)备份应用程序可执行文件

  4. 将 DLL 添加到导入表。我使用了CFF 探索者,但还有其他工具。对于 CFF explorer,打开可执行文件,转到“导入添加”,单击“添加”,然后选择复制到可执行文件目录的 DLL。然后,从“导出函数”列表中选择“dummy”函数,按“按名称导入”,然后按“重建导入表”,最后保存文件。

    在此处输入图片描述

相关内容