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..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,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // 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.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..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,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // 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.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..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,8 +4,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": " 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.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..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,8 +4,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": " 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.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..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,8 +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.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.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..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,8 +4,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": " 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.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..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,8 +4,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": " 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.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..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,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // 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.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..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,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // 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.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..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,8 +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.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.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..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,8 +4,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": " 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.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..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,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // 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.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..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,8 +4,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": " 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.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/package.json b/Extension/package.json index 91b36e5d08..99ac5372ad 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.persistVsDeveloperEnvironment": { + "type": "boolean", + "default": true, + "markdownDescription": "%c_cpp.configuration.persistVsDeveloperEnvironment.description%", + "scope": "window" } } } @@ -3541,6 +3547,16 @@ "category": "C/C++", "icon": "$(run)" }, + { + "command": "C_Cpp.SetVsDeveloperEnvironment", + "title": "%c_cpp.command.SetVsDeveloperEnvironment.title%", + "category": "C/C++" + }, + { + "command": "C_Cpp.ClearVsDeveloperEnvironment", + "title": "%c_cpp.command.ClearVsDeveloperEnvironment.title%", + "category": "C/C++" + }, { "command": "C_Cpp.AddDebugConfiguration", "title": "%c_cpp.command.AddDebugConfiguration.title%", @@ -6012,6 +6028,14 @@ "command": "C_Cpp.BuildAndRunFile", "when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && config.C_Cpp.debugShortcut && cpptools.buildAndDebug.isSourceFile" }, + { + "command": "C_Cpp.SetVsDeveloperEnvironment", + "when": "workspacePlatform == windows" + }, + { + "command": "C_Cpp.ClearVsDeveloperEnvironment", + "when": "workspacePlatform == windows" + }, { "command": "C_Cpp.AddDebugConfiguration", "when": "config.C_Cpp.debugShortcut && cpptools.buildAndDebug.isFolderOpen" @@ -6636,6 +6660,8 @@ "node-fetch": "^2.7.0", "node-loader": "^2.0.0", "node-stream-zip": "^1.15.0", + "node-vcvarsall": "^1.1.0", + "node-vswhere": "^1.0.2", "plist": "^3.1.0", "posix-getopt": "^1.2.1", "shell-quote": "^1.8.1", @@ -6651,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 262dd3f26b..a4d555efd9 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.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", @@ -843,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.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.", @@ -1003,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": { @@ -1025,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.SetVsDeveloperEnvironment?%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=\"](command: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 f4f8745016..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'; @@ -87,6 +88,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 +124,8 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv return []; // User canceled it. } - if (this.isClConfiguration(selection.label)) { - this.showErrorIfClNotAvailable(selection.label); + if (this.isClConfiguration(selection.label) && await this.showErrorIfClNotAvailable(selection.label)) { + return []; // Cannot continue with build/debug. } return [selection.configuration]; @@ -578,19 +582,61 @@ 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"); } - private showErrorIfClNotAvailable(_configurationLabel: string): boolean { - if (!process.env.DevEnvDir || process.env.DevEnvDir.length === 0) { - void vscode.window.showErrorMessage(localize({ + /** + * @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 { + 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 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. {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")); + comment: ["{0} is a command option in a menu."] + }, + "{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 === applyButton || response === updateButton) { + try { + await vscode.commands.executeCommand('C_Cpp.SetVsDeveloperEnvironment', 'buildAndDebug'); + } catch (e: any) { + // Ignore the error, the user will be prompted to apply the environment manually. + } + } + 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; } - return false; + + if (util.hasMsvcEnvironment() && await canFindCl()) { + return false; + } + 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; } private getLLDBFrameworkPath(): string | undefined { @@ -967,7 +1013,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/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/cppBuildTaskProvider.ts b/Extension/src/LanguageServer/cppBuildTaskProvider.ts index de08d6e436..dc9c64e895 100644 --- a/Extension/src/LanguageServer/cppBuildTaskProvider.ts +++ b/Extension/src/LanguageServer/cppBuildTaskProvider.ts @@ -12,6 +12,7 @@ import * as util from '../common'; import * as telemetry from '../telemetry'; import { Client } from './client'; import * as configs from './configurations'; +import { getEffectiveEnvironment, isEnvironmentOverrideApplied } from "./devcmd"; import * as ext from './extension'; import { OtherSettings } from './settings'; @@ -245,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; @@ -430,6 +431,13 @@ class CustomBuildTaskTerminal implements Pseudoterminal { } } + 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. + this.options.env = getEffectiveEnvironment(); + } + 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 new file mode 100644 index 0000000000..823217f90d --- /dev/null +++ b/Extension/src/LanguageServer/devcmd.ts @@ -0,0 +1,238 @@ +/* -------------------------------------------------------------------------------------------- + * 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'; +import * as nls from 'vscode-nls'; +import { extensionContext, isString, resolveVariables, whichAsync } from '../common'; +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 errorNoContext = localize('no.context.provided', 'No context provided'); +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'); +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'); +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(): 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) { + if (!isWindows) { + throw new Error(errorNotWindows); + } + + if (!context) { + throw new Error(errorNoContext); + } + + const vses = await getVSInstallations(); + if (!vses) { + throw new Error(errorNoVSFound); + } + + 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: configuringDevEnv + }, () => vcvars.getVCVars(vs, options)); + + if (!vars || !vars['INCLUDE']) { + throw new Error(localize('something.wrong', 'Something went wrong: {0}', 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 settings = new CppSettings(); + + context.environmentVariableCollection.clear(); + 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.persistent = settings.persistVSDeveloperEnvironment; + + 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(errorNoVSFound); + } + 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: vsDisplayNameWithSuffix(installation), + detail: localize('default.env', 'Default environment for {0}', installation.catalog.productDisplayVersion) + }); + items.push({ + label: advancedOptions, + description: advancedOptionsDescription + }); + const selection = await vscode.window.showQuickPick(items, { + placeHolder: selectVSInstallation + }); + if (!selection) { + throw new Error(errorOperationCancelled); + } + + return installations.find(installation => vsDisplayNameWithSuffix(installation) === 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(errorOperationCancelled); + } + await setOptions(compiler); + return compiler; +} + +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: vsDisplayNameWithSuffix(compiler.vs) + }); + const selection = await vscode.window.showQuickPick(items, { + placeHolder: selectToolsetVersion + }); + if (!selection) { + throw new Error(errorOperationCancelled); + } + return compilers.find(compiler => compiler.version === selection.label && vsDisplayNameWithSuffix(compiler.vs) === 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: localize('host.target', 'host = {0}, target = {1}', ht.host, ht.target) + }); + const selection = await vscode.window.showQuickPick(items, { + placeHolder: selectHostTargetArch + }); + if (!selection) { + throw new Error(errorOperationCancelled); + } + compiler.options.arch = selection.label; + } +} + +async function getHostsAndTargets(vcPath: string): Promise { + const hosts = await fs.readdir(vcPath); + if (hosts.length === 0) { + throw new Error(errorNoHostsFound); + } + 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; +} + +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..720820e249 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'; @@ -29,6 +29,7 @@ import { CodeActionDiagnosticInfo, CodeAnalysisDiagnosticIdentifiersAndUri, code import { registerRelatedFilesProvider } from './copilotProviders'; import { CppBuildTaskProvider } from './cppBuildTaskProvider'; import { getCustomConfigProviders } from './customProviders'; +import { errorOperationCancelled, 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.SetVsDeveloperEnvironment', enabled ? onSetVsDeveloperEnvironment : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ClearVsDeveloperEnvironment', enabled ? onClearVsDeveloperEnvironment : onDisabledCommand)); } function onDisabledCommand() { @@ -1558,3 +1561,28 @@ async function showCopilotContent(copilotHoverProvider: CopilotHoverProvider, ho return true; } + +async function onSetVsDeveloperEnvironment(sender?: any): Promise { + let success: boolean = true; + try { + await setEnvironment(util.extensionContext); + await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment()); + if (sender !== 'buildAndDebug') { + void vscode.window.showInformationMessage(`${util.extensionContext?.environmentVariableCollection.description} successfully set.`); + } + } catch (error: any) { + success = false; + if (!isWindows) { + throw error; + } + if (error.message !== errorOperationCancelled) { + void vscode.window.showErrorMessage(`Failed to apply the VS developer environment: ${error.message}`); + } + } + telemetry.logLanguageServerEvent("SetVsDeveloperEnvironment", { "sender": util.getSenderType(sender), "resultcode": success.toString() }); +} + +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 449143439f..fda8b3ab73 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 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 { diff --git a/Extension/src/common.ts b/Extension/src/common.ts index a48326eaea..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 { @@ -1556,7 +1556,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/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts new file mode 100644 index 0000000000..349a8803bb --- /dev/null +++ b/Extension/test/scenarios/SimpleCppProject/tests/devEnvironment.test.ts @@ -0,0 +1,40 @@ +/* -------------------------------------------------------------------------------------------- + * 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"; +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.SetVsDeveloperEnvironment', '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."); + }); + + test("clear developer environment (Windows)", async () => { + await vscode.commands.executeCommand('C_Cpp.ClearVsDeveloperEnvironment'); + equal(util.hasMsvcEnvironment(), false, "MSVC environment not cleared correctly."); + }); + } else { + test("should not be able to set developer environment (Linux/macOS)", async () => { + try { + 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) { + 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."); + }); + } +}); diff --git a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md index e8af0926f2..8500f11900 100644 --- a/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md +++ b/Extension/walkthrough/devcommandprompt/open-developer-command-prompt.md @@ -1,7 +1,17 @@ -

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:

+

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

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

    +
  • +
+

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. Open the Developer Command Prompt for VS by typing developer in the Windows Start menu then select the Developer Command Prompt for VS.

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

    +
  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.

  8. +
\ No newline at end of file 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.

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

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

  • 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

    diff --git a/Extension/yarn.lock b/Extension/yarn.lock index 2de55e9290..40fb269fc1 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.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" + +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=