Change:
Originally posted by in
This is a great idea: !
Previously, extensions that patched VSCode like would occasionally result in a notification only after VSCode was updated. After this change, this banner appears every time VSCode is opened, even if it was previously dismissed for the same version. This feels very obtrusive. Was that an intended part of this change? !
Banner will be removed again in , I think it will cause more harm than being useful.

Discussion:
import { IOpenerService } from 'vs/platform/opener/common/opener'; import { FileAccess, AppResourcePath } from 'vs/base/common/network'; import { IChecksumService } from 'vs/platform/checksum/common/checksumService'; <ins> import { ILogService } from 'vs/platform/log/common/log'; import { IBannerService } from 'vs/workbench/services/banner/browser/bannerService'; import { Codicon } from 'vs/base/common/codicons'; </ins> interface IStorageData { <del> dontShowPrompt: boolean; commit: string | undefined; </del> <ins> readonly dontShowPrompt: boolean; readonly commit: string | undefined; </ins> } class IntegrityStorage { private static readonly KEY = 'integrityService'; <del> private storageService: IStorageService; </del> private value: IStorageData | null; <del> constructor(storageService: IStorageService) { this.storageService = storageService; </del> <ins> constructor(private readonly storageService: IStorageService) { </ins> this.value = this._read(); }

if (!jsonValue) { return null; } try { return JSON.parse(jsonValue); } catch (err) {

declare readonly _serviceBrand: undefined; <del> private _storage: IntegrityStorage; private _isPurePromise: Promise<IntegrityTestResult>; </del> <ins> private readonly _storage = new IntegrityStorage(this.storageService); private readonly _isPurePromise = this._isPure(); isPure(): Promise<IntegrityTestResult> { return this._isPurePromise; } </ins> constructor( @INotificationService private readonly notificationService: INotificationService, <del> @IStorageService storageService: IStorageService, </del> <ins> @IStorageService private readonly storageService: IStorageService, </ins> @ILifecycleService private readonly lifecycleService: ILifecycleService, @IOpenerService private readonly openerService: IOpenerService, @IProductService private readonly productService: IProductService, <del> @IChecksumService private readonly checksumService: IChecksumService </del> <ins> @IChecksumService private readonly checksumService: IChecksumService, @ILogService private readonly logService: ILogService, @IBannerService private readonly bannerService: IBannerService </ins> ) { <del> this._storage = new IntegrityStorage(storageService); </del> <ins> this._compute(); } </ins> <del> this._isPurePromise = this._isPure(); </del> <ins> private async _compute(): Promise<void> { const { isPure } = await this.isPure(); if (isPure) { return; // all is good } </ins> <del> this.isPure().then(r => { if (r.isPure) { return; // all is good } </del> <ins> this.logService.warn(` </ins> <del> this._prompt(); }); } </del> <ins> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!	Installation has been modified on disk and is UNSUPPORTED. Please reinstall !!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! `); </ins> <del> private _prompt(): void { </del> const storedData = this._storage.get(); if (storedData?.dontShowPrompt && storedData.commit === this.productService.commit) { return; // Do not prompt } <del> const checksumFailMoreInfoUrl = this.productService.checksumFailMoreInfoUrl; const message = localize('integrity.prompt', "Your {0} installation appears to be corrupt. Please reinstall.", this.productService.nameShort); if (checksumFailMoreInfoUrl) { this.notificationService.prompt( Severity.Warning, message, [ { label: localize('integrity.moreInformation', "More Information"), run: () => this.openerService.open(URI.parse(checksumFailMoreInfoUrl)) }, { label: localize('integrity.dontShowAgain', "Don't Show Again"), isSecondary: true, run: () => this._storage.set({ dontShowPrompt: true, commit: this.productService.commit }) } ], { sticky: true, priority: NotificationPriority.URGENT } ); } else { this.notificationService.notify({ severity: Severity.Warning, message, sticky: true }); } } isPure(): Promise<IntegrityTestResult> { return this._isPurePromise; </del> <ins> this._showBanner(); this._showNotification(); </ins> } private async _isPure(): Promise<IntegrityTestResult> {

} return { <del> isPure: isPure, </del> <ins> isPure, </ins> proof: allResults }; }

isPure: (actual === expected) }; } <ins> private _showBanner(): void { const checksumFailMoreInfoUrl = this.productService.checksumFailMoreInfoUrl; this.bannerService.show({ id: 'installation.corrupt', message: localize('integrity.banner', "Your {0} installation appears to be corrupt. Please reinstall.", this.productService.nameShort), icon: Codicon.warning, actions: checksumFailMoreInfoUrl ? [ { label: localize('integrity.moreInformation', "More Information"), href: checksumFailMoreInfoUrl } ] : undefined }); } private _showNotification(): void { const checksumFailMoreInfoUrl = this.productService.checksumFailMoreInfoUrl; const message = localize('integrity.prompt', "Your {0} installation appears to be corrupt. Please reinstall.", this.productService.nameShort); if (checksumFailMoreInfoUrl) { this.notificationService.prompt( Severity.Warning, message, [ { label: localize('integrity.moreInformation', "More Information"), run: () => this.openerService.open(URI.parse(checksumFailMoreInfoUrl)) }, { label: localize('integrity.dontShowAgain', "Don't Show Again"), isSecondary: true, run: () => this._storage.set({ dontShowPrompt: true, commit: this.productService.commit }) } ], { sticky: true, priority: NotificationPriority.URGENT } ); } else { this.notificationService.notify({ severity: Severity.Warning, message, sticky: true, priority: NotificationPriority.URGENT }); } } </ins> } registerSingleton(IIntegrityService, IntegrityService, InstantiationType.Delayed);