From 622d67b8836d97262233a1af35745c04fa4d8b18 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Sat, 26 Apr 2025 15:27:49 -0700 Subject: [PATCH 01/25] WIP - migrate devcmd to cpptools --- Extension/package.json | 20 +++ Extension/package.nls.json | 2 + Extension/src/LanguageServer/devcmd.ts | 176 ++++++++++++++++++++++ Extension/src/LanguageServer/extension.ts | 16 ++ Extension/yarn.lock | 15 +- 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 Extension/src/LanguageServer/devcmd.ts diff --git a/Extension/package.json b/Extension/package.json index 147cd685c3..3a3a2349fc 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -3541,6 +3541,16 @@ "category": "C/C++", "icon": "$(run)" }, + { + "command": "C_Cpp.SetDevEnvironment", + "title": "%c_cpp.command.SetDevEnvironment.title%", + "category": "C/C++" + }, + { + "command": "C_Cpp.ClearDevEnvironment", + "title": "%c_cpp.command.ClearDevEnvironment.title%", + "category": "C/C++" + }, { "command": "C_Cpp.AddDebugConfiguration", "title": "%c_cpp.command.AddDebugConfiguration.title%", @@ -6012,6 +6022,14 @@ "command": "C_Cpp.BuildAndRunFile", "when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && config.C_Cpp.debugShortcut && cpptools.buildAndDebug.isSourceFile" }, + { + "command": "C_Cpp.SetDevEnvironment", + "when": "workspacePlatform == windows" + }, + { + "command": "C_Cpp.ClearDevEnvironment", + "when": "workspacePlatform == windows" + }, { "command": "C_Cpp.AddDebugConfiguration", "when": "config.C_Cpp.debugShortcut && cpptools.buildAndDebug.isFolderOpen" @@ -6636,6 +6654,8 @@ "node-fetch": "^2.7.0", "node-loader": "^2.0.0", "node-stream-zip": "^1.15.0", + "node-vcvarsall": "^1.0.1", + "node-vswhere": "^1.0.2", "plist": "^3.1.0", "posix-getopt": "^1.2.1", "shell-quote": "^1.8.1", diff --git a/Extension/package.nls.json b/Extension/package.nls.json index 262dd3f26b..3d4933f064 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -37,6 +37,8 @@ "c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Clear All Code Analysis Problems", "c_cpp.command.BuildAndDebugFile.title": "Debug C/C++ File", "c_cpp.command.BuildAndRunFile.title": "Run C/C++ File", + "c_cpp.command.SetDevEnvironment.title": "Set Developer Environment", + "c_cpp.command.ClearDevEnvironment.title": "Clear Developer Environment", "c_cpp.command.AddDebugConfiguration.title": "Add Debug Configuration", "c_cpp.command.GenerateDoxygenComment.title": "Generate Doxygen Comment", "c_cpp.command.addSshTarget.title": "Add SSH target", diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts new file mode 100644 index 0000000000..b7737e877c --- /dev/null +++ b/Extension/src/LanguageServer/devcmd.ts @@ -0,0 +1,176 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. + * See 'LICENSE' in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +import { promises as fs } from 'fs'; +import { vcvars } from 'node-vcvarsall'; +import { vswhere } from 'node-vswhere'; +import * as path from 'path'; +import * as vscode from 'vscode'; + +export async function setEnvironment(context?: vscode.ExtensionContext) { + if (!context) { + throw new Error('No context provided'); + } + + const vses = await getVSInstallations(); + if (!vses) { + throw new Error('A Visual Studio installation with the C++ compiler was not found'); + } + + let vs = await chooseVSInstallation(vses); + let options: vcvars.Options | undefined; + if (!vs) { + const compiler = await getAdvancedConfiguration(vses); + vs = compiler.vs; + options = compiler.options; + } + const vars = await vscode.window.withProgress({ + cancellable: false, + location: vscode.ProgressLocation.Notification, + title: 'Configuring Developer Environment...' + }, () => vcvars.getVCVars(vs, options)); + + if (!vars || !vars['INCLUDE']) { + throw new Error(`Something went wrong: ${JSON.stringify(vars)}`); + } + + const host = vars['VSCMD_ARG_HOST_ARCH']; + const target = vars['VSCMD_ARG_TGT_ARCH']; + const arch = vcvars.getArchitecture({ + host: match(host, { 'x86': 'x86', 'x64': 'x64' }) ?? 'x64', + target: match(target, { 'x86': 'x86', 'x64': 'x64', 'arm64': 'ARM64', 'arm': 'ARM' }) ?? 'x64' + }); + const persist = vscode.workspace.getConfiguration('devcmd').get('persistEnvironment') === true; + + context.environmentVariableCollection.clear(); + for (const key of Object.keys(vars)) { + context.environmentVariableCollection.replace(key, vars[key].replace(`%${key}%`, '${env:' + key + '}')); + } + context.environmentVariableCollection.description = (arch ? `${arch} ` : '') + 'Developer Command Prompt for ' + vs.displayName; + context.environmentVariableCollection.persistent = persist; + return true; +} + +async function getVSInstallations() { + const installations = await vswhere.getVSInstallations({ + all: true, + prerelease: true, + sort: true, + requires: ['Microsoft.VisualStudio.Component.VC.Tools.x86.x64'] + }); + + if (installations.length === 0) { + throw new Error('A Visual Studio installation with the C++ compiler was not found'); + } + return installations; +} + +async function chooseVSInstallation(installations: vswhere.Installation[]): Promise { + const items: vscode.QuickPickItem[] = installations.map(installation => { + label: installation.displayName, + description: `Default settings for ${installation.displayName}` + }); + items.push({ + label: 'Advanced options...', + description: 'Select a specific host/target architecture, toolset version, etc.' + }); + const selection = await vscode.window.showQuickPick(items, { + placeHolder: 'Select a Visual Studio installation' + }); + if (!selection) { + throw new Error('The operation was cancelled'); + } + + return installations.find(installation => installation.displayName === selection.label); +} + +async function getAdvancedConfiguration(vses: vswhere.Installation[]): Promise { + const compiler = await chooseCompiler(vses); + if (!compiler) { + throw new Error('The operation was cancelled'); + } + await setOptions(compiler); + return compiler; +} + +interface Compiler { + version: string; + vs: vswhere.Installation; + options: vcvars.Options; +} + +async function chooseCompiler(vses: vswhere.Installation[]): Promise { + const compilers: Compiler[] = []; + for (const vs of vses) { + const vcPath = path.join(vs.installationPath, 'VC', 'Tools', 'MSVC'); + const folders = await fs.readdir(vcPath); + for (const version of folders) { + const options: vcvars.Options = { + // Don't set the version in the options if there is only one + vcVersion: folders.length > 1 ? version : undefined + }; + compilers.push({ version, vs, options }); + } + } + const items = compilers.map(compiler => { + label: compiler.version, + description: compiler.vs.displayName + }); + const selection = await vscode.window.showQuickPick(items, { + placeHolder: 'Select a toolset version' + }); + if (!selection) { + throw new Error('The operation was cancelled'); + } + return compilers.find(compiler => compiler.version === selection.label && compiler.vs.displayName === selection.description); +} + +async function setOptions(compiler: Compiler): Promise { + const vcPath = path.join(compiler.vs.installationPath, 'VC', 'Tools', 'MSVC', compiler.version, 'bin'); + const hostTargets = await getHostsAndTargets(vcPath); + if (hostTargets.length > 1) { + const items = hostTargets.map(ht => { + label: vcvars.getArchitecture(ht), + description: `host = ${ht.host}, target = ${ht.target}` + }); + const selection = await vscode.window.showQuickPick(items, { + placeHolder: 'Select a host and target architecture' + }); + if (!selection) { + throw new Error('The operation was cancelled'); + } + compiler.options.arch = selection.label; + } +} + +async function getHostsAndTargets(vcPath: string): Promise { + const hosts = await fs.readdir(vcPath); + if (hosts.length === 0) { + throw new Error('No hosts found'); + } + const hostTargets: vcvars.HostTarget[] = []; + for (const host of hosts) { + const h = match<'x86' | 'x64' | undefined>(host.toLowerCase(), { 'hostx86': 'x86', 'hostx64': 'x64' }); + if (!h) { + // skip any arm/arm64 folders because there is no arm compiler + continue; + } + const targets = await fs.readdir(path.join(vcPath, host)); + for (const target of targets) { + hostTargets.push({ + host: h, + target: match(target, { 'x86': 'x86', 'x64': 'x64', 'arm64': 'ARM64', 'arm': 'ARM' }) ?? 'x64' + }); + } + } + return hostTargets; +} + +export function deactivate() { +} + +function match(item: string, cases: { [key: string]: T }): T | undefined { + return cases[item]; +} diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 826c188146..f21111f035 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -29,6 +29,7 @@ import { CodeActionDiagnosticInfo, CodeAnalysisDiagnosticIdentifiersAndUri, code import { registerRelatedFilesProvider } from './copilotProviders'; import { CppBuildTaskProvider } from './cppBuildTaskProvider'; import { getCustomConfigProviders } from './customProviders'; +import { setEnvironment } from './devcmd'; import { getLanguageConfig } from './languageConfig'; import { CppConfigurationLanguageModelTool } from './lmTool'; import { getLocaleId } from './localization'; @@ -430,6 +431,8 @@ export async function registerCommands(enabled: boolean): Promise { commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExtractToMemberFunction', enabled ? () => onExtractToFunction(false, true) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExpandSelection', enabled ? (r: Range) => onExpandSelection(r) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ShowCopilotHover', enabled ? () => onCopilotHover() : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SetDevEnvironment', enabled ? () => onSetDevEnvironment() : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearDevEnvironment', enabled ? () => onClearDevEnvironment() : onDisabledCommand)); } function onDisabledCommand() { @@ -1558,3 +1561,16 @@ async function showCopilotContent(copilotHoverProvider: CopilotHoverProvider, ho return true; } + +async function onSetDevEnvironment(): Promise { + try { + await setEnvironment(util.extensionContext); + void vscode.window.showInformationMessage(`${util.extensionContext?.environmentVariableCollection.description} successfully set.`); + } catch (error: any) { + void vscode.window.showErrorMessage(`Developer environment not set: ${error.message}`); + } +} + +async function onClearDevEnvironment(): Promise { + util.extensionContext?.environmentVariableCollection.clear(); +} diff --git a/Extension/yarn.lock b/Extension/yarn.lock index c35c500270..64225e2947 100644 --- a/Extension/yarn.lock +++ b/Extension/yarn.lock @@ -3558,6 +3558,19 @@ node-stream-zip@^1.15.0: resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" integrity sha1-FYrbiO2ABMbEmjlrUKal3jvKM+o= +node-vcvarsall@^1.0.1: + version "1.0.1" + resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/node-vcvarsall/-/node-vcvarsall-1.0.1.tgz#d7ee885e4ca41f0f0d814e3a277995cc95ff20b0" + integrity sha1-1+6IXkykHw8NgU46J3mVzJX/ILA= + dependencies: + node-vswhere "^1.0.2" + tmp "^0.2.1" + +node-vswhere@^1.0.2: + version "1.0.2" + resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/node-vswhere/-/node-vswhere-1.0.2.tgz#f6cac2bd288042f0ab4ee7904e534e04d2f55d2c" + integrity sha1-9srCvSiAQvCrTueQTlNOBNL1XSw= + normalize-path@3.0.0, normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -4711,7 +4724,7 @@ timers-ext@^0.1.7: es5-ext "^0.10.64" next-tick "^1.1.0" -tmp@^0.2.3: +tmp@^0.2.1, tmp@^0.2.3: version "0.2.3" resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" integrity sha1-63g8wivB6L69BnFHbUbqTrMqea4= From 12f31c1c61d4add7032e62092fbac0d637b75f2d Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Tue, 29 Apr 2025 20:20:55 -0700 Subject: [PATCH 02/25] Update walkthrough and make runAndDebug work --- Extension/package.json | 6 ++++ Extension/package.nls.json | 9 ++--- .../src/Debugger/configurationProvider.ts | 36 ++++++++++++++----- .../LanguageServer/cppBuildTaskProvider.ts | 19 +++++++++- Extension/src/LanguageServer/devcmd.ts | 10 ++++-- Extension/src/LanguageServer/extension.ts | 2 ++ Extension/src/LanguageServer/settings.ts | 1 + Extension/src/common.ts | 5 ++- .../open-developer-command-prompt.md | 12 +++++-- .../install-compiler-windows.md | 5 +-- .../install-compiler-windows10.md | 5 +-- .../install-compiler-windows11.md | 5 +-- 12 files changed, 84 insertions(+), 31 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index 3a3a2349fc..1adeb99d67 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -3376,6 +3376,12 @@ "default": "default", "markdownDescription": "%c_cpp.configuration.copilotHover.markdownDescription%", "scope": "window" + }, + "C_Cpp.persistDevEnvironment": { + "type": "boolean", + "default": true, + "markdownDescription": "%c_cpp.configuration.persistDevEnvironment.markdownDescription%", + "scope": "resource" } } } diff --git a/Extension/package.nls.json b/Extension/package.nls.json index 3d4933f064..df23e4cf7e 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -845,6 +845,7 @@ ] }, "c_cpp.configuration.debugShortcut.description": "Show the \"Run and Debug\" play button and \"Add Debug Configuration\" gear in the editor title bar for C++ files.", + "c_cpp.configuration.persistDevEnvironment.markdownDescription": "Remember the last used Visual Studio developer environment for the current workspace. This setting is only applicable for Windows.", "c_cpp.debuggers.pipeTransport.description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).", "c_cpp.debuggers.pipeTransport.default.pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'.", "c_cpp.debuggers.pipeTransport.default.debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb.", @@ -1027,15 +1028,15 @@ }, "c_cpp.walkthrough.create.cpp.file.altText": "Open a C++ file or a folder with a C++ project.", "c_cpp.walkthrough.command.prompt.title": { - "message": "Launch from the Developer Command Prompt for VS", + "message": "Apply the Visual Studio Developer Environment", "comment": [ - "{Locked=\"Developer Command Prompt for VS\"}" + "{Locked=\"Visual Studio\"}" ] }, "c_cpp.walkthrough.command.prompt.description": { - "message": "When using the Microsoft Visual Studio C++ compiler, the C++ extension requires you to launch VS Code from the Developer Command Prompt for VS. Follow the instructions on the right to relaunch.\n[Reload Window](command:workbench.action.reloadWindow)", + "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio Developer Environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetDevEnvironment?%22walkthrough%22)", "comment": [ - "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"VS Code\"} {Locked=\"Developer Command Prompt for VS\"} {Locked=\"\\\n[\"} {Locked=\"](command:workbench.action.reloadWindow)\"}" + "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](C_Cpp.SetDevEnvironment?%22walkthrough%22)\"}" ] }, "c_cpp.walkthrough.run.debug.title": "Run and debug your C++ file", diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index f4f8745016..c90c2916f7 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -121,7 +121,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv } if (this.isClConfiguration(selection.label)) { - this.showErrorIfClNotAvailable(selection.label); + await this.showErrorIfClNotAvailable(selection.label); } return [selection.configuration]; @@ -582,12 +582,32 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv return configurationLabel.startsWith("C/C++: cl.exe"); } - private showErrorIfClNotAvailable(_configurationLabel: string): boolean { - if (!process.env.DevEnvDir || process.env.DevEnvDir.length === 0) { - void vscode.window.showErrorMessage(localize({ - key: "cl.exe.not.available", - comment: ["{0} is a command option in a menu. {1} is the product name \"Developer Command Prompt for VS\"."] - }, "{0} is only usable when VS Code is run from the {1}.", `cl.exe ${this.buildAndDebugActiveFileStr()}`, "Developer Command Prompt for VS")); + /** + * @returns `true` if the Developer Environment is not available and an error was shown to the user, `false` if the Developer Environment is available or the user chose to apply it. + */ + private async showErrorIfClNotAvailable(_configurationLabel: string): Promise { + if (!util.hasMsvcEnvironment()) { + const applyDevEnv = localize("apply.dev.env", "Apply Developer Environment"); + const cancel = localize("cancel", "Cancel"); + const response = await vscode.window.showErrorMessage( + localize({ + key: "cl.exe.not.available", + comment: ["{0} is a command option in a menu."] + }, "{0} requires the Visual Studio Developer Environment.", `cl.exe ${this.buildAndDebugActiveFileStr()}`), + applyDevEnv, + cancel); + if (response === applyDevEnv) { + try { + await vscode.commands.executeCommand('C_Cpp.SetDevEnvironment'); + } catch { + // Ignore the error, the user will be prompted to apply the environment manually. + } + } + if (util.hasMsvcEnvironment()) { + return false; + } + void vscode.window.showErrorMessage( + localize('dev.env.not.applied', 'The Visual Studio Developer Environment was not applied. Please try again or run VS Code from the Developer Command Prompt for VS.')); return true; } return false; @@ -967,7 +987,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv placeHolder: items.length === 0 ? localize("no.compiler.found", "No compiler found") : localize("select.debug.configuration", "Select a debug configuration") }); } - if (selection && this.isClConfiguration(selection.configuration.name) && this.showErrorIfClNotAvailable(selection.configuration.name)) { + if (selection && this.isClConfiguration(selection.configuration.name) && await this.showErrorIfClNotAvailable(selection.configuration.name)) { return; } return selection?.configuration; diff --git a/Extension/src/LanguageServer/cppBuildTaskProvider.ts b/Extension/src/LanguageServer/cppBuildTaskProvider.ts index 014d2316cc..758b9167a4 100644 --- a/Extension/src/LanguageServer/cppBuildTaskProvider.ts +++ b/Extension/src/LanguageServer/cppBuildTaskProvider.ts @@ -6,12 +6,13 @@ import * as cp from "child_process"; import * as os from 'os'; import * as path from 'path'; -import { CustomExecution, Disposable, Event, EventEmitter, ProcessExecution, Pseudoterminal, ShellExecution, Task, TaskDefinition, TaskEndEvent, TaskExecution, TaskGroup, TaskProvider, tasks, TaskScope, TerminalDimensions, TextEditor, window, workspace, WorkspaceFolder } from 'vscode'; +import { CustomExecution, Disposable, EnvironmentVariableMutator, Event, EventEmitter, ProcessExecution, Pseudoterminal, ShellExecution, Task, TaskDefinition, TaskEndEvent, TaskExecution, TaskGroup, TaskProvider, tasks, TaskScope, TerminalDimensions, TextEditor, window, workspace, WorkspaceFolder } from 'vscode'; import * as nls from 'vscode-nls'; import * as util from '../common'; import * as telemetry from '../telemetry'; import { Client } from './client'; import * as configs from './configurations'; +import { isEnvironmentOverrideApplied } from "./devcmd"; import * as ext from './extension'; import { OtherSettings } from './settings'; @@ -430,6 +431,22 @@ class CustomBuildTaskTerminal implements Pseudoterminal { } } + if (isEnvironmentOverrideApplied(util.extensionContext)) { + // If the user has applied the Developer Environment to this workspace, it should apply to all newly opened terminals. + // However, this does not apply to processes that we spawn ourselves in the Pseudoterminal, so we need to specify the + // correct environment in order to emulate the terminal behavior properly. + const env = { ...process.env }; + util.extensionContext?.environmentVariableCollection.forEach((variable: string, mutator: EnvironmentVariableMutator) => { + if (variable.toLowerCase() === "path") { + // Path is special because it has a placeholder to insert the current Path into. + env[variable] = util.resolveVariables(mutator.value); + } else { + env[variable] = mutator.value; + } + }); + this.options.env = env; + } + const splitWriteEmitter = (lines: string | Buffer) => { const splitLines: string[] = lines.toString().split(/\r?\n/g); for (let i: number = 0; i < splitLines.length; i++) { diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index b7737e877c..0a066a4c3c 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -8,6 +8,11 @@ import { vcvars } from 'node-vcvarsall'; import { vswhere } from 'node-vswhere'; import * as path from 'path'; import * as vscode from 'vscode'; +import { CppSettings } from './settings'; + +export function isEnvironmentOverrideApplied(context?: vscode.ExtensionContext) { + return context?.environmentVariableCollection.get('VCToolsInstallDir') !== undefined; +} export async function setEnvironment(context?: vscode.ExtensionContext) { if (!context) { @@ -42,14 +47,15 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { host: match(host, { 'x86': 'x86', 'x64': 'x64' }) ?? 'x64', target: match(target, { 'x86': 'x86', 'x64': 'x64', 'arm64': 'ARM64', 'arm': 'ARM' }) ?? 'x64' }); - const persist = vscode.workspace.getConfiguration('devcmd').get('persistEnvironment') === true; + const settings = new CppSettings(vscode.workspace.workspaceFolders?.at(0)?.uri); context.environmentVariableCollection.clear(); for (const key of Object.keys(vars)) { context.environmentVariableCollection.replace(key, vars[key].replace(`%${key}%`, '${env:' + key + '}')); } context.environmentVariableCollection.description = (arch ? `${arch} ` : '') + 'Developer Command Prompt for ' + vs.displayName; - context.environmentVariableCollection.persistent = persist; + context.environmentVariableCollection.persistent = settings.persistDevEnvironment; + return true; } diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index f21111f035..7ecd4da4b6 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -1565,6 +1565,7 @@ async function showCopilotContent(copilotHoverProvider: CopilotHoverProvider, ho async function onSetDevEnvironment(): Promise { try { await setEnvironment(util.extensionContext); + await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment()); void vscode.window.showInformationMessage(`${util.extensionContext?.environmentVariableCollection.description} successfully set.`); } catch (error: any) { void vscode.window.showErrorMessage(`Developer environment not set: ${error.message}`); @@ -1573,4 +1574,5 @@ async function onSetDevEnvironment(): Promise { async function onClearDevEnvironment(): Promise { util.extensionContext?.environmentVariableCollection.clear(); + await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment()); } diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index 449143439f..58d1fe768a 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -549,6 +549,7 @@ export class CppSettings extends Settings { && this.intelliSenseEngine.toLowerCase() === "default" && vscode.workspace.getConfiguration("workbench").get("colorTheme") !== "Default High Contrast"; } public get sshTargetsView(): string { return this.getAsString("sshTargetsView"); } + public get persistDevEnvironment(): boolean { return this.getAsBoolean("persistDevEnvironment"); } // Returns the value of a setting as a string with proper type validation and checks for valid enum values while returning an undefined value if necessary. private getAsStringOrUndefined(settingName: string): string | undefined { diff --git a/Extension/src/common.ts b/Extension/src/common.ts index fba6c3ac3f..b7c395a16e 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -1564,7 +1564,10 @@ export function hasMsvcEnvironment(): boolean { 'WindowsSDKLibVersion', 'WindowsSDKVersion' ]; - return msvcEnvVars.every((envVarName) => process.env[envVarName] !== undefined && process.env[envVarName] !== ''); + return msvcEnvVars.every(envVarName => + (process.env[envVarName] !== undefined && process.env[envVarName] !== '') || + extensionContext?.environmentVariableCollection?.get(envVarName) !== undefined + ); } function isIntegral(str: string): boolean { diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index e8af0926f2..107af43608 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -1,7 +1,13 @@

Relaunch using the Developer Command Prompt for VS

-

You are using a Windows machine with the MSVC compiler, so you need to start VS Code from the Developer Command Prompt for VS for all environment variables to be set correctly. To relaunch using the Developer Command Prompt for VS:

+

You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:

    -
  1. Open the Developer Command Prompt for VS by typing "developer" in the Windows Start menu. Select the Developer Command Prompt for VS, which will automatically navigate to your current open folder.

    +
  2. Start VS Code from the Developer Command Prompt for VS.

  3. +

    - or -

    +
  4. Run the C/C++: Set Developer Environment command.

    +
+

To relaunch using the Developer Command Prompt for VS

+
    +
  1. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu. Select the Developer Command Prompt for VS, which will automatically navigate to your current open folder.

  2. -
  3. Type "code" into the command prompt and hit enter. This should relaunch VS Code and take you back to this walkthrough.

    +
  4. Type code into the command prompt and hit enter. This should relaunch VS Code and take you back to this walkthrough.

  5. diff --git a/Extension/walkthrough/installcompiler/install-compiler-windows.md b/Extension/walkthrough/installcompiler/install-compiler-windows.md index 81cdda541d..4da07bd3b3 100644 --- a/Extension/walkthrough/installcompiler/install-compiler-windows.md +++ b/Extension/walkthrough/installcompiler/install-compiler-windows.md @@ -8,11 +8,8 @@

    Note: You can use the C++ toolset from Visual Studio Build Tools along with Visual Studio Code to compile, build, and verify any C++ codebase as long as you also have a valid Visual Studio license (either Community, Pro, or Enterprise) that you are actively using to develop that C++ codebase.

    -
  6. Open the Developer Command Prompt for VS by typing 'developer' in the Windows Start menu.

    +
  7. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu.

  8. Check your MSVC installation by typing cl into the Developer Command Prompt for VS. You should see a copyright message with the version and basic usage description.

    -
    -

    Note: To use MSVC from the command line or VS Code, you must run from a Developer Command Prompt for VS. An ordinary shell such as PowerShell, Bash, or the Windows command prompt does not have the necessary path environment variables set.

    -
\ No newline at end of file diff --git a/Extension/walkthrough/installcompiler/install-compiler-windows10.md b/Extension/walkthrough/installcompiler/install-compiler-windows10.md index 5ae6ebadd2..7e215fd65a 100644 --- a/Extension/walkthrough/installcompiler/install-compiler-windows10.md +++ b/Extension/walkthrough/installcompiler/install-compiler-windows10.md @@ -11,12 +11,9 @@

Verifying the compiler installation

    -
  1. Open the Developer Command Prompt for VS by typing 'developer' in the Windows Start menu.

    +
  2. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu.

  3. Check your MSVC installation by typing cl into the Developer Command Prompt for VS. You should see a copyright message with the version and basic usage description.

    -
    -

    Note: To use MSVC from the command line or VS Code, you must run from a Developer Command Prompt for VS. An ordinary shell such as PowerShell, Bash, or the Windows command prompt does not have the necessary path environment variables set.

    -

Other compiler options

diff --git a/Extension/walkthrough/installcompiler/install-compiler-windows11.md b/Extension/walkthrough/installcompiler/install-compiler-windows11.md index ae48333f69..cf9c39f1bf 100644 --- a/Extension/walkthrough/installcompiler/install-compiler-windows11.md +++ b/Extension/walkthrough/installcompiler/install-compiler-windows11.md @@ -11,12 +11,9 @@

Verifying the compiler installation

    -
  1. Open the Developer Command Prompt for VS by typing 'developer' in the Windows Start menu.

    +
  2. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu.

  3. Check your MSVC installation by typing cl into the Developer Command Prompt for VS. You should see a copyright message with the version and basic usage description.

    -
    -

    Note: To use MSVC from the command line or VS Code, you must run from a Developer Command Prompt for VS. An ordinary shell such as PowerShell, Bash, or the Windows command prompt does not have the necessary path environment variables set.

    -

Other compiler options

From afbecf9b85ad0d4dee02fc801b376d02f8fcfe3b Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Tue, 29 Apr 2025 20:46:40 -0700 Subject: [PATCH 03/25] localize --- Extension/src/LanguageServer/devcmd.ts | 57 ++++++++++++++++++-------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index 0a066a4c3c..9e8507bccf 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -8,20 +8,41 @@ import { vcvars } from 'node-vcvarsall'; import { vswhere } from 'node-vswhere'; import * as path from 'path'; import * as vscode from 'vscode'; +import * as nls from 'vscode-nls'; +import { isWindows } from '../constants'; import { CppSettings } from './settings'; +nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); +const localize: nls.LocalizeFunc = nls.loadMessageBundle(); + +const ERROR_NO_CONTEXT = localize('no.context.provided', 'No context provided'); +const NOT_WINDOWS = localize('not.windows', 'This command is only available on Windows'); +const ERROR_NO_VS_FOUND = localize('error.no.vs', 'A Visual Studio installation with the C++ compiler was not found'); +const ERROR_OPERATION_CANCELLED = localize('operation.cancelled', 'The operation was cancelled'); +const ERROR_NO_HOSTS_FOUND = localize('no.hosts', 'No hosts found'); +const CONFIGURING_DEV_ENV = localize('config.dev.env', 'Configuring Developer Environment...'); +const SELECT_VS_INSTALLATION = localize('select.vs.install', 'Select a Visual Studio installation'); +const ADVANCED_OPTIONS = localize('advanced.options', 'Advanced options...'); +const ADVANCED_OPTIONS_DESCRIPTION = localize('advanced.options.desc', 'Select a specific host/target architecture, toolset version, etc.'); +const SELECT_TOOLSET_VERSION = localize('select.toolset', 'Select a toolset version'); +const SELECT_HOST_TARGET_ARCH = localize('select.host.target', 'Select a host and target architecture'); + export function isEnvironmentOverrideApplied(context?: vscode.ExtensionContext) { return context?.environmentVariableCollection.get('VCToolsInstallDir') !== undefined; } export async function setEnvironment(context?: vscode.ExtensionContext) { + if (!isWindows) { + throw new Error(NOT_WINDOWS); + } + if (!context) { - throw new Error('No context provided'); + throw new Error(ERROR_NO_CONTEXT); } const vses = await getVSInstallations(); if (!vses) { - throw new Error('A Visual Studio installation with the C++ compiler was not found'); + throw new Error(ERROR_NO_VS_FOUND); } let vs = await chooseVSInstallation(vses); @@ -34,11 +55,11 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { const vars = await vscode.window.withProgress({ cancellable: false, location: vscode.ProgressLocation.Notification, - title: 'Configuring Developer Environment...' + title: CONFIGURING_DEV_ENV }, () => vcvars.getVCVars(vs, options)); if (!vars || !vars['INCLUDE']) { - throw new Error(`Something went wrong: ${JSON.stringify(vars)}`); + throw new Error(localize('something.wrong', 'Something went wrong: {0}', JSON.stringify(vars))); } const host = vars['VSCMD_ARG_HOST_ARCH']; @@ -53,7 +74,7 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { for (const key of Object.keys(vars)) { context.environmentVariableCollection.replace(key, vars[key].replace(`%${key}%`, '${env:' + key + '}')); } - context.environmentVariableCollection.description = (arch ? `${arch} ` : '') + 'Developer Command Prompt for ' + vs.displayName; + context.environmentVariableCollection.description = localize('dev.env.for', '{0} Developer Environment for {1}', arch, vs.displayName); context.environmentVariableCollection.persistent = settings.persistDevEnvironment; return true; @@ -68,7 +89,7 @@ async function getVSInstallations() { }); if (installations.length === 0) { - throw new Error('A Visual Studio installation with the C++ compiler was not found'); + throw new Error(ERROR_NO_VS_FOUND); } return installations; } @@ -76,17 +97,17 @@ async function getVSInstallations() { async function chooseVSInstallation(installations: vswhere.Installation[]): Promise { const items: vscode.QuickPickItem[] = installations.map(installation => { label: installation.displayName, - description: `Default settings for ${installation.displayName}` + description: localize('default.settings', 'Default settings for {0}', installation.displayName) }); items.push({ - label: 'Advanced options...', - description: 'Select a specific host/target architecture, toolset version, etc.' + label: ADVANCED_OPTIONS, + description: ADVANCED_OPTIONS_DESCRIPTION }); const selection = await vscode.window.showQuickPick(items, { - placeHolder: 'Select a Visual Studio installation' + placeHolder: SELECT_VS_INSTALLATION }); if (!selection) { - throw new Error('The operation was cancelled'); + throw new Error(ERROR_OPERATION_CANCELLED); } return installations.find(installation => installation.displayName === selection.label); @@ -95,7 +116,7 @@ async function chooseVSInstallation(installations: vswhere.Installation[]): Prom async function getAdvancedConfiguration(vses: vswhere.Installation[]): Promise { const compiler = await chooseCompiler(vses); if (!compiler) { - throw new Error('The operation was cancelled'); + throw new Error(ERROR_OPERATION_CANCELLED); } await setOptions(compiler); return compiler; @@ -125,10 +146,10 @@ async function chooseCompiler(vses: vswhere.Installation[]): Promise compiler.version === selection.label && compiler.vs.displayName === selection.description); } @@ -139,13 +160,13 @@ async function setOptions(compiler: Compiler): Promise { if (hostTargets.length > 1) { const items = hostTargets.map(ht => { label: vcvars.getArchitecture(ht), - description: `host = ${ht.host}, target = ${ht.target}` + description: localize('host.target', 'host = {0}, target = {1}', ht.host, ht.target) }); const selection = await vscode.window.showQuickPick(items, { - placeHolder: 'Select a host and target architecture' + placeHolder: SELECT_HOST_TARGET_ARCH }); if (!selection) { - throw new Error('The operation was cancelled'); + throw new Error(ERROR_OPERATION_CANCELLED); } compiler.options.arch = selection.label; } @@ -154,7 +175,7 @@ async function setOptions(compiler: Compiler): Promise { async function getHostsAndTargets(vcPath: string): Promise { const hosts = await fs.readdir(vcPath); if (hosts.length === 0) { - throw new Error('No hosts found'); + throw new Error(ERROR_NO_HOSTS_FOUND); } const hostTargets: vcvars.HostTarget[] = []; for (const host of hosts) { From aefe4ccb880c782661780e8e8beae5b6d437238e Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Tue, 29 Apr 2025 20:47:09 -0700 Subject: [PATCH 04/25] rename variable --- Extension/src/LanguageServer/devcmd.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index 9e8507bccf..1041d5ecad 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -16,7 +16,7 @@ nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFo const localize: nls.LocalizeFunc = nls.loadMessageBundle(); const ERROR_NO_CONTEXT = localize('no.context.provided', 'No context provided'); -const NOT_WINDOWS = localize('not.windows', 'This command is only available on Windows'); +const ERROR_NOT_WINDOWS = localize('not.windows', 'This command is only available on Windows'); const ERROR_NO_VS_FOUND = localize('error.no.vs', 'A Visual Studio installation with the C++ compiler was not found'); const ERROR_OPERATION_CANCELLED = localize('operation.cancelled', 'The operation was cancelled'); const ERROR_NO_HOSTS_FOUND = localize('no.hosts', 'No hosts found'); @@ -33,7 +33,7 @@ export function isEnvironmentOverrideApplied(context?: vscode.ExtensionContext) export async function setEnvironment(context?: vscode.ExtensionContext) { if (!isWindows) { - throw new Error(NOT_WINDOWS); + throw new Error(ERROR_NOT_WINDOWS); } if (!context) { From ff1a8fec94b177e7f4afacf08a5fcf84210a1bce Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Tue, 29 Apr 2025 21:47:04 -0700 Subject: [PATCH 05/25] Reset translations for string without args to fix gulp task --- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md.i18n.json | 2 +- .../open-developer-command-prompt.md | 14 ++++++++------ 14 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 50da12c2cc..81e4157044 100644 --- a/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "使用 {0} 重新启动", - "walkthrough.windows.background.dev.command.prompt": " 你使用的是具有 MSVC 编译器的 Windows 计算机,因此需要从 {0} 启动 VS Code,以正确设置所有环境变量。要使用 {1} 重新启动,请:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "通过在 Windows“开始”菜单中键入“{1}”打开 {0}。选择 {2} 将自动导航到当前打开的文件夹。", "walkthrough.windows.press.f5": "在命令提示符中键入“{0}”,然后按 Enter。此操作应会重新启动 VS Code 并将你带回此演练。" } \ No newline at end of file diff --git a/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index b23a8e0f00..c53630609e 100644 --- a/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "使用 {0} 重新啟動", - "walkthrough.windows.background.dev.command.prompt": " 您正使用 Windows 電腦搭配 MSVC 編譯器,因此您必須從 {0} 啟動 VS Code,以便正確設定所有環境變數。若要使用 {1} 以下重新啟動:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "在 Windows [開始] 功能表中輸入 \"{1}\",以開啟 {0}。選取 {2},這會自動瀏覽至您目前開啟的資料夾。", "walkthrough.windows.press.f5": "在命令提示字元中輸入 \"{0}\",然後按 Enter。這應該會重新啟動 VS Code,並帶您回到此逐步解說。" } \ No newline at end of file diff --git a/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 60a0d692e0..093203d8cc 100644 --- a/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Znovu spustit pomocí {0}", - "walkthrough.windows.background.dev.command.prompt": " Používáte počítač s Windows s kompilátorem MVSC, takže musíte spustit VS Code z {0}, aby se všechny proměnné prostředí správně nastavily. Opětovné spuštění pomocí nástroje {1}:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Otevřete {0} zadáním „{1}“ v nabídce Start ve Windows. Vyberte {2}, čímž automaticky přejdete do aktuální otevřené složky.", "walkthrough.windows.press.f5": "Do příkazového řádku zadejte „{0}“ a stiskněte Enter. Mělo by se znovu spustit VS Code a vrátit se k tomuto názorném postupu. " } \ No newline at end of file diff --git a/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 03d07cc307..771cb72eb1 100644 --- a/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Mit dem {0} neu starten", - "walkthrough.windows.background.dev.command.prompt": " Sie verwenden einen Windows-Computer mit dem MSVC-Compiler. Daher müssen Sie VS Code aus dem {0} starten, damit alle Umgebungsvariablen ordnungsgemäß festgelegt werden. So initiieren Sie den Neustart mithilfe von {1}:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Öffnen Sie die {0}, indem Sie im Windows-Startmenü „{1}“ eingeben. Wählen Sie {2} aus, das Sie automatisch zu Ihrem aktuell geöffneten Ordner navigiert.", "walkthrough.windows.press.f5": "Geben Sie „{0}“ in die Eingabeaufforderung ein, und drücken Sie die EINGABETASTE. Dies sollte VS Code neu starten und Sie zu dieser exemplarischen Vorgehensweise zurückkehren. " } \ No newline at end of file diff --git a/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 9bad7c7eae..8ae6da32fa 100644 --- a/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Volver a iniciar con el {0}", - "walkthrough.windows.background.dev.command.prompt": " Está usando una máquina Windows con el compilador de MSVC, por lo que debe iniciar VS Code desde el {0} para que todas las variables de entorno se establezcan correctamente. Para volver a iniciar con el {1}:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Abra {0} escribiendo '{1}' en el menú Inicio de Windows. Selecciona el {2}, que irá automáticamente a la carpeta abierta actual.", "walkthrough.windows.press.f5": "Escriba '{0}' en el símbolo del sistema y pulse Entrar. Esto debería reiniciar VS Code y hacerte volver a este tutorial. " } \ No newline at end of file diff --git a/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 9c3cf03916..51f7824da0 100644 --- a/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Relancer à l’aide du {0}", - "walkthrough.windows.background.dev.command.prompt": " Vous utilisez une machine Windows avec le compilateur MSVC. Vous devez donc démarrer VS Code à partir de l’{0} pour que toutes les variables d’environnement soient correctement définies. Pour relancer en tirant parti de l’{1} :", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Ouvrez le {0} en tapant « {1} » dans le menu Démarrer de Windows. Sélectionnez le {2}, qui accède automatiquement à votre dossier ouvert actuel.", "walkthrough.windows.press.f5": "Tapez « {0} » dans l’invite de commandes et appuyez sur Entrée. Vous devriez relancer VS Code et revenir à cette procédure pas à pas. " } \ No newline at end of file diff --git a/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index d0ad50441a..500f071d6b 100644 --- a/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Riavvia utilizzando il {0}", - "walkthrough.windows.background.dev.command.prompt": " Si sta usando un computer Windows con il compilatore MSVC, quindi è necessario avviare VS Code da {0} per impostare correttamente tutte le variabili di ambiente. Per riavviare usando {1}:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Aprire il {0} digitando \"{1}\" nel menu Start di Windows. Selezionare il {2}, che passerà automaticamente alla cartella aperta corrente.", "walkthrough.windows.press.f5": "Digitare \"{0}\" nel prompt dei comandi e premere INVIO. È consigliabile riavviare VS Code e tornare a questa procedura dettagliata. " } \ No newline at end of file diff --git a/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 8068620ed2..225ed70461 100644 --- a/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "{0} を使用して再起動する", - "walkthrough.windows.background.dev.command.prompt": " MSVC コンパイラで Windows マシンを使用しているため、すべての環境変数を正しく設定するには、{0} から VS Code を開始する必要があります。{1} を使用して再起動するには:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Windows スタート メニューで \"{1}\" と入力して、{0} を開きます。{2} を選択すると、現在開いているフォルダーに自動的に移動します。", "walkthrough.windows.press.f5": "コマンド プロンプトに \"{0}\" と入力して Enter キーを押します。これにより、VS Code が再起動され、このチュートリアルに戻ります。" } \ No newline at end of file diff --git a/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index b87e3d4ad1..1f2ce6eaf4 100644 --- a/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "{0}을(를) 사용하여 다시 시작", - "walkthrough.windows.background.dev.command.prompt": " MSVC 컴파일러와 함께 Windows 컴퓨터를 사용하고 있으므로 모든 환경 변수를 올바르게 설정하려면 {0}에서 VS Code를 시작해야 합니다. {1}을(를) 사용하여 다시 시작하려면 다음을 수행하세요.", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Windows 시작 메뉴에 \"{1}\"을(를) 입력하여 {0}을(를) 엽니다. {2}을(를) 선택하면 현재 열려 있는 폴더로 자동으로 이동합니다.", "walkthrough.windows.press.f5": "명령 프롬프트에 \"{0}\"을(를) 입력하고 Enter 키를 누릅니다. 이렇게 하면 VS Code가 다시 시작되고 이 연습으로 다시 돌아옵니다. " } \ No newline at end of file diff --git a/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index d7cf404d3f..f81ace39c0 100644 --- a/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Uruchom ponownie przy użyciu {0}", - "walkthrough.windows.background.dev.command.prompt": " Używasz komputera z systemem Windows i kompilatorem programu Microsoft Visual C++ z {0}, więc musisz uruchomić program VS Code od początku, aby wszystkie zmienne środowiskowe zostały poprawnie ustawione. Aby ponownie uruchomić przy użyciu {1}:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Otwórz pozycję {0}, wpisując „{1}” w menu Start systemu Windows. Wybierz {2}, który automatycznie przeniesie do bieżącego otwartego folderu.", "walkthrough.windows.press.f5": "Wpisz „{0}” w wierszu polecenia i naciśnij klawisz Enter. To powinno ponownie uruchomić program VS Code i przenieść Cię z powrotem do tego przewodnika. " } \ No newline at end of file diff --git a/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 4a188415ae..df1e5073d0 100644 --- a/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Reiniciar usando o {0}", - "walkthrough.windows.background.dev.command.prompt": " Você está usando um computador Windows com o compilador do MSVC, portanto, é necessário iniciar o VS Code a partir do {0} para que todas as variáveis de ambiente sejam definidas corretamente. Para reiniciar usando o {1}:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Abra o {0} digitando \"{1}\" no menu Iniciar do Windows. Selecione o {2}, que navegará automaticamente para a pasta atualmente aberta.", "walkthrough.windows.press.f5": "Digite \"{0}\" na solicitação de comando e pressione enter. Isso deve relançar o VS Code e levá-lo de volta a este tutorial. " } \ No newline at end of file diff --git a/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 6e672957d1..8d7cde5722 100644 --- a/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Перезапустить с помощью {0}", - "walkthrough.windows.background.dev.command.prompt": " Вы используете компьютер Windows с компилятором MSVC, поэтому вам необходимо запустить VS Code из {0}, чтобы все переменные среды были установлены правильно. Для перезапуска с помощью {1}:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Откройте {0}, введя \"{1}\" в меню \"Пуск\" в Windows. Выберите {2}. Вы автоматически перейдете к текущей открытой папке.", "walkthrough.windows.press.f5": "Введите \"{0}\" в командную строку и нажмите ВВОД. Это должно перезапустить VS Code и вернуть вас к этому пошаговому руководству. " } \ No newline at end of file diff --git a/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 9159abf1b0..226d5e2d8b 100644 --- a/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Sayfayı kullanarak yeniden {0}", - "walkthrough.windows.background.dev.command.prompt": " MSVC derleyicili bir Windows makinesi kullanıyorsunuz, dolayısıyla tüm ortam değişkenlerinin doğru ayarlanması için {0} öğesinden VS Code'u başlatmanız gerekiyor. {1} kullanarak yeniden başlatmak için:", + "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Windows Başlat menüsüne “{1}” yazarak {0} öğesini açın. Mevcut açık klasörünüze otomatik olarak gidecek olan {2} öğesini seçin.", "walkthrough.windows.press.f5": "Komut istemine \"{0}\" yazın ve enter tuşuna basın. Bu, VS Code'u yeniden başlatmalı ve sizi bu izlenecek yola geri götürmelidir. " } \ No newline at end of file diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index 107af43608..683ee21dd3 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -1,13 +1,15 @@

Relaunch using the Developer Command Prompt for VS

-

You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:

-
    -
  1. Start VS Code from the Developer Command Prompt for VS.

  2. -

    - or -

    -
  3. Run the C/C++: Set Developer Environment command.

    -
+

You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:

+
    +
  • Start VS Code from the Developer Command Prompt for VS, or

    +
  • +
  • Run the C/C++: Set Developer Environment command.

    +
  • +

To relaunch using the Developer Command Prompt for VS

  1. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu. Select the Developer Command Prompt for VS, which will automatically navigate to your current open folder.

  2. Type code into the command prompt and hit enter. This should relaunch VS Code and take you back to this walkthrough.

  3. +
\ No newline at end of file From af6374db9342a0a69b29702493c5da510426628b Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 12:00:56 -0700 Subject: [PATCH 06/25] delete the strings instead --- .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md.i18n.json | 1 - 13 files changed, 13 deletions(-) diff --git a/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 81e4157044..0e68d62fe6 100644 --- a/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "使用 {0} 重新启动", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "通过在 Windows“开始”菜单中键入“{1}”打开 {0}。选择 {2} 将自动导航到当前打开的文件夹。", "walkthrough.windows.press.f5": "在命令提示符中键入“{0}”,然后按 Enter。此操作应会重新启动 VS Code 并将你带回此演练。" } \ No newline at end of file diff --git a/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index c53630609e..4c04eefeed 100644 --- a/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "使用 {0} 重新啟動", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "在 Windows [開始] 功能表中輸入 \"{1}\",以開啟 {0}。選取 {2},這會自動瀏覽至您目前開啟的資料夾。", "walkthrough.windows.press.f5": "在命令提示字元中輸入 \"{0}\",然後按 Enter。這應該會重新啟動 VS Code,並帶您回到此逐步解說。" } \ No newline at end of file diff --git a/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 093203d8cc..39ddcb8e33 100644 --- a/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Znovu spustit pomocí {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Otevřete {0} zadáním „{1}“ v nabídce Start ve Windows. Vyberte {2}, čímž automaticky přejdete do aktuální otevřené složky.", "walkthrough.windows.press.f5": "Do příkazového řádku zadejte „{0}“ a stiskněte Enter. Mělo by se znovu spustit VS Code a vrátit se k tomuto názorném postupu. " } \ No newline at end of file diff --git a/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 771cb72eb1..33180a5564 100644 --- a/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Mit dem {0} neu starten", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Öffnen Sie die {0}, indem Sie im Windows-Startmenü „{1}“ eingeben. Wählen Sie {2} aus, das Sie automatisch zu Ihrem aktuell geöffneten Ordner navigiert.", "walkthrough.windows.press.f5": "Geben Sie „{0}“ in die Eingabeaufforderung ein, und drücken Sie die EINGABETASTE. Dies sollte VS Code neu starten und Sie zu dieser exemplarischen Vorgehensweise zurückkehren. " } \ No newline at end of file diff --git a/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 8ae6da32fa..98b13f51f2 100644 --- a/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Volver a iniciar con el {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Abra {0} escribiendo '{1}' en el menú Inicio de Windows. Selecciona el {2}, que irá automáticamente a la carpeta abierta actual.", "walkthrough.windows.press.f5": "Escriba '{0}' en el símbolo del sistema y pulse Entrar. Esto debería reiniciar VS Code y hacerte volver a este tutorial. " } \ No newline at end of file diff --git a/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 51f7824da0..37a4c1c6eb 100644 --- a/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Relancer à l’aide du {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Ouvrez le {0} en tapant « {1} » dans le menu Démarrer de Windows. Sélectionnez le {2}, qui accède automatiquement à votre dossier ouvert actuel.", "walkthrough.windows.press.f5": "Tapez « {0} » dans l’invite de commandes et appuyez sur Entrée. Vous devriez relancer VS Code et revenir à cette procédure pas à pas. " } \ No newline at end of file diff --git a/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 500f071d6b..e39f05c55d 100644 --- a/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Riavvia utilizzando il {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Aprire il {0} digitando \"{1}\" nel menu Start di Windows. Selezionare il {2}, che passerà automaticamente alla cartella aperta corrente.", "walkthrough.windows.press.f5": "Digitare \"{0}\" nel prompt dei comandi e premere INVIO. È consigliabile riavviare VS Code e tornare a questa procedura dettagliata. " } \ No newline at end of file diff --git a/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 225ed70461..be03f59505 100644 --- a/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "{0} を使用して再起動する", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Windows スタート メニューで \"{1}\" と入力して、{0} を開きます。{2} を選択すると、現在開いているフォルダーに自動的に移動します。", "walkthrough.windows.press.f5": "コマンド プロンプトに \"{0}\" と入力して Enter キーを押します。これにより、VS Code が再起動され、このチュートリアルに戻ります。" } \ No newline at end of file diff --git a/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 1f2ce6eaf4..d6bb46d8ba 100644 --- a/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "{0}을(를) 사용하여 다시 시작", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Windows 시작 메뉴에 \"{1}\"을(를) 입력하여 {0}을(를) 엽니다. {2}을(를) 선택하면 현재 열려 있는 폴더로 자동으로 이동합니다.", "walkthrough.windows.press.f5": "명령 프롬프트에 \"{0}\"을(를) 입력하고 Enter 키를 누릅니다. 이렇게 하면 VS Code가 다시 시작되고 이 연습으로 다시 돌아옵니다. " } \ No newline at end of file diff --git a/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index f81ace39c0..cee9103aa6 100644 --- a/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Uruchom ponownie przy użyciu {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Otwórz pozycję {0}, wpisując „{1}” w menu Start systemu Windows. Wybierz {2}, który automatycznie przeniesie do bieżącego otwartego folderu.", "walkthrough.windows.press.f5": "Wpisz „{0}” w wierszu polecenia i naciśnij klawisz Enter. To powinno ponownie uruchomić program VS Code i przenieść Cię z powrotem do tego przewodnika. " } \ No newline at end of file diff --git a/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index df1e5073d0..ea83252609 100644 --- a/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Reiniciar usando o {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Abra o {0} digitando \"{1}\" no menu Iniciar do Windows. Selecione o {2}, que navegará automaticamente para a pasta atualmente aberta.", "walkthrough.windows.press.f5": "Digite \"{0}\" na solicitação de comando e pressione enter. Isso deve relançar o VS Code e levá-lo de volta a este tutorial. " } \ No newline at end of file diff --git a/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 8d7cde5722..6623b6dc66 100644 --- a/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Перезапустить с помощью {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Откройте {0}, введя \"{1}\" в меню \"Пуск\" в Windows. Выберите {2}. Вы автоматически перейдете к текущей открытой папке.", "walkthrough.windows.press.f5": "Введите \"{0}\" в командную строку и нажмите ВВОД. Это должно перезапустить VS Code и вернуть вас к этому пошаговому руководству. " } \ No newline at end of file diff --git a/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 226d5e2d8b..1b3368b213 100644 --- a/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "walkthrough.windows.title.open.dev.command.prompt": "Sayfayı kullanarak yeniden {0}", - "walkthrough.windows.background.dev.command.prompt": "You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:", "walkthrough.open.command.prompt": "Windows Başlat menüsüne “{1}” yazarak {0} öğesini açın. Mevcut açık klasörünüze otomatik olarak gidecek olan {2} öğesini seçin.", "walkthrough.windows.press.f5": "Komut istemine \"{0}\" yazın ve enter tuşuna basın. Bu, VS Code'u yeniden başlatmalı ve sizi bu izlenecek yola geri götürmelidir. " } \ No newline at end of file From cf58757a00b901b8429f82a0d69008cbc949e523 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 12:16:49 -0700 Subject: [PATCH 07/25] add telemetry --- Extension/src/LanguageServer/extension.ts | 9 ++++++--- .../devcommandprompt/open-developer-command-prompt.md | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 7ecd4da4b6..15feacc797 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -431,8 +431,8 @@ export async function registerCommands(enabled: boolean): Promise { commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExtractToMemberFunction', enabled ? () => onExtractToFunction(false, true) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExpandSelection', enabled ? (r: Range) => onExpandSelection(r) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ShowCopilotHover', enabled ? () => onCopilotHover() : onDisabledCommand)); - commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SetDevEnvironment', enabled ? () => onSetDevEnvironment() : onDisabledCommand)); - commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearDevEnvironment', enabled ? () => onClearDevEnvironment() : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SetDevEnvironment', enabled ? onSetDevEnvironment : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearDevEnvironment', enabled ? onClearDevEnvironment : onDisabledCommand)); } function onDisabledCommand() { @@ -1562,14 +1562,17 @@ async function showCopilotContent(copilotHoverProvider: CopilotHoverProvider, ho return true; } -async function onSetDevEnvironment(): Promise { +async function onSetDevEnvironment(sender?: any): Promise { + let success: boolean = true; try { await setEnvironment(util.extensionContext); await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment()); void vscode.window.showInformationMessage(`${util.extensionContext?.environmentVariableCollection.description} successfully set.`); } catch (error: any) { + success = false; void vscode.window.showErrorMessage(`Developer environment not set: ${error.message}`); } + telemetry.logLanguageServerEvent("SetDevEnvironment", { "sender": util.getSenderType(sender), success: success.toString() }); } async function onClearDevEnvironment(): Promise { diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index 683ee21dd3..d2f88709a6 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -1,9 +1,9 @@

Relaunch using the Developer Command Prompt for VS

-

You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:

+

You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:

  • Start VS Code from the Developer Command Prompt for VS, or

  • -
  • Run the C/C++: Set Developer Environment command.

    +
  • Run the C/C++: Set Developer Environment command.

To relaunch using the Developer Command Prompt for VS

From a6dde1b0e990d4e0f0ba0f00e2cca31463cf356b Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 12:32:21 -0700 Subject: [PATCH 08/25] add a test for Windows --- .../tests/devEnvironment.test.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts diff --git a/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts new file mode 100644 index 0000000000..2adcbfcffc --- /dev/null +++ b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts @@ -0,0 +1,26 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. + * See 'LICENSE' in the project root for license information. + * ------------------------------------------------------------------------------------------ */ +import { equal } from 'assert'; +import { suite } from 'mocha'; +import * as vscode from 'vscode'; +import * as util from '../../../../src/common'; +import { isWindows } from "../../../../src/constants"; + +suite("set developer environment", () => { + if (isWindows) { + test("set developer environment (Windows)", async () => { + const promise = vscode.commands.executeCommand('C_Cpp.SetDevEnvironment', 'test'); + const timer = setInterval(() => { + void vscode.commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem'); + }, 1000); + await promise; + clearInterval(timer); + equal(util.hasMsvcEnvironment(), true, "MSVC environment not set correctly."); + }); + } else { + test("set developer environment (Linux/macOS)", () => { + }); + } +}); From 8075e84fb1121fba6115d8e1c9fb30106f51cebe Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 12:51:25 -0700 Subject: [PATCH 09/25] test for linux/mac --- Extension/src/LanguageServer/extension.ts | 5 ++++- .../SimpleCppProject/tests/devEnvironment.test.ts | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 15feacc797..bde8bf9ad1 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -17,7 +17,7 @@ import { TargetPopulation } from 'vscode-tas-client'; import * as which from 'which'; import { logAndReturn } from '../Utility/Async/returns'; import * as util from '../common'; -import { modelSelector } from '../constants'; +import { isWindows, modelSelector } from '../constants'; import { instrument } from '../instrumentation'; import { getCrashCallStacksChannel } from '../logger'; import { PlatformInformation } from '../platform'; @@ -1570,6 +1570,9 @@ async function onSetDevEnvironment(sender?: any): Promise { void vscode.window.showInformationMessage(`${util.extensionContext?.environmentVariableCollection.description} successfully set.`); } catch (error: any) { success = false; + if (!isWindows) { + throw error; + } void vscode.window.showErrorMessage(`Developer environment not set: ${error.message}`); } telemetry.logLanguageServerEvent("SetDevEnvironment", { "sender": util.getSenderType(sender), success: success.toString() }); diff --git a/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts index 2adcbfcffc..95e2d09267 100644 --- a/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts +++ b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts @@ -20,7 +20,15 @@ suite("set developer environment", () => { equal(util.hasMsvcEnvironment(), true, "MSVC environment not set correctly."); }); } else { - test("set developer environment (Linux/macOS)", () => { + test("set developer environment (Linux/macOS)", async () => { + try { + await vscode.commands.executeCommand('C_Cpp.SetDevEnvironment', 'test'); + equal(false, true, "Should not be able to set developer environment on non-Windows platform."); + } + catch (e) { + equal((e as Error).message, 'This command is only available on Windows', "Should throw error when trying to set developer environment on non-Windows platform."); + } + equal(util.hasMsvcEnvironment(), false, "MSVC environment should not be set on non-Windows platforms."); }); } }); From facd749eff28b5269bb6505fd8fa1f7c1f7d1c32 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 15:32:32 -0700 Subject: [PATCH 10/25] Additional walkthrough tuning --- .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../open-developer-command-prompt.md.i18n.json | 1 - .../devcommandprompt/open-developer-command-prompt.md | 10 +++++----- 14 files changed, 5 insertions(+), 18 deletions(-) diff --git a/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 0e68d62fe6..4f654052a9 100644 --- a/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/chs/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "使用 {0} 重新启动", "walkthrough.open.command.prompt": "通过在 Windows“开始”菜单中键入“{1}”打开 {0}。选择 {2} 将自动导航到当前打开的文件夹。", "walkthrough.windows.press.f5": "在命令提示符中键入“{0}”,然后按 Enter。此操作应会重新启动 VS Code 并将你带回此演练。" } \ No newline at end of file diff --git a/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 4c04eefeed..27d110bdf0 100644 --- a/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/cht/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "使用 {0} 重新啟動", "walkthrough.open.command.prompt": "在 Windows [開始] 功能表中輸入 \"{1}\",以開啟 {0}。選取 {2},這會自動瀏覽至您目前開啟的資料夾。", "walkthrough.windows.press.f5": "在命令提示字元中輸入 \"{0}\",然後按 Enter。這應該會重新啟動 VS Code,並帶您回到此逐步解說。" } \ No newline at end of file diff --git a/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 39ddcb8e33..6620c4386c 100644 --- a/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/csy/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Znovu spustit pomocí {0}", "walkthrough.open.command.prompt": "Otevřete {0} zadáním „{1}“ v nabídce Start ve Windows. Vyberte {2}, čímž automaticky přejdete do aktuální otevřené složky.", "walkthrough.windows.press.f5": "Do příkazového řádku zadejte „{0}“ a stiskněte Enter. Mělo by se znovu spustit VS Code a vrátit se k tomuto názorném postupu. " } \ No newline at end of file diff --git a/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 33180a5564..ae200631ab 100644 --- a/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/deu/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Mit dem {0} neu starten", "walkthrough.open.command.prompt": "Öffnen Sie die {0}, indem Sie im Windows-Startmenü „{1}“ eingeben. Wählen Sie {2} aus, das Sie automatisch zu Ihrem aktuell geöffneten Ordner navigiert.", "walkthrough.windows.press.f5": "Geben Sie „{0}“ in die Eingabeaufforderung ein, und drücken Sie die EINGABETASTE. Dies sollte VS Code neu starten und Sie zu dieser exemplarischen Vorgehensweise zurückkehren. " } \ No newline at end of file diff --git a/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 98b13f51f2..fdb0e1947e 100644 --- a/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/esn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Volver a iniciar con el {0}", "walkthrough.open.command.prompt": "Abra {0} escribiendo '{1}' en el menú Inicio de Windows. Selecciona el {2}, que irá automáticamente a la carpeta abierta actual.", "walkthrough.windows.press.f5": "Escriba '{0}' en el símbolo del sistema y pulse Entrar. Esto debería reiniciar VS Code y hacerte volver a este tutorial. " } \ No newline at end of file diff --git a/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 37a4c1c6eb..9e7f1b479a 100644 --- a/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/fra/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Relancer à l’aide du {0}", "walkthrough.open.command.prompt": "Ouvrez le {0} en tapant « {1} » dans le menu Démarrer de Windows. Sélectionnez le {2}, qui accède automatiquement à votre dossier ouvert actuel.", "walkthrough.windows.press.f5": "Tapez « {0} » dans l’invite de commandes et appuyez sur Entrée. Vous devriez relancer VS Code et revenir à cette procédure pas à pas. " } \ No newline at end of file diff --git a/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index e39f05c55d..92cf22cdc8 100644 --- a/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/ita/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Riavvia utilizzando il {0}", "walkthrough.open.command.prompt": "Aprire il {0} digitando \"{1}\" nel menu Start di Windows. Selezionare il {2}, che passerà automaticamente alla cartella aperta corrente.", "walkthrough.windows.press.f5": "Digitare \"{0}\" nel prompt dei comandi e premere INVIO. È consigliabile riavviare VS Code e tornare a questa procedura dettagliata. " } \ No newline at end of file diff --git a/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index be03f59505..ce5a01e7c2 100644 --- a/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/jpn/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "{0} を使用して再起動する", "walkthrough.open.command.prompt": "Windows スタート メニューで \"{1}\" と入力して、{0} を開きます。{2} を選択すると、現在開いているフォルダーに自動的に移動します。", "walkthrough.windows.press.f5": "コマンド プロンプトに \"{0}\" と入力して Enter キーを押します。これにより、VS Code が再起動され、このチュートリアルに戻ります。" } \ No newline at end of file diff --git a/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index d6bb46d8ba..3972b8e4a0 100644 --- a/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/kor/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "{0}을(를) 사용하여 다시 시작", "walkthrough.open.command.prompt": "Windows 시작 메뉴에 \"{1}\"을(를) 입력하여 {0}을(를) 엽니다. {2}을(를) 선택하면 현재 열려 있는 폴더로 자동으로 이동합니다.", "walkthrough.windows.press.f5": "명령 프롬프트에 \"{0}\"을(를) 입력하고 Enter 키를 누릅니다. 이렇게 하면 VS Code가 다시 시작되고 이 연습으로 다시 돌아옵니다. " } \ No newline at end of file diff --git a/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index cee9103aa6..a1672f55b8 100644 --- a/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/plk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Uruchom ponownie przy użyciu {0}", "walkthrough.open.command.prompt": "Otwórz pozycję {0}, wpisując „{1}” w menu Start systemu Windows. Wybierz {2}, który automatycznie przeniesie do bieżącego otwartego folderu.", "walkthrough.windows.press.f5": "Wpisz „{0}” w wierszu polecenia i naciśnij klawisz Enter. To powinno ponownie uruchomić program VS Code i przenieść Cię z powrotem do tego przewodnika. " } \ No newline at end of file diff --git a/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index ea83252609..469b3e3846 100644 --- a/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/ptb/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Reiniciar usando o {0}", "walkthrough.open.command.prompt": "Abra o {0} digitando \"{1}\" no menu Iniciar do Windows. Selecione o {2}, que navegará automaticamente para a pasta atualmente aberta.", "walkthrough.windows.press.f5": "Digite \"{0}\" na solicitação de comando e pressione enter. Isso deve relançar o VS Code e levá-lo de volta a este tutorial. " } \ No newline at end of file diff --git a/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 6623b6dc66..c785ebd839 100644 --- a/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/rus/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Перезапустить с помощью {0}", "walkthrough.open.command.prompt": "Откройте {0}, введя \"{1}\" в меню \"Пуск\" в Windows. Выберите {2}. Вы автоматически перейдете к текущей открытой папке.", "walkthrough.windows.press.f5": "Введите \"{0}\" в командную строку и нажмите ВВОД. Это должно перезапустить VS Code и вернуть вас к этому пошаговому руководству. " } \ No newline at end of file diff --git a/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json b/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json index 1b3368b213..7fd65d7a18 100644 --- a/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json +++ b/Extension/i18n/trk/walkthrough/devcommandprompt/open-developer-command-prompt.md.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "walkthrough.windows.title.open.dev.command.prompt": "Sayfayı kullanarak yeniden {0}", "walkthrough.open.command.prompt": "Windows Başlat menüsüne “{1}” yazarak {0} öğesini açın. Mevcut açık klasörünüze otomatik olarak gidecek olan {2} öğesini seçin.", "walkthrough.windows.press.f5": "Komut istemine \"{0}\" yazın ve enter tuşuna basın. Bu, VS Code'u yeniden başlatmalı ve sizi bu izlenecek yola geri götürmelidir. " } \ No newline at end of file diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index d2f88709a6..52e7f6bab4 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -1,15 +1,15 @@ -

Relaunch using the Developer Command Prompt for VS

-

You are using a Windows machine with the MSVC compiler, so for all environment variables to be set correctly, you either need to:

+

Apply the Visual Studio Developer Environment

+

The Visual Studio C++ compiler requires several environment variables to be set in order to successfully compile your code. If you are using a Windows machine with the Visual Studio C++ compiler, there are two ways you can ensure the environment is applied:

    -
  • Start VS Code from the Developer Command Prompt for VS, or

    +
  • Start VS Code from the Developer Command Prompt for VS

  • Run the C/C++: Set Developer Environment command.

-

To relaunch using the Developer Command Prompt for VS

+

To relaunch VS Code using the Developer Command Prompt for VS

  1. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu. Select the Developer Command Prompt for VS, which will automatically navigate to your current open folder.

  2. -
  3. Type code into the command prompt and hit enter. This should relaunch VS Code and take you back to this walkthrough.

    +
  4. Type code into the command prompt and hit enter. This should relaunch VS Code and take you back to this walkthrough.

\ No newline at end of file From f2b66ad347ce6ff5fe9bf8da590042fdda8c50e8 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 15:35:31 -0700 Subject: [PATCH 11/25] fix the setting scope --- Extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/package.json b/Extension/package.json index 1adeb99d67..dd83a54c3a 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -3381,7 +3381,7 @@ "type": "boolean", "default": true, "markdownDescription": "%c_cpp.configuration.persistDevEnvironment.markdownDescription%", - "scope": "resource" + "scope": "window" } } } From 6c97412d41629a7dc225236b4c3bbef7b501be96 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 15:40:36 -0700 Subject: [PATCH 12/25] telemetry for build and debug --- Extension/src/Debugger/configurationProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index c90c2916f7..13d46e7c28 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -598,7 +598,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv cancel); if (response === applyDevEnv) { try { - await vscode.commands.executeCommand('C_Cpp.SetDevEnvironment'); + await vscode.commands.executeCommand('C_Cpp.SetDevEnvironment', 'buildAndDebug'); } catch { // Ignore the error, the user will be prompted to apply the environment manually. } From 540537a939d008503214608b9a3f4f3edc8d8224 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 16:05:23 -0700 Subject: [PATCH 13/25] cleanup in devcmd.ts --- Extension/src/LanguageServer/devcmd.ts | 67 ++++++++++++-------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index 1041d5ecad..896eae2150 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -15,17 +15,17 @@ import { CppSettings } from './settings'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); -const ERROR_NO_CONTEXT = localize('no.context.provided', 'No context provided'); -const ERROR_NOT_WINDOWS = localize('not.windows', 'This command is only available on Windows'); -const ERROR_NO_VS_FOUND = localize('error.no.vs', 'A Visual Studio installation with the C++ compiler was not found'); -const ERROR_OPERATION_CANCELLED = localize('operation.cancelled', 'The operation was cancelled'); -const ERROR_NO_HOSTS_FOUND = localize('no.hosts', 'No hosts found'); -const CONFIGURING_DEV_ENV = localize('config.dev.env', 'Configuring Developer Environment...'); -const SELECT_VS_INSTALLATION = localize('select.vs.install', 'Select a Visual Studio installation'); -const ADVANCED_OPTIONS = localize('advanced.options', 'Advanced options...'); -const ADVANCED_OPTIONS_DESCRIPTION = localize('advanced.options.desc', 'Select a specific host/target architecture, toolset version, etc.'); -const SELECT_TOOLSET_VERSION = localize('select.toolset', 'Select a toolset version'); -const SELECT_HOST_TARGET_ARCH = localize('select.host.target', 'Select a host and target architecture'); +const errorNoContext = localize('no.context.provided', 'No context provided'); +const errorNotWindows = localize('not.windows', 'This command is only available on Windows'); +const errorNoVSFound = localize('error.no.vs', 'A Visual Studio installation with the C++ compiler was not found'); +const errorOperationCancelled = localize('operation.cancelled', 'The operation was cancelled'); +const errorNoHostsFound = localize('no.hosts', 'No hosts found'); +const configuringDevEnv = localize('config.dev.env', 'Configuring Developer Environment...'); +const selectVSInstallation = localize('select.vs.install', 'Select a Visual Studio installation'); +const advancedOptions = localize('advanced.options', 'Advanced options...'); +const advancedOptionsDescription = localize('advanced.options.desc', 'Select a specific host/target architecture, toolset version, etc.'); +const selectToolsetVersion = localize('select.toolset', 'Select a toolset version'); +const selectHostTargetArch = localize('select.host.target', 'Select a host and target architecture'); export function isEnvironmentOverrideApplied(context?: vscode.ExtensionContext) { return context?.environmentVariableCollection.get('VCToolsInstallDir') !== undefined; @@ -33,16 +33,16 @@ export function isEnvironmentOverrideApplied(context?: vscode.ExtensionContext) export async function setEnvironment(context?: vscode.ExtensionContext) { if (!isWindows) { - throw new Error(ERROR_NOT_WINDOWS); + throw new Error(errorNotWindows); } if (!context) { - throw new Error(ERROR_NO_CONTEXT); + throw new Error(errorNoContext); } const vses = await getVSInstallations(); if (!vses) { - throw new Error(ERROR_NO_VS_FOUND); + throw new Error(errorNoVSFound); } let vs = await chooseVSInstallation(vses); @@ -55,7 +55,7 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { const vars = await vscode.window.withProgress({ cancellable: false, location: vscode.ProgressLocation.Notification, - title: CONFIGURING_DEV_ENV + title: configuringDevEnv }, () => vcvars.getVCVars(vs, options)); if (!vars || !vars['INCLUDE']) { @@ -89,7 +89,7 @@ async function getVSInstallations() { }); if (installations.length === 0) { - throw new Error(ERROR_NO_VS_FOUND); + throw new Error(errorNoVSFound); } return installations; } @@ -100,34 +100,34 @@ async function chooseVSInstallation(installations: vswhere.Installation[]): Prom description: localize('default.settings', 'Default settings for {0}', installation.displayName) }); items.push({ - label: ADVANCED_OPTIONS, - description: ADVANCED_OPTIONS_DESCRIPTION + label: advancedOptions, + description: advancedOptionsDescription }); const selection = await vscode.window.showQuickPick(items, { - placeHolder: SELECT_VS_INSTALLATION + placeHolder: selectVSInstallation }); if (!selection) { - throw new Error(ERROR_OPERATION_CANCELLED); + throw new Error(errorOperationCancelled); } return installations.find(installation => installation.displayName === selection.label); } +interface Compiler { + version: string; + vs: vswhere.Installation; + options: vcvars.Options; +} + async function getAdvancedConfiguration(vses: vswhere.Installation[]): Promise { const compiler = await chooseCompiler(vses); if (!compiler) { - throw new Error(ERROR_OPERATION_CANCELLED); + throw new Error(errorOperationCancelled); } await setOptions(compiler); return compiler; } -interface Compiler { - version: string; - vs: vswhere.Installation; - options: vcvars.Options; -} - async function chooseCompiler(vses: vswhere.Installation[]): Promise { const compilers: Compiler[] = []; for (const vs of vses) { @@ -146,10 +146,10 @@ async function chooseCompiler(vses: vswhere.Installation[]): Promise compiler.version === selection.label && compiler.vs.displayName === selection.description); } @@ -163,10 +163,10 @@ async function setOptions(compiler: Compiler): Promise { description: localize('host.target', 'host = {0}, target = {1}', ht.host, ht.target) }); const selection = await vscode.window.showQuickPick(items, { - placeHolder: SELECT_HOST_TARGET_ARCH + placeHolder: selectHostTargetArch }); if (!selection) { - throw new Error(ERROR_OPERATION_CANCELLED); + throw new Error(errorOperationCancelled); } compiler.options.arch = selection.label; } @@ -175,7 +175,7 @@ async function setOptions(compiler: Compiler): Promise { async function getHostsAndTargets(vcPath: string): Promise { const hosts = await fs.readdir(vcPath); if (hosts.length === 0) { - throw new Error(ERROR_NO_HOSTS_FOUND); + throw new Error(errorNoHostsFound); } const hostTargets: vcvars.HostTarget[] = []; for (const host of hosts) { @@ -195,9 +195,6 @@ async function getHostsAndTargets(vcPath: string): Promise return hostTargets; } -export function deactivate() { -} - function match(item: string, cases: { [key: string]: T }): T | undefined { return cases[item]; } From bf9bb26e89a23ddb27aa1e625188c42bf4bc8b6e Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 30 Apr 2025 16:35:29 -0700 Subject: [PATCH 14/25] one more update to the walkthrough text --- .../devcommandprompt/open-developer-command-prompt.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index 52e7f6bab4..ea5187dd05 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -1,5 +1,5 @@

Apply the Visual Studio Developer Environment

-

The Visual Studio C++ compiler requires several environment variables to be set in order to successfully compile your code. If you are using a Windows machine with the Visual Studio C++ compiler, there are two ways you can ensure the environment is applied:

+

The Visual Studio C++ compiler requires several environment variables to be set in order to successfully compile your code. If you are using a Windows machine with the Visual Studio C++ compiler, there are two ways you can ensure the environment is applied. You only need to do one of the following:

  • Start VS Code from the Developer Command Prompt for VS

  • @@ -8,8 +8,10 @@

To relaunch VS Code using the Developer Command Prompt for VS

    -
  1. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu. Select the Developer Command Prompt for VS, which will automatically navigate to your current open folder.

    +
  2. Close the current instance of VS Code

  3. -
  4. Type code into the command prompt and hit enter. This should relaunch VS Code and take you back to this walkthrough.

    +
  5. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu then select the Developer Command Prompt for VS.

    +
  6. +
  7. Type code into the command prompt and hit enter. This should relaunch VS Code in the same workspace and take you back to this walkthrough.

\ No newline at end of file From 80c9d8e997938d92d46e66a5b206558ae02d0a7c Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Thu, 1 May 2025 11:59:33 -0700 Subject: [PATCH 15/25] PR feedback --- Extension/package.json | 16 +++--- Extension/package.nls.json | 10 ++-- .../src/Debugger/configurationProvider.ts | 50 +++++++++++-------- Extension/src/LanguageServer/devcmd.ts | 30 ++++++++--- Extension/src/LanguageServer/extension.ts | 20 +++++--- Extension/src/LanguageServer/settings.ts | 2 +- .../tests/devEnvironment.test.ts | 7 +-- 7 files changed, 80 insertions(+), 55 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index dd83a54c3a..8a7f877e78 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -3377,10 +3377,10 @@ "markdownDescription": "%c_cpp.configuration.copilotHover.markdownDescription%", "scope": "window" }, - "C_Cpp.persistDevEnvironment": { + "C_Cpp.persistVSDeveloperEnvironment": { "type": "boolean", "default": true, - "markdownDescription": "%c_cpp.configuration.persistDevEnvironment.markdownDescription%", + "markdownDescription": "%c_cpp.configuration.persistVSDeveloperEnvironment.markdownDescription%", "scope": "window" } } @@ -3548,13 +3548,13 @@ "icon": "$(run)" }, { - "command": "C_Cpp.SetDevEnvironment", - "title": "%c_cpp.command.SetDevEnvironment.title%", + "command": "C_Cpp.SetVSDevEnvironment", + "title": "%c_cpp.command.SetVSDevEnvironment.title%", "category": "C/C++" }, { - "command": "C_Cpp.ClearDevEnvironment", - "title": "%c_cpp.command.ClearDevEnvironment.title%", + "command": "C_Cpp.ClearVSDevEnvironment", + "title": "%c_cpp.command.ClearVSDevEnvironment.title%", "category": "C/C++" }, { @@ -6029,11 +6029,11 @@ "when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && config.C_Cpp.debugShortcut && cpptools.buildAndDebug.isSourceFile" }, { - "command": "C_Cpp.SetDevEnvironment", + "command": "C_Cpp.SetVSDevEnvironment", "when": "workspacePlatform == windows" }, { - "command": "C_Cpp.ClearDevEnvironment", + "command": "C_Cpp.ClearVSDevEnvironment", "when": "workspacePlatform == windows" }, { diff --git a/Extension/package.nls.json b/Extension/package.nls.json index df23e4cf7e..0cf87bc0cf 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -37,8 +37,8 @@ "c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Clear All Code Analysis Problems", "c_cpp.command.BuildAndDebugFile.title": "Debug C/C++ File", "c_cpp.command.BuildAndRunFile.title": "Run C/C++ File", - "c_cpp.command.SetDevEnvironment.title": "Set Developer Environment", - "c_cpp.command.ClearDevEnvironment.title": "Clear Developer Environment", + "c_cpp.command.SetVSDevEnvironment.title": "Set Visual Studio Developer Environment", + "c_cpp.command.ClearVSDevEnvironment.title": "Clear Visual Studio Developer Environment", "c_cpp.command.AddDebugConfiguration.title": "Add Debug Configuration", "c_cpp.command.GenerateDoxygenComment.title": "Generate Doxygen Comment", "c_cpp.command.addSshTarget.title": "Add SSH target", @@ -845,7 +845,7 @@ ] }, "c_cpp.configuration.debugShortcut.description": "Show the \"Run and Debug\" play button and \"Add Debug Configuration\" gear in the editor title bar for C++ files.", - "c_cpp.configuration.persistDevEnvironment.markdownDescription": "Remember the last used Visual Studio developer environment for the current workspace. This setting is only applicable for Windows.", + "c_cpp.configuration.persistVSDeveloperEnvironment.markdownDescription": "Remember the last used Visual Studio developer environment for the current workspace. This setting is only applicable for Windows.", "c_cpp.debuggers.pipeTransport.description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).", "c_cpp.debuggers.pipeTransport.default.pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'.", "c_cpp.debuggers.pipeTransport.default.debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb.", @@ -1034,9 +1034,9 @@ ] }, "c_cpp.walkthrough.command.prompt.description": { - "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio Developer Environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetDevEnvironment?%22walkthrough%22)", + "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio Developer Environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetVSDevEnvironment?%22walkthrough%22)", "comment": [ - "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](C_Cpp.SetDevEnvironment?%22walkthrough%22)\"}" + "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](C_Cpp.SetVSDevEnvironment?%22walkthrough%22)\"}" ] }, "c_cpp.walkthrough.run.debug.title": "Run and debug your C++ file", diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index 13d46e7c28..8338f081c5 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -586,31 +586,37 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv * @returns `true` if the Developer Environment is not available and an error was shown to the user, `false` if the Developer Environment is available or the user chose to apply it. */ private async showErrorIfClNotAvailable(_configurationLabel: string): Promise { - if (!util.hasMsvcEnvironment()) { - const applyDevEnv = localize("apply.dev.env", "Apply Developer Environment"); - const cancel = localize("cancel", "Cancel"); - const response = await vscode.window.showErrorMessage( - localize({ - key: "cl.exe.not.available", - comment: ["{0} is a command option in a menu."] - }, "{0} requires the Visual Studio Developer Environment.", `cl.exe ${this.buildAndDebugActiveFileStr()}`), - applyDevEnv, - cancel); - if (response === applyDevEnv) { - try { - await vscode.commands.executeCommand('C_Cpp.SetDevEnvironment', 'buildAndDebug'); - } catch { - // Ignore the error, the user will be prompted to apply the environment manually. - } - } - if (util.hasMsvcEnvironment()) { - return false; + if (util.hasMsvcEnvironment()) { + return false; // No error to show + } + + const applyDevEnv = localize("apply.dev.env", "Apply Developer Environment"); + const cancel = localize("cancel", "Cancel"); + const response = await vscode.window.showErrorMessage( + localize({ + key: "cl.exe.not.available", + comment: ["{0} is a command option in a menu."] + }, "{0} requires the Visual Studio Developer Environment.", `cl.exe ${this.buildAndDebugActiveFileStr()}`), + applyDevEnv, + cancel); + if (response === applyDevEnv) { + try { + await vscode.commands.executeCommand('C_Cpp.SetVSDevEnvironment', 'buildAndDebug'); + } catch (e: any) { + // Ignore the error, the user will be prompted to apply the environment manually. } - void vscode.window.showErrorMessage( - localize('dev.env.not.applied', 'The Visual Studio Developer Environment was not applied. Please try again or run VS Code from the Developer Command Prompt for VS.')); + } + if (response === cancel) { + // A message was already shown, so exit early noting that the environment is not available. We don't need to show another error message. return true; } - return false; + + if (util.hasMsvcEnvironment()) { + return false; + } + void vscode.window.showErrorMessage( + localize('dev.env.not.applied', 'The Visual Studio Developer Environment was not applied. Please try again or run VS Code from the Developer Command Prompt for VS.')); + return true; } private getLLDBFrameworkPath(): string | undefined { diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index 896eae2150..e35dd21b2f 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -16,9 +16,9 @@ nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFo const localize: nls.LocalizeFunc = nls.loadMessageBundle(); const errorNoContext = localize('no.context.provided', 'No context provided'); -const errorNotWindows = localize('not.windows', 'This command is only available on Windows'); +const errorNotWindows = localize('not.windows', 'The "Set Visual Studio Developer Environment" command is only available on Windows'); const errorNoVSFound = localize('error.no.vs', 'A Visual Studio installation with the C++ compiler was not found'); -const errorOperationCancelled = localize('operation.cancelled', 'The operation was cancelled'); +export const errorOperationCancelled = localize('operation.cancelled', 'The operation was cancelled'); const errorNoHostsFound = localize('no.hosts', 'No hosts found'); const configuringDevEnv = localize('config.dev.env', 'Configuring Developer Environment...'); const selectVSInstallation = localize('select.vs.install', 'Select a Visual Studio installation'); @@ -74,7 +74,7 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { for (const key of Object.keys(vars)) { context.environmentVariableCollection.replace(key, vars[key].replace(`%${key}%`, '${env:' + key + '}')); } - context.environmentVariableCollection.description = localize('dev.env.for', '{0} Developer Environment for {1}', arch, vs.displayName); + context.environmentVariableCollection.description = localize('dev.env.for', '{0} Developer Environment for {1}', arch, vsDisplayNameWithSuffix(vs)); context.environmentVariableCollection.persistent = settings.persistDevEnvironment; return true; @@ -94,10 +94,24 @@ async function getVSInstallations() { return installations; } +function vsDisplayNameWithSuffix(installation: vswhere.Installation): string { + const suffix = (() => { + if (installation.channelId.endsWith('.main')) { + return 'main'; + } else if (installation.channelId.endsWith('.IntPreview')) { + return 'Int Preview'; + } else if (installation.channelId.endsWith('.Preview')) { + return 'Preview'; + } + return ''; + })(); + return `${installation.displayName}${suffix ? ` ${suffix}` : ''}`; +} + async function chooseVSInstallation(installations: vswhere.Installation[]): Promise { const items: vscode.QuickPickItem[] = installations.map(installation => { - label: installation.displayName, - description: localize('default.settings', 'Default settings for {0}', installation.displayName) + label: vsDisplayNameWithSuffix(installation), + detail: localize('default.env', 'Default environment for {0}', installation.catalog.productDisplayVersion) }); items.push({ label: advancedOptions, @@ -110,7 +124,7 @@ async function chooseVSInstallation(installations: vswhere.Installation[]): Prom throw new Error(errorOperationCancelled); } - return installations.find(installation => installation.displayName === selection.label); + return installations.find(installation => vsDisplayNameWithSuffix(installation) === selection.label); } interface Compiler { @@ -143,7 +157,7 @@ async function chooseCompiler(vses: vswhere.Installation[]): Promise { label: compiler.version, - description: compiler.vs.displayName + description: vsDisplayNameWithSuffix(compiler.vs) }); const selection = await vscode.window.showQuickPick(items, { placeHolder: selectToolsetVersion @@ -151,7 +165,7 @@ async function chooseCompiler(vses: vswhere.Installation[]): Promise compiler.version === selection.label && compiler.vs.displayName === selection.description); + return compilers.find(compiler => compiler.version === selection.label && vsDisplayNameWithSuffix(compiler.vs) === selection.description); } async function setOptions(compiler: Compiler): Promise { diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index bde8bf9ad1..8f1ac5db0c 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -29,7 +29,7 @@ import { CodeActionDiagnosticInfo, CodeAnalysisDiagnosticIdentifiersAndUri, code import { registerRelatedFilesProvider } from './copilotProviders'; import { CppBuildTaskProvider } from './cppBuildTaskProvider'; import { getCustomConfigProviders } from './customProviders'; -import { setEnvironment } from './devcmd'; +import { errorOperationCancelled, setEnvironment } from './devcmd'; import { getLanguageConfig } from './languageConfig'; import { CppConfigurationLanguageModelTool } from './lmTool'; import { getLocaleId } from './localization'; @@ -431,8 +431,8 @@ export async function registerCommands(enabled: boolean): Promise { commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExtractToMemberFunction', enabled ? () => onExtractToFunction(false, true) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExpandSelection', enabled ? (r: Range) => onExpandSelection(r) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ShowCopilotHover', enabled ? () => onCopilotHover() : onDisabledCommand)); - commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SetDevEnvironment', enabled ? onSetDevEnvironment : onDisabledCommand)); - commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearDevEnvironment', enabled ? onClearDevEnvironment : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SetVSDevEnvironment', enabled ? onSetVSDevEnvironment : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearVSDevEnvironment', enabled ? onClearVSDevEnvironment : onDisabledCommand)); } function onDisabledCommand() { @@ -1562,23 +1562,27 @@ async function showCopilotContent(copilotHoverProvider: CopilotHoverProvider, ho return true; } -async function onSetDevEnvironment(sender?: any): Promise { +async function onSetVSDevEnvironment(sender?: any): Promise { let success: boolean = true; try { await setEnvironment(util.extensionContext); await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment()); - void vscode.window.showInformationMessage(`${util.extensionContext?.environmentVariableCollection.description} successfully set.`); + if (sender !== 'buildAndDebug') { + void vscode.window.showInformationMessage(`${util.extensionContext?.environmentVariableCollection.description} successfully set.`); + } } catch (error: any) { success = false; if (!isWindows) { throw error; } - void vscode.window.showErrorMessage(`Developer environment not set: ${error.message}`); + if (error.message !== errorOperationCancelled) { + void vscode.window.showErrorMessage(`Failed to apply VS developer environment: ${error.message}`); + } } - telemetry.logLanguageServerEvent("SetDevEnvironment", { "sender": util.getSenderType(sender), success: success.toString() }); + telemetry.logLanguageServerEvent("SetVSDevEnvironment", { "sender": util.getSenderType(sender), success: success.toString() }); } -async function onClearDevEnvironment(): Promise { +async function onClearVSDevEnvironment(): Promise { util.extensionContext?.environmentVariableCollection.clear(); await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment()); } diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index 58d1fe768a..b9566b146f 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -549,7 +549,7 @@ export class CppSettings extends Settings { && this.intelliSenseEngine.toLowerCase() === "default" && vscode.workspace.getConfiguration("workbench").get("colorTheme") !== "Default High Contrast"; } public get sshTargetsView(): string { return this.getAsString("sshTargetsView"); } - public get persistDevEnvironment(): boolean { return this.getAsBoolean("persistDevEnvironment"); } + public get persistDevEnvironment(): boolean { return this.getAsBoolean("persistVSDeveloperEnvironment"); } // Returns the value of a setting as a string with proper type validation and checks for valid enum values while returning an undefined value if necessary. private getAsStringOrUndefined(settingName: string): string | undefined { diff --git a/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts index 95e2d09267..8a2e08a5ae 100644 --- a/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts +++ b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts @@ -7,11 +7,12 @@ import { suite } from 'mocha'; import * as vscode from 'vscode'; import * as util from '../../../../src/common'; import { isWindows } from "../../../../src/constants"; +import { errorOperationCancelled } from '../../../../src/LanguageServer/devcmd'; suite("set developer environment", () => { if (isWindows) { test("set developer environment (Windows)", async () => { - const promise = vscode.commands.executeCommand('C_Cpp.SetDevEnvironment', 'test'); + const promise = vscode.commands.executeCommand('C_Cpp.SetVSDevEnvironment', 'test'); const timer = setInterval(() => { void vscode.commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem'); }, 1000); @@ -22,11 +23,11 @@ suite("set developer environment", () => { } else { test("set developer environment (Linux/macOS)", async () => { try { - await vscode.commands.executeCommand('C_Cpp.SetDevEnvironment', 'test'); + await vscode.commands.executeCommand('C_Cpp.SetVSDevEnvironment', 'test'); equal(false, true, "Should not be able to set developer environment on non-Windows platform."); } catch (e) { - equal((e as Error).message, 'This command is only available on Windows', "Should throw error when trying to set developer environment on non-Windows platform."); + equal((e as Error).message, errorOperationCancelled, "Should throw error when trying to set developer environment on non-Windows platform."); } equal(util.hasMsvcEnvironment(), false, "MSVC environment should not be set on non-Windows platforms."); }); From 5281786466622d4a9b9b11b3005216e32fe0d29c Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Mon, 5 May 2025 16:33:51 -0700 Subject: [PATCH 16/25] Address PR feedback --- Extension/src/Debugger/configurationProvider.ts | 15 +++++++++------ .../src/LanguageServer/cppBuildTaskProvider.ts | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index 8338f081c5..9b880a8723 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -87,6 +87,9 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv const defaultConfig: CppDebugConfiguration[] = this.findDefaultConfig(configs); // If there was only one config defined for the default task, choose that config, otherwise ask the user to choose. if (defaultConfig.length === 1) { + if (this.isClConfiguration(defaultConfig[0].name) && await this.showErrorIfClNotAvailable(defaultConfig[0].label)) { + return []; // Cannot continue with build/debug. + } return defaultConfig; } @@ -120,8 +123,8 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv return []; // User canceled it. } - if (this.isClConfiguration(selection.label)) { - await this.showErrorIfClNotAvailable(selection.label); + if (this.isClConfiguration(selection.label) && await this.showErrorIfClNotAvailable(selection.label)) { + return []; // Cannot continue with build/debug. } return [selection.configuration]; @@ -578,8 +581,8 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv return `${localize("build.and.debug.active.file", 'build and debug active file')}`; } - private isClConfiguration(configurationLabel: string): boolean { - return configurationLabel.startsWith("C/C++: cl.exe"); + private isClConfiguration(configurationLabel?: string): boolean { + return !!configurationLabel?.startsWith("C/C++: cl.exe"); } /** @@ -606,7 +609,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv // Ignore the error, the user will be prompted to apply the environment manually. } } - if (response === cancel) { + if (response === cancel || response === undefined) { // A message was already shown, so exit early noting that the environment is not available. We don't need to show another error message. return true; } @@ -615,7 +618,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv return false; } void vscode.window.showErrorMessage( - localize('dev.env.not.applied', 'The Visual Studio Developer Environment was not applied. Please try again or run VS Code from the Developer Command Prompt for VS.')); + localize('dev.env.not.applied', 'The source code could not be built because the Visual Studio Developer Environment was not applied.')); return true; } diff --git a/Extension/src/LanguageServer/cppBuildTaskProvider.ts b/Extension/src/LanguageServer/cppBuildTaskProvider.ts index 758b9167a4..40b3cbbf2c 100644 --- a/Extension/src/LanguageServer/cppBuildTaskProvider.ts +++ b/Extension/src/LanguageServer/cppBuildTaskProvider.ts @@ -246,7 +246,7 @@ export class CppBuildTaskProvider implements TaskProvider { const cppBuildTask: CppBuildTask = new Task(definition, TaskScope.Workspace, task.label, ext.CppSourceStr); cppBuildTask.detail = task.detail; cppBuildTask.existing = true; - if (task.group.isDefault) { + if (util.isObject(task.group) && task.group.isDefault) { cppBuildTask.isDefault = true; } return cppBuildTask; From 901312411478329da4c008186849f091305b33dd Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Tue, 6 May 2025 09:06:33 -0700 Subject: [PATCH 17/25] rename telemetry property --- Extension/src/LanguageServer/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 8f1ac5db0c..0fe3b2c7e9 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -1579,7 +1579,7 @@ async function onSetVSDevEnvironment(sender?: any): Promise { void vscode.window.showErrorMessage(`Failed to apply VS developer environment: ${error.message}`); } } - telemetry.logLanguageServerEvent("SetVSDevEnvironment", { "sender": util.getSenderType(sender), success: success.toString() }); + telemetry.logLanguageServerEvent("SetVSDevEnvironment", { "sender": util.getSenderType(sender), "resultcode": success.toString() }); } async function onClearVSDevEnvironment(): Promise { From 98f430eceda222a354501421a489ea348dc8ef9b Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Tue, 6 May 2025 16:23:52 -0700 Subject: [PATCH 18/25] PR feedback --- Extension/package.json | 18 +++++++++--------- Extension/package.nls.json | 10 +++++----- .../src/Debugger/configurationProvider.ts | 2 +- Extension/src/LanguageServer/extension.ts | 10 +++++----- Extension/src/LanguageServer/settings.ts | 2 +- .../tests/devEnvironment.test.ts | 11 ++++++++--- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index da3040099f..eef3df79b0 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -3377,10 +3377,10 @@ "markdownDescription": "%c_cpp.configuration.copilotHover.markdownDescription%", "scope": "window" }, - "C_Cpp.persistVSDeveloperEnvironment": { + "C_Cpp.persistVsDeveloperEnvironment": { "type": "boolean", "default": true, - "markdownDescription": "%c_cpp.configuration.persistVSDeveloperEnvironment.markdownDescription%", + "markdownDescription": "%c_cpp.configuration.persistVsDeveloperEnvironment.markdownDescription%", "scope": "window" } } @@ -3548,13 +3548,13 @@ "icon": "$(run)" }, { - "command": "C_Cpp.SetVSDevEnvironment", - "title": "%c_cpp.command.SetVSDevEnvironment.title%", + "command": "C_Cpp.SetVsDeveloperEnvironment", + "title": "%c_cpp.command.SetVsDeveloperEnvironment.title%", "category": "C/C++" }, { - "command": "C_Cpp.ClearVSDevEnvironment", - "title": "%c_cpp.command.ClearVSDevEnvironment.title%", + "command": "C_Cpp.ClearVsDeveloperEnvironment", + "title": "%c_cpp.command.ClearVsDeveloperEnvironment.title%", "category": "C/C++" }, { @@ -6029,11 +6029,11 @@ "when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && config.C_Cpp.debugShortcut && cpptools.buildAndDebug.isSourceFile" }, { - "command": "C_Cpp.SetVSDevEnvironment", + "command": "C_Cpp.SetVsDeveloperEnvironment", "when": "workspacePlatform == windows" }, { - "command": "C_Cpp.ClearVSDevEnvironment", + "command": "C_Cpp.ClearVsDeveloperEnvironment", "when": "workspacePlatform == windows" }, { @@ -6677,4 +6677,4 @@ "postcss": "^8.4.31", "gulp-typescript/**/glob-parent": "^5.1.2" } -} +} \ No newline at end of file diff --git a/Extension/package.nls.json b/Extension/package.nls.json index 0cf87bc0cf..575d0456b0 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -37,8 +37,8 @@ "c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Clear All Code Analysis Problems", "c_cpp.command.BuildAndDebugFile.title": "Debug C/C++ File", "c_cpp.command.BuildAndRunFile.title": "Run C/C++ File", - "c_cpp.command.SetVSDevEnvironment.title": "Set Visual Studio Developer Environment", - "c_cpp.command.ClearVSDevEnvironment.title": "Clear Visual Studio Developer Environment", + "c_cpp.command.SetVsDeveloperEnvironment.title": "Set Visual Studio Developer Environment", + "c_cpp.command.ClearVsDeveloperEnvironment.title": "Clear Visual Studio Developer Environment", "c_cpp.command.AddDebugConfiguration.title": "Add Debug Configuration", "c_cpp.command.GenerateDoxygenComment.title": "Generate Doxygen Comment", "c_cpp.command.addSshTarget.title": "Add SSH target", @@ -845,7 +845,7 @@ ] }, "c_cpp.configuration.debugShortcut.description": "Show the \"Run and Debug\" play button and \"Add Debug Configuration\" gear in the editor title bar for C++ files.", - "c_cpp.configuration.persistVSDeveloperEnvironment.markdownDescription": "Remember the last used Visual Studio developer environment for the current workspace. This setting is only applicable for Windows.", + "c_cpp.configuration.persistVsDeveloperEnvironment.markdownDescription": "Remember the last used Visual Studio developer environment for the current workspace. This setting is only applicable for Windows.", "c_cpp.debuggers.pipeTransport.description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).", "c_cpp.debuggers.pipeTransport.default.pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'.", "c_cpp.debuggers.pipeTransport.default.debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb.", @@ -1034,9 +1034,9 @@ ] }, "c_cpp.walkthrough.command.prompt.description": { - "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio Developer Environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetVSDevEnvironment?%22walkthrough%22)", + "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio Developer Environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)", "comment": [ - "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](C_Cpp.SetVSDevEnvironment?%22walkthrough%22)\"}" + "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)\"}" ] }, "c_cpp.walkthrough.run.debug.title": "Run and debug your C++ file", diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index 9b880a8723..55a61a0d35 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -604,7 +604,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv cancel); if (response === applyDevEnv) { try { - await vscode.commands.executeCommand('C_Cpp.SetVSDevEnvironment', 'buildAndDebug'); + await vscode.commands.executeCommand('C_Cpp.SetVsDeveloperEnvironment', 'buildAndDebug'); } catch (e: any) { // Ignore the error, the user will be prompted to apply the environment manually. } diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 0fe3b2c7e9..66bd76178b 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -431,8 +431,8 @@ export async function registerCommands(enabled: boolean): Promise { commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExtractToMemberFunction', enabled ? () => onExtractToFunction(false, true) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ExpandSelection', enabled ? (r: Range) => onExpandSelection(r) : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ShowCopilotHover', enabled ? () => onCopilotHover() : onDisabledCommand)); - commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SetVSDevEnvironment', enabled ? onSetVSDevEnvironment : onDisabledCommand)); - commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearVSDevEnvironment', enabled ? onClearVSDevEnvironment : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SetVsDeveloperEnvironment', enabled ? onSetVsDeveloperEnvironment : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearVsDeveloperEnvironment', enabled ? onClearVsDeveloperEnvironment : onDisabledCommand)); } function onDisabledCommand() { @@ -1562,7 +1562,7 @@ async function showCopilotContent(copilotHoverProvider: CopilotHoverProvider, ho return true; } -async function onSetVSDevEnvironment(sender?: any): Promise { +async function onSetVsDeveloperEnvironment(sender?: any): Promise { let success: boolean = true; try { await setEnvironment(util.extensionContext); @@ -1579,10 +1579,10 @@ async function onSetVSDevEnvironment(sender?: any): Promise { void vscode.window.showErrorMessage(`Failed to apply VS developer environment: ${error.message}`); } } - telemetry.logLanguageServerEvent("SetVSDevEnvironment", { "sender": util.getSenderType(sender), "resultcode": success.toString() }); + telemetry.logLanguageServerEvent("SetVsDeveloperEnvironment", { "sender": util.getSenderType(sender), "resultcode": success.toString() }); } -async function onClearVSDevEnvironment(): Promise { +async function onClearVsDeveloperEnvironment(): Promise { util.extensionContext?.environmentVariableCollection.clear(); await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment()); } diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index b9566b146f..393ba512d5 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -549,7 +549,7 @@ export class CppSettings extends Settings { && this.intelliSenseEngine.toLowerCase() === "default" && vscode.workspace.getConfiguration("workbench").get("colorTheme") !== "Default High Contrast"; } public get sshTargetsView(): string { return this.getAsString("sshTargetsView"); } - public get persistDevEnvironment(): boolean { return this.getAsBoolean("persistVSDeveloperEnvironment"); } + public get persistDevEnvironment(): boolean { return this.getAsBoolean("persistVsDeveloperEnvironment"); } // Returns the value of a setting as a string with proper type validation and checks for valid enum values while returning an undefined value if necessary. private getAsStringOrUndefined(settingName: string): string | undefined { diff --git a/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts index 8a2e08a5ae..349a8803bb 100644 --- a/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts +++ b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts @@ -12,7 +12,7 @@ import { errorOperationCancelled } from '../../../../src/LanguageServer/devcmd'; suite("set developer environment", () => { if (isWindows) { test("set developer environment (Windows)", async () => { - const promise = vscode.commands.executeCommand('C_Cpp.SetVSDevEnvironment', 'test'); + const promise = vscode.commands.executeCommand('C_Cpp.SetVsDeveloperEnvironment', 'test'); const timer = setInterval(() => { void vscode.commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem'); }, 1000); @@ -20,10 +20,15 @@ suite("set developer environment", () => { clearInterval(timer); equal(util.hasMsvcEnvironment(), true, "MSVC environment not set correctly."); }); + + test("clear developer environment (Windows)", async () => { + await vscode.commands.executeCommand('C_Cpp.ClearVsDeveloperEnvironment'); + equal(util.hasMsvcEnvironment(), false, "MSVC environment not cleared correctly."); + }); } else { - test("set developer environment (Linux/macOS)", async () => { + test("should not be able to set developer environment (Linux/macOS)", async () => { try { - await vscode.commands.executeCommand('C_Cpp.SetVSDevEnvironment', 'test'); + await vscode.commands.executeCommand('C_Cpp.SetVsDeveloperEnvironment', 'test'); equal(false, true, "Should not be able to set developer environment on non-Windows platform."); } catch (e) { From b68f025da79307c10cf17b589538df50b8463726 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Tue, 6 May 2025 16:29:51 -0700 Subject: [PATCH 19/25] consistency in commands and user-visible text --- Extension/package.nls.json | 2 +- Extension/src/Debugger/configurationProvider.ts | 7 ++++--- Extension/src/LanguageServer/cppBuildTaskProvider.ts | 2 +- .../devcommandprompt/open-developer-command-prompt.md | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Extension/package.nls.json b/Extension/package.nls.json index 575d0456b0..d3c07cfdc6 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -1034,7 +1034,7 @@ ] }, "c_cpp.walkthrough.command.prompt.description": { - "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio Developer Environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)", + "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio developer environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)", "comment": [ "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)\"}" ] diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index 55a61a0d35..cdb1d795f8 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -586,7 +586,8 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv } /** - * @returns `true` if the Developer Environment is not available and an error was shown to the user, `false` if the Developer Environment is available or the user chose to apply it. + * @returns `true` if the VS developer environment is not available and an error was shown to the user, + * `false` if the VS developer environment is available or the user chose to apply it. */ private async showErrorIfClNotAvailable(_configurationLabel: string): Promise { if (util.hasMsvcEnvironment()) { @@ -599,7 +600,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv localize({ key: "cl.exe.not.available", comment: ["{0} is a command option in a menu."] - }, "{0} requires the Visual Studio Developer Environment.", `cl.exe ${this.buildAndDebugActiveFileStr()}`), + }, "{0} requires the Visual Studio developer environment.", `cl.exe ${this.buildAndDebugActiveFileStr()}`), applyDevEnv, cancel); if (response === applyDevEnv) { @@ -618,7 +619,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv return false; } void vscode.window.showErrorMessage( - localize('dev.env.not.applied', 'The source code could not be built because the Visual Studio Developer Environment was not applied.')); + localize('dev.env.not.applied', 'The source code could not be built because the Visual Studio developer environment was not applied.')); return true; } diff --git a/Extension/src/LanguageServer/cppBuildTaskProvider.ts b/Extension/src/LanguageServer/cppBuildTaskProvider.ts index 6dae2a1c10..0b7113fb2b 100644 --- a/Extension/src/LanguageServer/cppBuildTaskProvider.ts +++ b/Extension/src/LanguageServer/cppBuildTaskProvider.ts @@ -432,7 +432,7 @@ class CustomBuildTaskTerminal implements Pseudoterminal { } if (isEnvironmentOverrideApplied(util.extensionContext)) { - // If the user has applied the Developer Environment to this workspace, it should apply to all newly opened terminals. + // If the user has applied the developer environment to this workspace, it should apply to all newly opened terminals. // However, this does not apply to processes that we spawn ourselves in the Pseudoterminal, so we need to specify the // correct environment in order to emulate the terminal behavior properly. const env = { ...process.env }; diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index ea5187dd05..ca6b53c4c2 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -3,7 +3,7 @@
  • Start VS Code from the Developer Command Prompt for VS

  • -
  • Run the C/C++: Set Developer Environment command.

    +
  • Run the C/C++: Set Visual Studio Developer Environment command.

To relaunch VS Code using the Developer Command Prompt for VS

From a79eef90d7f6ec9eee215374143f39584434d3cb Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 7 May 2025 11:26:33 -0700 Subject: [PATCH 20/25] fix environment overriding and some string capitalization --- Extension/package.json | 2 +- Extension/package.nls.json | 6 +++--- Extension/src/LanguageServer/devcmd.ts | 4 ++-- .../devcommandprompt/open-developer-command-prompt.md | 2 +- Extension/yarn.lock | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index eef3df79b0..f7e4678513 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -6660,7 +6660,7 @@ "node-fetch": "^2.7.0", "node-loader": "^2.0.0", "node-stream-zip": "^1.15.0", - "node-vcvarsall": "^1.0.1", + "node-vcvarsall": "^1.1.0", "node-vswhere": "^1.0.2", "plist": "^3.1.0", "posix-getopt": "^1.2.1", diff --git a/Extension/package.nls.json b/Extension/package.nls.json index d3c07cfdc6..9b3dd81e60 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -1006,9 +1006,9 @@ "c_cpp.debuggers.logging.category.warning.description": "Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the application execution to stop.", "c_cpp.debuggers.logging.category.error.description": "Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a failure in the current activity, not an application-wide failure.", "c_cpp.debuggers.logging.category.none.description": "Not used for writing log messages. Specifies that a logging category should not write any messages.", - "c_cpp.walkthrough.title": "Get Started with C++ Development", + "c_cpp.walkthrough.title": "Get started with C++ development", "c_cpp.walkthrough.description": "Dive into VS Code's rich C++ development experience.", - "c_cpp.walkthrough.set.up.title": "Set up your C++ Environment", + "c_cpp.walkthrough.set.up.title": "Set up your C++ environment", "c_cpp.walkthrough.activating.description": "Activating the C++ extension to determine whether your C++ Environment has been set up.\nActivating Extension...", "c_cpp.walkthrough.no.compilers.windows.description": "We could not find a C++ compiler on your machine, which is required to use the C++ extension. Follow the instructions on the right to install one, then click “Find my new Compiler” below.\n[Find my new Compiler](command:C_Cpp.RescanCompilers?%22walkthrough%22)", "c_cpp.walkthrough.no.compilers.description": { @@ -1028,7 +1028,7 @@ }, "c_cpp.walkthrough.create.cpp.file.altText": "Open a C++ file or a folder with a C++ project.", "c_cpp.walkthrough.command.prompt.title": { - "message": "Apply the Visual Studio Developer Environment", + "message": "Apply the Visual Studio developer environment", "comment": [ "{Locked=\"Visual Studio\"}" ] diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index e35dd21b2f..e5fdf4f641 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -20,7 +20,7 @@ const errorNotWindows = localize('not.windows', 'The "Set Visual Studio Develope const errorNoVSFound = localize('error.no.vs', 'A Visual Studio installation with the C++ compiler was not found'); export const errorOperationCancelled = localize('operation.cancelled', 'The operation was cancelled'); const errorNoHostsFound = localize('no.hosts', 'No hosts found'); -const configuringDevEnv = localize('config.dev.env', 'Configuring Developer Environment...'); +const configuringDevEnv = localize('config.dev.env', 'Configuring developer environment...'); const selectVSInstallation = localize('select.vs.install', 'Select a Visual Studio installation'); const advancedOptions = localize('advanced.options', 'Advanced options...'); const advancedOptionsDescription = localize('advanced.options.desc', 'Select a specific host/target architecture, toolset version, etc.'); @@ -74,7 +74,7 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { for (const key of Object.keys(vars)) { context.environmentVariableCollection.replace(key, vars[key].replace(`%${key}%`, '${env:' + key + '}')); } - context.environmentVariableCollection.description = localize('dev.env.for', '{0} Developer Environment for {1}', arch, vsDisplayNameWithSuffix(vs)); + context.environmentVariableCollection.description = localize('dev.env.for', '{0} developer environment for {1}', arch, vsDisplayNameWithSuffix(vs)); context.environmentVariableCollection.persistent = settings.persistDevEnvironment; return true; diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index ca6b53c4c2..8500f11900 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -1,4 +1,4 @@ -

Apply the Visual Studio Developer Environment

+

Apply the Visual Studio developer environment

The Visual Studio C++ compiler requires several environment variables to be set in order to successfully compile your code. If you are using a Windows machine with the Visual Studio C++ compiler, there are two ways you can ensure the environment is applied. You only need to do one of the following:

  • Start VS Code from the Developer Command Prompt for VS

    diff --git a/Extension/yarn.lock b/Extension/yarn.lock index 08f6cee125..2784ba57b5 100644 --- a/Extension/yarn.lock +++ b/Extension/yarn.lock @@ -3558,10 +3558,10 @@ node-stream-zip@^1.15.0: resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" integrity sha1-FYrbiO2ABMbEmjlrUKal3jvKM+o= -node-vcvarsall@^1.0.1: - version "1.0.1" - resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/node-vcvarsall/-/node-vcvarsall-1.0.1.tgz#d7ee885e4ca41f0f0d814e3a277995cc95ff20b0" - integrity sha1-1+6IXkykHw8NgU46J3mVzJX/ILA= +node-vcvarsall@^1.1.0: + version "1.1.0" + resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/node-vcvarsall/-/node-vcvarsall-1.1.0.tgz#4e0b3959f0d5bc6114c8c61e20ac0caab9dcbecf" + integrity sha1-Tgs5WfDVvGEUyMYeIKwMqrncvs8= dependencies: node-vswhere "^1.0.2" tmp "^0.2.1" From 614795bbf798f1e31a1af78366ae26682ceaf2f5 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 7 May 2025 11:30:36 -0700 Subject: [PATCH 21/25] update the settings wrapper --- Extension/src/LanguageServer/devcmd.ts | 2 +- Extension/src/LanguageServer/settings.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index e5fdf4f641..a1b2e7595a 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -75,7 +75,7 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { context.environmentVariableCollection.replace(key, vars[key].replace(`%${key}%`, '${env:' + key + '}')); } context.environmentVariableCollection.description = localize('dev.env.for', '{0} developer environment for {1}', arch, vsDisplayNameWithSuffix(vs)); - context.environmentVariableCollection.persistent = settings.persistDevEnvironment; + context.environmentVariableCollection.persistent = settings.persistVSDeveloperEnvironment; return true; } diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index 393ba512d5..fda8b3ab73 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -549,7 +549,7 @@ export class CppSettings extends Settings { && this.intelliSenseEngine.toLowerCase() === "default" && vscode.workspace.getConfiguration("workbench").get("colorTheme") !== "Default High Contrast"; } public get sshTargetsView(): string { return this.getAsString("sshTargetsView"); } - public get persistDevEnvironment(): boolean { return this.getAsBoolean("persistVsDeveloperEnvironment"); } + public get persistVSDeveloperEnvironment(): boolean { return this.getAsBoolean("persistVsDeveloperEnvironment"); } // Returns the value of a setting as a string with proper type validation and checks for valid enum values while returning an undefined value if necessary. private getAsStringOrUndefined(settingName: string): string | undefined { From 4482734b664addf5b9c84e487452c7c5b02b098a Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 7 May 2025 14:42:12 -0700 Subject: [PATCH 22/25] update locked string --- Extension/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/package.nls.json b/Extension/package.nls.json index 9b3dd81e60..b1a81194c6 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -1036,7 +1036,7 @@ "c_cpp.walkthrough.command.prompt.description": { "message": "When using the Microsoft Visual Studio C++ compiler, the Visual Studio developer environment must be present.\n\nFollow the instructions on the right to relaunch or click the button below.\n[Set Developer Environment](command:C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)", "comment": [ - "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)\"}" + "{Locked=\"Visual Studio\"} {Locked=\"C++\"} {Locked=\"\\\n[\"} {Locked=\"](command:C_Cpp.SetVsDeveloperEnvironment?%22walkthrough%22)\"}" ] }, "c_cpp.walkthrough.run.debug.title": "Run and debug your C++ file", From bebdaeb190283f00234a956349a2e82b236919ce Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 7 May 2025 15:22:03 -0700 Subject: [PATCH 23/25] PR feedback --- Extension/package.json | 2 +- Extension/package.nls.json | 2 +- Extension/src/LanguageServer/client.ts | 14 ++++++++++---- Extension/src/LanguageServer/devcmd.ts | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index f7e4678513..ed96d4fa28 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -3380,7 +3380,7 @@ "C_Cpp.persistVsDeveloperEnvironment": { "type": "boolean", "default": true, - "markdownDescription": "%c_cpp.configuration.persistVsDeveloperEnvironment.markdownDescription%", + "markdownDescription": "%c_cpp.configuration.persistVsDeveloperEnvironment.description%", "scope": "window" } } diff --git a/Extension/package.nls.json b/Extension/package.nls.json index b1a81194c6..a4d555efd9 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -845,7 +845,7 @@ ] }, "c_cpp.configuration.debugShortcut.description": "Show the \"Run and Debug\" play button and \"Add Debug Configuration\" gear in the editor title bar for C++ files.", - "c_cpp.configuration.persistVsDeveloperEnvironment.markdownDescription": "Remember the last used Visual Studio developer environment for the current workspace. This setting is only applicable for Windows.", + "c_cpp.configuration.persistVsDeveloperEnvironment.description": "Remember the last used Visual Studio developer environment for the current workspace. This setting is only applicable for Windows.", "c_cpp.debuggers.pipeTransport.description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).", "c_cpp.debuggers.pipeTransport.default.pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'.", "c_cpp.debuggers.pipeTransport.default.debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb.", diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index fdd0eb737a..73fa1401fb 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -1748,10 +1748,10 @@ export class DefaultClient implements Client { if (Object.keys(changedSettings).length > 0) { if (this === defaultClient) { - if (changedSettings.commentContinuationPatterns) { + if (changedSettings.commentContinuationPatterns !== undefined) { updateLanguageConfigurations(); } - if (changedSettings.loggingLevel) { + if (changedSettings.loggingLevel !== undefined) { const oldLoggingLevelLogged: boolean = this.loggingLevel > 1; this.loggingLevel = util.getNumericLoggingLevel(changedSettings.loggingLevel); if (oldLoggingLevelLogged || this.loggingLevel > 1) { @@ -1759,7 +1759,7 @@ export class DefaultClient implements Client { } } const settings: CppSettings = new CppSettings(); - if (changedSettings.enhancedColorization) { + if (changedSettings.enhancedColorization !== undefined) { if (settings.isEnhancedColorizationEnabled && semanticTokensLegend) { this.semanticTokensProvider = new SemanticTokensProvider(); this.semanticTokensProviderDisposable = vscode.languages.registerDocumentSemanticTokensProvider(util.documentSelector, this.semanticTokensProvider, semanticTokensLegend); @@ -1801,12 +1801,18 @@ export class DefaultClient implements Client { void ui.ShowConfigureIntelliSenseButton(false, this, ConfigurationType.CompilerPath, showButtonSender); } } - if (changedSettings.legacyCompilerArgsBehavior) { + if (changedSettings.legacyCompilerArgsBehavior !== undefined) { this.configuration.handleConfigurationChange(); } if (changedSettings["default.compilerPath"] !== undefined || changedSettings["default.compileCommands"] !== undefined || changedSettings["default.configurationProvider"] !== undefined) { void ui.ShowConfigureIntelliSenseButton(false, this).catch(logAndReturn.undefined); } + if (changedSettings.persistVsDeveloperEnvironment !== undefined) { + if (util.extensionContext) { + const settings: CppSettings = new CppSettings(); + util.extensionContext.environmentVariableCollection.persistent = settings.persistVSDeveloperEnvironment; + } + } this.configuration.onDidChangeSettings(); telemetry.logLanguageServerEvent("CppSettingsChange", changedSettings, undefined); } diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index a1b2e7595a..bd0bfd88d2 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -68,7 +68,7 @@ export async function setEnvironment(context?: vscode.ExtensionContext) { host: match(host, { 'x86': 'x86', 'x64': 'x64' }) ?? 'x64', target: match(target, { 'x86': 'x86', 'x64': 'x64', 'arm64': 'ARM64', 'arm': 'ARM' }) ?? 'x64' }); - const settings = new CppSettings(vscode.workspace.workspaceFolders?.at(0)?.uri); + const settings = new CppSettings(); context.environmentVariableCollection.clear(); for (const key of Object.keys(vars)) { From 14ffb78abffe0c6490e35321757c50471fff425b Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Thu, 8 May 2025 11:56:26 -0700 Subject: [PATCH 24/25] handle outdated vs environment --- .../src/Debugger/configurationProvider.ts | 40 +++++++++++++------ .../LanguageServer/cppBuildTaskProvider.ts | 17 ++------ Extension/src/LanguageServer/devcmd.ts | 28 ++++++++++++- Extension/src/common.ts | 4 +- 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index cdb1d795f8..5590112510 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -15,6 +15,7 @@ import * as util from '../common'; import { isWindows } from '../constants'; import { expandAllStrings, ExpansionOptions, ExpansionVars } from '../expand'; import { CppBuildTask, CppBuildTaskDefinition, cppBuildTaskProvider } from '../LanguageServer/cppBuildTaskProvider'; +import { canFindCl } from '../LanguageServer/devcmd'; import { configPrefix } from '../LanguageServer/extension'; import { CppSettings, OtherSettings } from '../LanguageServer/settings'; import * as logger from '../logger'; @@ -590,20 +591,34 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv * `false` if the VS developer environment is available or the user chose to apply it. */ private async showErrorIfClNotAvailable(_configurationLabel: string): Promise { - if (util.hasMsvcEnvironment()) { - return false; // No error to show + const hasEnvironment = util.hasMsvcEnvironment(); + if (hasEnvironment) { + if (await canFindCl()) { + return false; // No error to show + } + // The user has an environment but cl.exe cannot be found. Prompt the user to update the environment. } - const applyDevEnv = localize("apply.dev.env", "Apply Developer Environment"); - const cancel = localize("cancel", "Cancel"); - const response = await vscode.window.showErrorMessage( - localize({ + const applyButton = localize("apply.dev.env", "Apply Developer Environment"); + const applyMessage = localize( + { key: "cl.exe.not.available", comment: ["{0} is a command option in a menu."] - }, "{0} requires the Visual Studio developer environment.", `cl.exe ${this.buildAndDebugActiveFileStr()}`), - applyDevEnv, + }, + "{0} requires the Visual Studio developer environment.", `cl.exe ${this.buildAndDebugActiveFileStr()}`); + const updateButton = localize("update.dev.env", "Update Developer Environment"); + const updateMessage = localize( + { + key: "update.dev.env", + comment: ["{0} is a command option in a menu."] + }, + "{0} requires the Visual Studio developer environment to be updated.", `cl.exe ${this.buildAndDebugActiveFileStr()}`); + const cancel = localize("cancel", "Cancel"); + const response = await vscode.window.showErrorMessage( + hasEnvironment ? updateMessage : applyMessage, + hasEnvironment ? updateButton : applyButton, cancel); - if (response === applyDevEnv) { + if (response === applyButton || response === updateButton) { try { await vscode.commands.executeCommand('C_Cpp.SetVsDeveloperEnvironment', 'buildAndDebug'); } catch (e: any) { @@ -615,11 +630,12 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv return true; } - if (util.hasMsvcEnvironment()) { + if (util.hasMsvcEnvironment() && await canFindCl()) { return false; } - void vscode.window.showErrorMessage( - localize('dev.env.not.applied', 'The source code could not be built because the Visual Studio developer environment was not applied.')); + const notAppliedMessage = localize("dev.env.not.applied", "The source code could not be built because the Visual Studio developer environment was not applied."); + const notFoundMessage = localize("dev.env.not.found", "The source code could not be built because the Visual C++ compiler could not be found."); + void vscode.window.showErrorMessage(hasEnvironment ? notFoundMessage : notAppliedMessage); return true; } diff --git a/Extension/src/LanguageServer/cppBuildTaskProvider.ts b/Extension/src/LanguageServer/cppBuildTaskProvider.ts index 0b7113fb2b..dc9c64e895 100644 --- a/Extension/src/LanguageServer/cppBuildTaskProvider.ts +++ b/Extension/src/LanguageServer/cppBuildTaskProvider.ts @@ -6,13 +6,13 @@ import * as cp from "child_process"; import * as os from 'os'; import * as path from 'path'; -import { CustomExecution, Disposable, EnvironmentVariableMutator, Event, EventEmitter, ProcessExecution, Pseudoterminal, ShellExecution, Task, TaskDefinition, TaskEndEvent, TaskExecution, TaskGroup, TaskProvider, tasks, TaskScope, TerminalDimensions, TextEditor, window, workspace, WorkspaceFolder } from 'vscode'; +import { CustomExecution, Disposable, Event, EventEmitter, ProcessExecution, Pseudoterminal, ShellExecution, Task, TaskDefinition, TaskEndEvent, TaskExecution, TaskGroup, TaskProvider, tasks, TaskScope, TerminalDimensions, TextEditor, window, workspace, WorkspaceFolder } from 'vscode'; import * as nls from 'vscode-nls'; import * as util from '../common'; import * as telemetry from '../telemetry'; import { Client } from './client'; import * as configs from './configurations'; -import { isEnvironmentOverrideApplied } from "./devcmd"; +import { getEffectiveEnvironment, isEnvironmentOverrideApplied } from "./devcmd"; import * as ext from './extension'; import { OtherSettings } from './settings'; @@ -431,20 +431,11 @@ class CustomBuildTaskTerminal implements Pseudoterminal { } } - if (isEnvironmentOverrideApplied(util.extensionContext)) { + if (isEnvironmentOverrideApplied()) { // If the user has applied the developer environment to this workspace, it should apply to all newly opened terminals. // However, this does not apply to processes that we spawn ourselves in the Pseudoterminal, so we need to specify the // correct environment in order to emulate the terminal behavior properly. - const env = { ...process.env }; - util.extensionContext?.environmentVariableCollection.forEach((variable: string, mutator: EnvironmentVariableMutator) => { - if (variable.toLowerCase() === "path") { - // Path is special because it has a placeholder to insert the current Path into. - env[variable] = util.resolveVariables(mutator.value); - } else { - env[variable] = mutator.value; - } - }); - this.options.env = env; + this.options.env = getEffectiveEnvironment(); } const splitWriteEmitter = (lines: string | Buffer) => { diff --git a/Extension/src/LanguageServer/devcmd.ts b/Extension/src/LanguageServer/devcmd.ts index bd0bfd88d2..823217f90d 100644 --- a/Extension/src/LanguageServer/devcmd.ts +++ b/Extension/src/LanguageServer/devcmd.ts @@ -9,6 +9,7 @@ import { vswhere } from 'node-vswhere'; import * as path from 'path'; import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; +import { extensionContext, isString, resolveVariables, whichAsync } from '../common'; import { isWindows } from '../constants'; import { CppSettings } from './settings'; @@ -27,8 +28,31 @@ const advancedOptionsDescription = localize('advanced.options.desc', 'Select a s const selectToolsetVersion = localize('select.toolset', 'Select a toolset version'); const selectHostTargetArch = localize('select.host.target', 'Select a host and target architecture'); -export function isEnvironmentOverrideApplied(context?: vscode.ExtensionContext) { - return context?.environmentVariableCollection.get('VCToolsInstallDir') !== undefined; +export function isEnvironmentOverrideApplied(): boolean { + return extensionContext?.environmentVariableCollection.get('VCToolsInstallDir') !== undefined; +} + +export function getEffectiveEnvironment(): { [key: string]: string | undefined } { + const env = { ...process.env }; + extensionContext?.environmentVariableCollection.forEach((variable: string, mutator: vscode.EnvironmentVariableMutator) => { + if (variable.toLowerCase() === "path") { + // Path is special because it has a placeholder to insert the current Path into. + env[variable] = resolveVariables(mutator.value); + } else { + env[variable] = mutator.value; + } + }); + return env; +} + +export async function canFindCl(): Promise { + if (!isWindows) { + return false; + } + const pathOverride = resolveVariables(extensionContext?.environmentVariableCollection.get('Path')?.value); + const path = pathOverride ?? process.env['Path']; + const found = await whichAsync('cl.exe', path); + return isString(found); } export async function setEnvironment(context?: vscode.ExtensionContext) { diff --git a/Extension/src/common.ts b/Extension/src/common.ts index 75e339a85f..03ad8e36e7 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -1515,9 +1515,9 @@ export interface ISshLocalForwardInfo { remoteSocket?: string; } -export function whichAsync(name: string): Promise { +export function whichAsync(name: string, path?: string): Promise { return new Promise(resolve => { - which(name, (err, resolved) => { + which(name, path ? { path } : {}, (err, resolved) => { if (err) { resolve(undefined); } else { From 63be00c4fda971ec6111af291d0c221a1f3cde0a Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Mon, 12 May 2025 14:13:33 -0700 Subject: [PATCH 25/25] PR feedback --- Extension/src/LanguageServer/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 66bd76178b..720820e249 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -1576,7 +1576,7 @@ async function onSetVsDeveloperEnvironment(sender?: any): Promise { throw error; } if (error.message !== errorOperationCancelled) { - void vscode.window.showErrorMessage(`Failed to apply VS developer environment: ${error.message}`); + void vscode.window.showErrorMessage(`Failed to apply the VS developer environment: ${error.message}`); } } telemetry.logLanguageServerEvent("SetVsDeveloperEnvironment", { "sender": util.getSenderType(sender), "resultcode": success.toString() });