如何在NodeJS中正确获取用户的PATH环境变量?

olhwl3o2  于 2023-06-22  发布在  Node.js
关注(0)|答案(1)|浏览(247)

我正在构建一个需要修改用户的PATH变量的应用程序(仅限Windows)。在某些时候,它会将新目录添加到PATH中,而在另一些时候,它会从PATH中删除这些目录。
我使用exec方法(来自child_process)运行setx命令来设置环境变量。所以,这很好。
问题是当我需要检索PATH变量时。我试着运行echo %PATH%来获取当前的%PATH%,然后运行reg query HKCU\Environment /v Path来从注册表中获取当前的PATH。这两个方法返回不同的结果,并且这两个结果都不是预期的结果。
例如,当我运行echo %PATH时,它返回用户的PATH变量,前置当前应用程序的二进制目录(如node_modules.bin)(我认为发生这种行为是因为Node.JS在运行应用程序时前置一些PATH=“blablabla”到命令)。

而且,当我运行reg query HKCU\Environment /v Path时,我相信它会返回“原始”用户的PATH变量,而没有任何第三方软件目录。这与我打开regedit并检查该键的内容,或者打开系统的环境变量接口并检查PATH中的路径时得到的结果有很大的不同(这两种方法都有“C:\local.host\modules\bin”,“C:\local.host\modules\nvm\1.1.11”和“C:\local.host\modules\nodejs”目录,这些目录不在NodeJS提供的结果中)。

当我从命令提示符窗口运行相同的命令时,这可能会更奇怪,它返回正确的用户路径,以及第三方目录。

有什么问题吗我需要检索用户的PATH变量(如在系统工具中看到的- regedit,命令提示符和env。变量编辑器),但回显%PATH%或从Node的注册表查询不会返回预期的结果。
如何正确获取用户的PATH?

dy1byipe

dy1byipe1#

我找到解决办法了也许不是完美的,但正如预期的那样工作。
其概念是从普通CMD获取%PATH% envvar(使用exec并运行echo %PATH%),然后删除所有包含“node_modules”的路径。另外,我已经检查了NodeJS将真实的的%PATH%“转储”到应用程序中,在那里它追加了node_modules目录,因此我需要保持process.env.PATH变量随我的修改而更新,但包括node_modules的修改
最终的解决方案看起来是这样的:

const appPath = process.env.PATH.split(";").filter((segment) => segment.trim().length > 0).filter((segment) => segment.indexOf("node_modules") > -1);

export function getPath(callback){
    exec(`echo %PATH%`, (err, stdOut, stdErr) => {
        let data = stdOut.trim();
        let pathArray = data.split(";").filter((segment) => segment.trim().length > 0);
        let uniquePathArray = [];

        pathArray.forEach((path) => {
            if(uniquePathArray.indexOf(path) == -1 && appPath.indexOf(path) == -1){
                uniquePathArray.push(path);
            }
        });

        if(callback){
            callback(uniquePathArray);
        }
    });
}

export function setPath(pathArray, callback){
    let systemPath = pathArray.join(";");
    let envPath = [...appPath, ...pathArray].join(";");

    process.env.PATH = envPath;

    exec(`setx PATH "${systemPath}"`, (err, stdOut, stdErr) => {
        if(err == null){
            if(callback){
                callback(stdOut);
            }
        }
    });
}

首先,我将包含“node_modules”的目录存储到一个appPath数组中,在获取%PATH%变量时将其“减去”。另外,在设置%PATH%时,我将appPath前置到%PATH%变量中,仅适用于process.env.PATH,而系统的%PATH%不需要这些路径。
我做了一个帮助器来管理系统的envars(仅限Windows),你可以在这个链接上找到:https://gist.github.com/RBFraphael/dcd3385c8e18a885345d364cff0f3e2f
谢谢!

相关问题