@@ -74,8 +74,8 @@ export class DefaultExtensionsInstaller extends Disposable {
7474 storageFile : URI ,
7575 installedPaths : string [ ]
7676 ) : Promise < void > {
77- // Install all extensions in a single batch operation
78- // This ensures all extensions are installed together before any activation happens, preventing dependency notifications
77+ // Install all extensions in parallel (like the old workbench.extensions.command.installFromVSIX command)
78+ // Use the same options as the old command to match its behavior exactly
7979 const vsixUris = pathsToInstall
8080 . filter ( p => p . trim ( ) )
8181 . map ( p => URI . file ( p . trim ( ) ) ) ;
@@ -84,53 +84,36 @@ export class DefaultExtensionsInstaller extends Disposable {
8484 return ;
8585 }
8686
87- this . logService . info ( `DefaultExtensionsInstaller: Installing ${ vsixUris . length } extension(s) in batch` ) ;
88-
89- try {
90- const installed = await this . extensionManagementService . installVSIXBatch ( vsixUris , {
91- isDefault : true // Mark as default extension to bypass policy checks
92- } ) ;
93-
94- // Map installed extensions back to their paths
95- const successfullyInstalled : string [ ] = [ ] ;
96- for ( const vsixUri of vsixUris ) {
97- // Check if this extension was successfully installed by checking if any installed extension
98- // matches the path (we'll track by path since we don't have the extension ID easily)
99- // For simplicity, assume all extensions in the batch that didn't throw were installed
100- successfullyInstalled . push ( vsixUri . fsPath ) ;
101- }
102-
103- this . logService . info ( `DefaultExtensionsInstaller: Successfully installed ${ installed . length } extension(s) in batch` ) ;
104-
105- // Update storage with successfully installed extensions
106- if ( successfullyInstalled . length > 0 ) {
107- const updatedInstalled = [ ...installedPaths , ...successfullyInstalled ] ;
108- await this . fileService . writeFile ( storageFile , VSBuffer . fromString ( JSON . stringify ( updatedInstalled , null , 2 ) ) ) ;
109- this . logService . info ( `DefaultExtensionsInstaller: Updated storage with ${ successfullyInstalled . length } successfully installed extension(s)` ) ;
110- }
111- } catch ( error ) {
112- this . logService . error ( `DefaultExtensionsInstaller: Failed to install extensions in batch` , error ) ;
113- // Try to install individually as fallback
114- this . logService . info ( `DefaultExtensionsInstaller: Falling back to individual installation` ) ;
115- const successfullyInstalled : string [ ] = [ ] ;
116-
117- for ( const vsixUri of vsixUris ) {
118- try {
119- await this . extensionManagementService . install ( vsixUri , {
120- isDefault : true
121- } ) ;
122- successfullyInstalled . push ( vsixUri . fsPath ) ;
123- this . logService . info ( `DefaultExtensionsInstaller: Successfully installed extension from ${ vsixUri . fsPath } ` ) ;
124- } catch ( err ) {
125- this . logService . error ( `DefaultExtensionsInstaller: Failed to install extension from ${ vsixUri . fsPath } ` , err ) ;
126- }
87+ this . logService . info ( `DefaultExtensionsInstaller: Installing ${ vsixUris . length } extension(s) in parallel` ) ;
88+
89+ // Install in parallel using Promise.allSettled (same as old command)
90+ const results = await Promise . allSettled (
91+ vsixUris . map ( async ( vsixUri ) => {
92+ this . logService . info ( `DefaultExtensionsInstaller: Installing extension from ${ vsixUri . fsPath } ` ) ;
93+ await this . extensionManagementService . install ( vsixUri , {
94+ isDefault : true , // Mark as default extension to bypass policy checks
95+ installGivenVersion : true , // Same as old command
96+ donotIncludePackAndDependencies : true // Skip dependency checking during installation (like defaultExtensionsInitializer)
97+ } ) ;
98+ this . logService . info ( `DefaultExtensionsInstaller: Successfully installed extension from ${ vsixUri . fsPath } ` ) ;
99+ return vsixUri . fsPath ;
100+ } )
101+ ) ;
102+
103+ const successfullyInstalled : string [ ] = [ ] ;
104+ for ( const result of results ) {
105+ if ( result . status === 'fulfilled' ) {
106+ successfullyInstalled . push ( result . value ) ;
107+ } else {
108+ this . logService . error ( `DefaultExtensionsInstaller: Failed to install extension` , result . reason ) ;
127109 }
110+ }
128111
129- if ( successfullyInstalled . length > 0 ) {
130- const updatedInstalled = [ ... installedPaths , ... successfullyInstalled ] ;
131- await this . fileService . writeFile ( storageFile , VSBuffer . fromString ( JSON . stringify ( updatedInstalled , null , 2 ) ) ) ;
132- this . logService . info ( `DefaultExtensionsInstaller: Updated storage with ${ successfullyInstalled . length } successfully installed extension(s)` ) ;
133- }
112+ // Update storage with successfully installed extensions
113+ if ( successfullyInstalled . length > 0 ) {
114+ const updatedInstalled = [ ... installedPaths , ... successfullyInstalled ] ;
115+ await this . fileService . writeFile ( storageFile , VSBuffer . fromString ( JSON . stringify ( updatedInstalled , null , 2 ) ) ) ;
116+ this . logService . info ( `DefaultExtensionsInstaller: Updated storage with ${ successfullyInstalled . length } successfully installed extension(s)` ) ;
134117 }
135118 }
136119
0 commit comments