Empty environment variables passed to vscode are unset

iq0todco  于 5个月前  发布在  Vscode
关注(0)|答案(7)|浏览(57)

这是一个关于#174330的延续,现在已经锁定,不再接受评论。原始报告是由我们的Go扩展用户提交的,他们观察到在使用扩展功能运行/调试测试时,空的环境变量没有被反映出来。这个问题已经在#175682中关闭,修复了术语环境中的环境处理问题。然而,Go扩展功能(运行/调试测试)实际上直接使用扩展主机的process.env。因此,术语环境的修复对原始问题的用户没有帮助。(golang/vscode-go#2745)

我已经在microsoft/vscode-extension-samples@main...hyangah:vscode-extension-samples:main#diff-665767c0f91ad3e1e028cc5dd145783e8ecaef232aefdb222ba9590b6bd52ba1中准备了一个复现示例。

你可以使用提交中的启动配置,或者按照以下步骤操作:

  1. cd getting-started-sample
  2. vsce package
  3. code-insiders --install-extension=getting-started-sample-0.0.1.vsix
  4. EMPTY_VAR="" NONEMPTY_VAR="nonempty" code-insiders
  5. 从命令面板中选择 "Getting Started Sample: Say Hello"。检查控制台日志,使用 "Developer: Toggle Developer Tools"。

code-insiders(版本:1.79.0-insider(通用))给我的是

。你可以看到EMPTY_VAR是未定义的。除了process.env之外,是否有推荐的方式让扩展获取进程环境?节点调试器是否在#174330(评论)中避免了这个问题,因为调试器/被调试者是从终端启动的?

nbnkbykc

nbnkbykc1#

出于好奇,是否有关于何时解决这个问题的估计?我非常希望能够升级到VSCode 1.73.1以上的版本,但在这个问题仍然未解决的情况下无法实现。如果这有帮助的话,我很乐意尝试调查这个问题,看看是否可以修复它。我不太确定process.env在哪里被覆盖了,因为我进行了一些测试,无论是单独的node还是标准的electron,都将EMPTY_VAR=""视为空字符串而不是未定义,所以vscode中的某个地方正在覆盖它。

ca1c2owp

ca1c2owp2#

@fedorareis,目前这个问题已经在待办事项列表中,也就是说它没有任何预计的时间。如果你想尝试解决这个问题,可以从以下位置开始调查:

CLI中的环境代码:
vscode/src/vs/code/node/cli.ts
第182行到第185行
| | constenv: IProcessEnvironment={ |
| | ...process.env, |
| | 'ELECTRON_NO_ATTACH_CONSOLE': '1' |
| | }; |
当我们通过dock启动时,在Linux和macOS上解析"开发环境":
vscode/src/vs/platform/shell/node/shellEnv.ts
第123行
| | returnnewPromise<typeofprocess.env>((resolve,reject)=>{ |
启动扩展主机:
vscode/src/vs/platform/extensions/electron-main/extensionHostStarter.ts
第89行到第98行
| | this._getExtHost(id).start({ |
| | ...opts, |
| | type: 'extensionHost', |
| | entryPoint: 'vs/workbench/api/node/extensionHostProcess', |
| | args: ['--skipWorkspaceStorageLock'], |
| | execArgv: opts.execArgv, |
| | allowLoadingUnsignedLibraries: true, |
| | forceAllocationsToV8Sandbox: true, |
| | correlationId: id |
| | }); |
请注意,更改 process.env 不是公共API,这意味着它可能会出现问题。有一个与通过 EnvironmentVariableCollection 在扩展主机上设置环境相关的问题: #152806

ktecyv1j

ktecyv1j3#

我认为这个bug是在Electron或Chromium中。1.74版本的发布说明中提到,在沙箱化VS Code方面取得了进展,包括引入了一个新的UtilityProcess API来支持这些更改。由于1.73.1是最后一个不存在此bug的版本,我认为它是在这个更改中引入的。

为了确认工具进程分叉是移除环境变量的原因,我们可以在Extension Host生成的地方以及Extension Host本身的入口点记录process.env:

  1. "__A_EMPTY_VAR": """__A_NONEMPTY_VAR": ""添加到Launch VS Code Internal任务的环境变量中:
vscode/.vscode/launch.json
第234行至第237行 [3cd6f48](https://github.com/microsoft/vscode/commit/3cd6f481266dcbd2ca2fcff43b4465d747c78e2f)
|  | "env": { |
|  | "VSCODE_EXTHOST_WILL_SEND_SOCKET": null, |
|  | "VSCODE_SKIP_PRELAUNCH": "1" |
|  | }, |
  1. 在第237行设置一个条件断点,条件为configuration.env,以检查Extension Host生成时的环境中的环境变量:
vscode/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts
第236行至第244行 [3cd6f48](https://github.com/microsoft/vscode/commit/3cd6f481266dcbd2ca2fcff43b4465d747c78e2f)
|  | // Fork utility process |
|  | this.process=utilityProcess.fork(modulePath,args,{ |
|  | serviceName, |
|  | env, |
|  | execArgv, |
|  | allowLoadingUnsignedLibraries, |
|  | forceAllocationsToV8Sandbox, |
|  | stdio |
|  | }asForkOptions&{forceAllocationsToV8Sandbox?: Boolean}); |
  1. bootstrap-fork.js的顶部添加一个console.log(process.env);,以在Extension Host的入口点记录环境变量:
vscode/src/bootstrap-fork.js
第1行至第9行 [3cd6f48](https://github.com/microsoft/vscode/commit/3cd6f481266dcbd2ca2fcff43b4465d747c78e2f)
|  | /*--------------------------------------------------------------------------------------------- *
|  | * Copyright (c) Microsoft Corporation. All rights reserved. *
|  | * Licensed under the MIT License. See License.txt in the project root for license information. *
|  | *---------------------------------------------------------------------------------------------*/ |
|  | |
|  | //@ts-check |
|  | 'use strict'; |
|  | |
|  | constperformance=require('./vs/base/common/performance'); |
  1. 启动VS Code任务。
  2. 在断点处检查env变量。确认__A_EMPTY_VAR__A_NONEMPTY_VAR都存在,且值与我们放入的相同。
  3. 继续。
  4. 切换到调试控制台和“附加到扩展主机”任务。展开已记录的Object并确认__A_EMPTY_VAR已消失,但__A_NONEMPTY_VAR仍然存在。
7kjnsjlb

7kjnsjlb4#

嘿,伙计们,我找到了它,它在Chromium中。
我偶然发现了clue:

// Setting values in EnvironmentMap to an empty-string will make
// sure that they get unset from the environment via AlterEnvironment().

这引导我去了解它的全部:

// Now append all modified and new values.
for (const auto& i : changes) {
  if (!i.second.empty()) {
    result_indices.push_back(value_storage.size());
    value_storage.append(i.first);
    value_storage.push_back('=');
    value_storage.append(i.second);
    value_storage.push_back(0);
  }
}

Chromium的服务API将带有空白值的环境Map条目视为不应在新进程中设置变量。当你继承父环境且不传递任何环境变量时,它不会这样做,因为没有必要修改它已经拥有的环境变量。
如果你用这段代码构建Electron,并在if语句之前的for循环中运行它,你可以确认当它启动实用程序进程时,它不会设置变量:

if (i.first == "EMPTY_VAR") {
  LOG(INFO) << "It's unsetting the empty variable";
}

Dobby找到了这个bug的根本原因。Dobby是免费的。
(这是个谎言。Dobby必须在未来某个时候向Chromium提交一个问题...)

inb24sb2

inb24sb25#

@deepak1556 这可能是因为Chromium/Electron吞噬了空变量?

hkmswyz6

hkmswyz66#

@NoelTautges的发现恰到好处,谢谢!但这不是Chromium的bug,启动API并不打算用于外部用例,它们的行为无法在上游更改。然而,我们可以调整Electron中实用程序进程的行为。

k4aesqcs

k4aesqcs7#

+1,只是为了添加一个额外的数据点,遇到了与vscode-python扩展相同的行为。参见 microsoft/vscode-python#22337

相关问题