Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/notebooks/endgame.github-issues
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$MILESTONE=milestone:\"1.111.0\""
"value": "$MILESTONE=milestone:\"1.112.0\""
},
{
"kind": 1,
Expand Down
2 changes: 1 addition & 1 deletion .vscode/notebooks/my-endgame.github-issues
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$MILESTONE=milestone:\"1.111.0\"\n\n$MINE=assignee:@me"
"value": "$MILESTONE=milestone:\"1.112.0\"\n\n$MINE=assignee:@me"
},
{
"kind": 2,
Expand Down
6 changes: 3 additions & 3 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,11 @@
}
},
{
"label": "Install & Compile",
"label": "Install & Watch",
"type": "shell",
"command": "npm install && npm run compile",
"command": "npm install && npm run watch",
"windows": {
"command": "cmd /d /c \"npm install && npm run compile\""
"command": "cmd /d /c \"npm install && npm run watch\""
},
"inSessions": true,
"runOptions": {
Expand Down
9 changes: 1 addition & 8 deletions build/azure-pipelines/common/releaseBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,8 @@ async function main(force: boolean): Promise<void> {

console.log(`Releasing build ${commit}...`);

let rolloutDurationMs = undefined;

// If the build is insiders or exploration, start a rollout of 4 hours
if (quality === 'insider') {
rolloutDurationMs = 4 * 60 * 60 * 1000; // 4 hours
}

const scripts = client.database('builds').container(quality).scripts;
await retry(() => scripts.storedProcedure('releaseBuild').execute('', [commit, rolloutDurationMs]));
await retry(() => scripts.storedProcedure('releaseBuild').execute('', [commit]));
}

const [, , force] = process.argv;
Expand Down
122 changes: 96 additions & 26 deletions build/win32/code.iss
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Type: files; Name: "{app}\updating_version"
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
Name: "addcontextmenufiles"; Description: "{cm:AddContextMenuFiles,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "addcontextmenufolders"; Description: "{cm:AddContextMenuFolders,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked; Check: not ShouldUseWindows11ContextMenu
Name: "addcontextmenufolders"; Description: "{cm:AddContextMenuFolders,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameShort}}"; GroupDescription: "{cm:Other}"
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"
Name: "runcode"; Description: "{cm:RunAfter,{#NameShort}}"; GroupDescription: "{cm:Other}"; Check: WizardSilent
Expand Down Expand Up @@ -1284,15 +1284,15 @@ Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}Contex
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufiles; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: addcontextmenufiles; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders; Check: not ShouldUseWindows11ContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Flags: uninsdeletekey; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Flags: uninsdeletekey; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Flags: uninsdeletekey; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Check: ShouldInstallLegacyFolderContextMenu
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Check: ShouldInstallLegacyFolderContextMenu

; Environment
#if "user" == InstallTarget
Expand Down Expand Up @@ -1527,6 +1527,68 @@ begin
Result := IsWindows11OrLater() and not IsWindows10ContextMenuForced();
end;

function HasLegacyFileContextMenu(): Boolean;
begin
Result := RegKeyExists({#EnvironmentRootKey}, 'Software\Classes\*\shell\{#RegValueName}\command');
end;

function HasLegacyFolderContextMenu(): Boolean;
begin
Result := RegKeyExists({#EnvironmentRootKey}, 'Software\Classes\directory\shell\{#RegValueName}\command');
end;

function ShouldRepairFolderContextMenu(): Boolean;
begin
// Repair folder context menu during updates if:
// 1. This is a background update (not a fresh install or manual re-install)
// 2. Windows 11+ with forced classic context menu
// 3. Legacy file context menu exists (user previously selected it)
// 4. Legacy folder context menu is MISSING
Result := IsBackgroundUpdate()
and IsWindows11OrLater()
and IsWindows10ContextMenuForced()
and HasLegacyFileContextMenu()
and not HasLegacyFolderContextMenu();
end;

function ShouldInstallLegacyFolderContextMenu(): Boolean;
begin
Result := (WizardIsTaskSelected('addcontextmenufolders') and not ShouldUseWindows11ContextMenu()) or ShouldRepairFolderContextMenu();
end;

function BoolToStr(Value: Boolean): String;
begin
if Value then
Result := 'true'
else
Result := 'false';
end;

procedure LogContextMenuInstallState();
begin
Log(
'Context menu state: '
+ 'isBackgroundUpdate=' + BoolToStr(IsBackgroundUpdate())
+ ', isWindows11OrLater=' + BoolToStr(IsWindows11OrLater())
+ ', isWindows10ContextMenuForced=' + BoolToStr(IsWindows10ContextMenuForced())
+ ', shouldUseWindows11ContextMenu=' + BoolToStr(ShouldUseWindows11ContextMenu())
+ ', hasLegacyFileContextMenu=' + BoolToStr(HasLegacyFileContextMenu())
+ ', hasLegacyFolderContextMenu=' + BoolToStr(HasLegacyFolderContextMenu())
+ ', shouldRepairFolderContextMenu=' + BoolToStr(ShouldRepairFolderContextMenu())
+ ', shouldInstallLegacyFolderContextMenu=' + BoolToStr(ShouldInstallLegacyFolderContextMenu())
+ ', addcontextmenufiles=' + BoolToStr(WizardIsTaskSelected('addcontextmenufiles'))
+ ', addcontextmenufolders=' + BoolToStr(WizardIsTaskSelected('addcontextmenufolders'))
);
end;

procedure DeleteLegacyContextMenuRegistryKeys();
begin
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\*\shell\{#RegValueName}');
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\directory\shell\{#RegValueName}');
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\directory\background\shell\{#RegValueName}');
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\Drive\shell\{#RegValueName}');
end;

function GetAppMutex(Value: string): string;
begin
if IsBackgroundUpdate() then
Expand Down Expand Up @@ -1604,14 +1666,6 @@ begin
Result := ExpandConstant('{#ApplicationName}.cmd');
end;

function BoolToStr(Value: Boolean): String;
begin
if Value then
Result := 'true'
else
Result := 'false';
end;

function QualityIsInsiders(): boolean;
begin
if '{#Quality}' = 'insider' then
Expand All @@ -1634,30 +1688,43 @@ end;
function AppxPackageInstalled(const name: String; var ResultCode: Integer): Boolean;
begin
AppxPackageFullname := '';
ResultCode := -1;
try
Log('Get-AppxPackage for package with name: ' + name);
ExecAndLogOutput('powershell.exe', '-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command ' + AddQuotes('Get-AppxPackage -Name ''' + name + ''' | Select-Object -ExpandProperty PackageFullName'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode, @ExecAndGetFirstLineLog);
except
Log(GetExceptionMessage);
ResultCode := -1;
end;
if (AppxPackageFullname <> '') then
Result := True
else
Result := False
Result := False;

Log('Get-AppxPackage result: name=' + name + ', installed=' + BoolToStr(Result) + ', resultCode=' + IntToStr(ResultCode) + ', packageFullName=' + AppxPackageFullname);
end;

procedure AddAppxPackage();
var
AddAppxPackageResultCode: Integer;
IsCurrentAppxInstalled: Boolean;
begin
if not SessionEndFileExists() and not AppxPackageInstalled(ExpandConstant('{#AppxPackageName}'), AddAppxPackageResultCode) then begin
if SessionEndFileExists() then begin
Log('Skipping Add-AppxPackage because session end was detected.');
exit;
end;

IsCurrentAppxInstalled := AppxPackageInstalled(ExpandConstant('{#AppxPackageName}'), AddAppxPackageResultCode);
if not IsCurrentAppxInstalled then begin
Log('Installing appx ' + AppxPackageFullname + ' ...');
#if "user" == InstallTarget
ShellExec('', 'powershell.exe', '-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command ' + AddQuotes('Add-AppxPackage -Path ''' + ExpandConstant('{app}\{#VersionedResourcesFolder}\appx\{#AppxPackage}') + ''' -ExternalLocation ''' + ExpandConstant('{app}\{#VersionedResourcesFolder}\appx') + ''''), '', SW_HIDE, ewWaitUntilTerminated, AddAppxPackageResultCode);
#else
ShellExec('', 'powershell.exe', '-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command ' + AddQuotes('Add-AppxPackage -Stage ''' + ExpandConstant('{app}\{#VersionedResourcesFolder}\appx\{#AppxPackage}') + ''' -ExternalLocation ''' + ExpandConstant('{app}\{#VersionedResourcesFolder}\appx') + '''; Add-AppxProvisionedPackage -Online -SkipLicense -PackagePath ''' + ExpandConstant('{app}\{#VersionedResourcesFolder}\appx\{#AppxPackage}') + ''''), '', SW_HIDE, ewWaitUntilTerminated, AddAppxPackageResultCode);
#endif
Log('Add-AppxPackage complete.');
Log('Add-AppxPackage complete with result code ' + IntToStr(AddAppxPackageResultCode) + '.');
end else begin
Log('Skipping Add-AppxPackage because package is already installed.');
end;
end;

Expand All @@ -1670,6 +1737,7 @@ begin
if QualityIsInsiders() and not SessionEndFileExists() and AppxPackageInstalled('Microsoft.VSCodeInsiders', RemoveAppxPackageResultCode) then begin
Log('Deleting old appx ' + AppxPackageFullname + ' installation...');
ShellExec('', 'powershell.exe', '-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command ' + AddQuotes('Remove-AppxPackage -Package ''' + AppxPackageFullname + ''''), '', SW_HIDE, ewWaitUntilTerminated, RemoveAppxPackageResultCode);
Log('Remove-AppxPackage for old appx completed with result code ' + IntToStr(RemoveAppxPackageResultCode) + '.');
DeleteFile(ExpandConstant('{app}\appx\code_insiders_explorer_{#Arch}.appx'));
DeleteFile(ExpandConstant('{app}\appx\code_insiders_explorer_command.dll'));
end;
Expand All @@ -1680,7 +1748,9 @@ begin
#else
ShellExec('', 'powershell.exe', '-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command ' + AddQuotes('$packages = Get-AppxPackage ''' + ExpandConstant('{#AppxPackageName}') + '''; foreach ($package in $packages) { Remove-AppxProvisionedPackage -PackageName $package.PackageFullName -Online }; foreach ($package in $packages) { Remove-AppxPackage -Package $package.PackageFullName -AllUsers }'), '', SW_HIDE, ewWaitUntilTerminated, RemoveAppxPackageResultCode);
#endif
Log('Remove-AppxPackage for current appx installation complete.');
Log('Remove-AppxPackage for current appx installation complete with result code ' + IntToStr(RemoveAppxPackageResultCode) + '.');
end else if not SessionEndFileExists() then begin
Log('Skipping Remove-AppxPackage for current appx because package is not installed.');
end;
end;
#endif
Expand All @@ -1692,6 +1762,8 @@ var
begin
if CurStep = ssPostInstall then
begin
LogContextMenuInstallState();

#ifdef AppxPackageName
// Remove the appx package when user has forced Windows 10 context menus via
// registry. This handles the case where the user previously had the appx
Expand All @@ -1701,10 +1773,7 @@ begin
end;
// Remove the old context menu registry keys
if ShouldUseWindows11ContextMenu() then begin
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\*\shell\{#RegValueName}');
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\directory\shell\{#RegValueName}');
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\directory\background\shell\{#RegValueName}');
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\Drive\shell\{#RegValueName}');
DeleteLegacyContextMenuRegistryKeys();
end;
#endif

Expand Down Expand Up @@ -1817,6 +1886,7 @@ begin
if not CurUninstallStep = usUninstall then begin
exit;
end;

#ifdef AppxPackageName
RemoveAppxPackage();
#endif
Expand Down
1 change: 1 addition & 0 deletions extensions/vscode-api-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"enabledApiProposals": [
"activeComment",
"authSession",
"browser",
"environmentPower",
"chatParticipantPrivate",
"chatPromptFiles",
Expand Down
Loading
Loading