如何撒谎关于`process.platform`? [英] How to lie to program about `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屋!