如何撒谎关于`process.platform`? [英] How to lie to program about `process.platform`?

查看:117
本文介绍了如何撒谎关于`process.platform`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个CLI运行在Node上,可以通过命令行上的命令执行。在其代码中,如果(process.platform ==='win32'){process.exit(1); } 。现在,我想禁用此检查,并允许Windows用户使用隐藏功能(通常Windows上未安装必需的软件,但是我在其中有特殊的设置)。

There is a CLI that runs on Node and can be executed via command on the command line. In its code, some functionality is deactivated for Windows users by if (process.platform === 'win32') { process.exit(1); }. Now I want to disable this check, and allow Windows users to use the "hidden" functionality (usually the the required software is not installed on Windows, but I have a special setup where it is).

是否存在某种方式,可以说谎此CLI并模拟它正在运行,例如是Linux还是macOS?

Is there some way, to lie to this CLI and simulate that it is running on e.g. Linux or macOS?

我当然可以派生CLI,取消检查并使用自己的版本-但这需要为每个发行版重复此过程。由于其他用户也应该可以使用此功能,因此我必须发布分支的和经过修改的CLI,这可能会使它的用户经常感到困惑(版本号呢?我是否使用相同的命令?)-99.9%的代码将保持不变。

Of course I could fork the CLI, remove the check and work with my own version - but this would require repeating this process for each release. As this functionality should also be available to other users, I would have to publish the forked and modified CLI which could be a frequent source of confusion for its users (What about version numbers? Do I use the same command?) - 99.9% of the code will stay untouched.

我是否可以编写自己的CLI,这样做可以伪造环境,然后执行已安装的原始CLI,然后进行清理?

Could I maybe write my own CLI, that does something to "fake" the environment, then executes the installed, original CLI, and cleans up afterwards?

我创建了一个示例软件包,其工作原理与CLI,但仅执行我要调查的部分:

I created an example package that works identical to the CLI, but only does exactly that part that I am investigating:

  • https://github.com/janpio/nodejs-cli-nowin
  • https://www.npmjs.com/package/nodejs-cli-nowin

通过 npm i -g nodejs-cli-nowin 安装。

推荐答案

基本上,包装程序包应用于提供入口点,而不是原始程序包。在原始程序包运行之前,应使用新值模拟 process.platform

Basically, wrapper package should be used to provide entry point instead of original package. process.platform should be mocked with new value before original package runs.

包装程序包/index.js

Object.defineProperty(process, 'platform', { value: 'linux' });

require('original-package/bin/entry-point.js');

如果原始程序包产生了子进程,这不会影响子进程。

This won't affect child processes if original package spawns them.

这不能保证程序包可以在模拟平台上正常工作,很有可能不会。即使包本身正常工作,这也可能导致依赖 process.platform 的包依赖项中的行为无法预测。

This doesn't guarantee that the package will work as intended with mocked platform, there's a good chance that it won't. Even if the package itself works correctly, this may result in unpredictable behaviour in package dependencies that rely on process.platform.

为了只影响特定模块的 process.platform ,全局 platform 应该用局部变量遮盖。为此,应修改模块包装器函数:

In order to affect process.platform only for specific module, platform global should be shadowed with local variable. To do this, module wrapper function should be modified:

const Module = require('module')

const escapedPatchedModulePath = require.resolve('original-package/module-to-patch.js')
  .replace(/\\/g, '\\\\');

Module.wrapper[0] += `
const isPatchedModule = __filename === "${escapedPatchedModulePath}";
let process = isPatchedModule
  ? Object.create(global.process, { platform: { value: 'linux' } })
  : global.process;
`;

require('original-package/bin/entry-point.js');

这篇关于如何撒谎关于`process.platform`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆