Path: blob/main/src/vs/workbench/services/extensionManagement/electron-browser/nativeExtensionManagementService.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { IChannel } from '../../../../base/parts/ipc/common/ipc.js';6import { DidChangeProfileEvent, IProfileAwareExtensionManagementService } from '../common/extensionManagement.js';7import { URI } from '../../../../base/common/uri.js';8import { IAllowedExtensionsService, ILocalExtension, InstallOptions } from '../../../../platform/extensionManagement/common/extensionManagement.js';9import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';10import { IUserDataProfileService } from '../../userDataProfile/common/userDataProfile.js';11import { joinPath } from '../../../../base/common/resources.js';12import { Schemas } from '../../../../base/common/network.js';13import { ILogService } from '../../../../platform/log/common/log.js';14import { IDownloadService } from '../../../../platform/download/common/download.js';15import { IFileService } from '../../../../platform/files/common/files.js';16import { generateUuid } from '../../../../base/common/uuid.js';17import { ProfileAwareExtensionManagementChannelClient } from '../common/extensionManagementChannelClient.js';18import { ExtensionIdentifier, ExtensionType, isResolverExtension } from '../../../../platform/extensions/common/extensions.js';19import { INativeWorkbenchEnvironmentService } from '../../environment/electron-browser/environmentService.js';20import { IProductService } from '../../../../platform/product/common/productService.js';2122export class NativeExtensionManagementService extends ProfileAwareExtensionManagementChannelClient implements IProfileAwareExtensionManagementService {2324constructor(25channel: IChannel,26@IProductService productService: IProductService,27@IAllowedExtensionsService allowedExtensionsService: IAllowedExtensionsService,28@IUserDataProfileService userDataProfileService: IUserDataProfileService,29@IUriIdentityService uriIdentityService: IUriIdentityService,30@IFileService private readonly fileService: IFileService,31@IDownloadService private readonly downloadService: IDownloadService,32@INativeWorkbenchEnvironmentService private readonly nativeEnvironmentService: INativeWorkbenchEnvironmentService,33@ILogService private readonly logService: ILogService,34) {35super(channel, productService, allowedExtensionsService, userDataProfileService, uriIdentityService);36}3738protected filterEvent(profileLocation: URI, isApplicationScoped: boolean): boolean {39return isApplicationScoped || this.uriIdentityService.extUri.isEqual(this.userDataProfileService.currentProfile.extensionsResource, profileLocation);40}4142override async install(vsix: URI, options?: InstallOptions): Promise<ILocalExtension> {43const { location, cleanup } = await this.downloadVsix(vsix);44try {45return await super.install(location, options);46} finally {47await cleanup();48}49}5051private async downloadVsix(vsix: URI): Promise<{ location: URI; cleanup: () => Promise<void> }> {52if (vsix.scheme === Schemas.file) {53return { location: vsix, async cleanup() { } };54}55this.logService.trace('Downloading extension from', vsix.toString());56const location = joinPath(this.nativeEnvironmentService.extensionsDownloadLocation, generateUuid());57await this.downloadService.download(vsix, location);58this.logService.info('Downloaded extension to', location.toString());59const cleanup = async () => {60try {61await this.fileService.del(location);62} catch (error) {63this.logService.error(error);64}65};66return { location, cleanup };67}6869protected override async switchExtensionsProfile(previousProfileLocation: URI, currentProfileLocation: URI, preserveExtensions?: ExtensionIdentifier[]): Promise<DidChangeProfileEvent> {70if (this.nativeEnvironmentService.remoteAuthority) {71const previousInstalledExtensions = await this.getInstalled(ExtensionType.User, previousProfileLocation);72const resolverExtension = previousInstalledExtensions.find(e => isResolverExtension(e.manifest, this.nativeEnvironmentService.remoteAuthority));73if (resolverExtension) {74if (!preserveExtensions) {75preserveExtensions = [];76}77preserveExtensions.push(new ExtensionIdentifier(resolverExtension.identifier.id));78}79}80return super.switchExtensionsProfile(previousProfileLocation, currentProfileLocation, preserveExtensions);81}82}838485