Skip to content

Commit d607e9d

Browse files
authored
show notification when running as admin on user setup (microsoft#186986)
fixes microsoft#186960
1 parent dca4956 commit d607e9d

File tree

6 files changed

+47
-10
lines changed

6 files changed

+47
-10
lines changed

src/vs/platform/menubar/electron-main/menubar.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,6 @@ export class Menubar {
596596
const state = this.updateService.state;
597597

598598
switch (state.type) {
599-
case StateType.Uninitialized:
600-
return [];
601-
602599
case StateType.Idle:
603600
return [new MenuItem({
604601
label: this.mnemonicLabel(nls.localize('miCheckForUpdates', "Check for &&Updates...")), click: () => setTimeout(() => {
@@ -638,6 +635,9 @@ export class Menubar {
638635
this.updateService.quitAndInstall();
639636
}
640637
})];
638+
639+
default:
640+
return [];
641641
}
642642
}
643643

src/vs/platform/update/common/update.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export interface IUpdate {
3535
export const enum StateType {
3636
Uninitialized = 'uninitialized',
3737
Idle = 'idle',
38+
Disabled = 'disabled',
3839
CheckingForUpdates = 'checking for updates',
3940
AvailableForDownload = 'available for download',
4041
Downloading = 'downloading',
@@ -49,7 +50,17 @@ export const enum UpdateType {
4950
Snap
5051
}
5152

53+
export const enum DisablementReason {
54+
NotBuilt,
55+
DisabledByEnvironment,
56+
ManuallyDisabled,
57+
MissingConfiguration,
58+
InvalidConfiguration,
59+
RunningAsAdmin,
60+
}
61+
5262
export type Uninitialized = { type: StateType.Uninitialized };
63+
export type Disabled = { type: StateType.Disabled; reason: DisablementReason };
5364
export type Idle = { type: StateType.Idle; updateType: UpdateType; error?: string };
5465
export type CheckingForUpdates = { type: StateType.CheckingForUpdates; explicit: boolean };
5566
export type AvailableForDownload = { type: StateType.AvailableForDownload; update: IUpdate };
@@ -58,10 +69,11 @@ export type Downloaded = { type: StateType.Downloaded; update: IUpdate };
5869
export type Updating = { type: StateType.Updating; update: IUpdate };
5970
export type Ready = { type: StateType.Ready; update: IUpdate };
6071

61-
export type State = Uninitialized | Idle | CheckingForUpdates | AvailableForDownload | Downloading | Downloaded | Updating | Ready;
72+
export type State = Uninitialized | Disabled | Idle | CheckingForUpdates | AvailableForDownload | Downloading | Downloaded | Updating | Ready;
6273

6374
export const State = {
6475
Uninitialized: { type: StateType.Uninitialized } as Uninitialized,
76+
Disabled: (reason: DisablementReason) => ({ type: StateType.Disabled, reason }) as Disabled,
6577
Idle: (updateType: UpdateType, error?: string) => ({ type: StateType.Idle, updateType, error }) as Idle,
6678
CheckingForUpdates: (explicit: boolean) => ({ type: StateType.CheckingForUpdates, explicit } as CheckingForUpdates),
6779
AvailableForDownload: (update: IUpdate) => ({ type: StateType.AvailableForDownload, update } as AvailableForDownload),

src/vs/platform/update/electron-main/abstractUpdateService.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle
1212
import { ILogService } from 'vs/platform/log/common/log';
1313
import { IProductService } from 'vs/platform/product/common/productService';
1414
import { IRequestService } from 'vs/platform/request/common/request';
15-
import { AvailableForDownload, IUpdateService, State, StateType, UpdateType } from 'vs/platform/update/common/update';
15+
import { AvailableForDownload, DisablementReason, IUpdateService, State, StateType, UpdateType } from 'vs/platform/update/common/update';
1616

1717
export function createUpdateURL(platform: string, quality: string, productService: IProductService): string {
1818
return `${productService.updateUrl}/api/update/${platform}/${quality}/${productService.commit}`;
@@ -64,15 +64,18 @@ export abstract class AbstractUpdateService implements IUpdateService {
6464
*/
6565
protected async initialize(): Promise<void> {
6666
if (!this.environmentMainService.isBuilt) {
67+
this.setState(State.Disabled(DisablementReason.NotBuilt));
6768
return; // updates are never enabled when running out of sources
6869
}
6970

7071
if (this.environmentMainService.disableUpdates) {
72+
this.setState(State.Disabled(DisablementReason.DisabledByEnvironment));
7173
this.logService.info('update#ctor - updates are disabled by the environment');
7274
return;
7375
}
7476

7577
if (!this.productService.updateUrl || !this.productService.commit) {
78+
this.setState(State.Disabled(DisablementReason.MissingConfiguration));
7679
this.logService.info('update#ctor - updates are disabled as there is no update URL');
7780
return;
7881
}
@@ -81,12 +84,14 @@ export abstract class AbstractUpdateService implements IUpdateService {
8184
const quality = this.getProductQuality(updateMode);
8285

8386
if (!quality) {
87+
this.setState(State.Disabled(DisablementReason.ManuallyDisabled));
8488
this.logService.info('update#ctor - updates are disabled by user preference');
8589
return;
8690
}
8791

8892
this.url = this.buildUpdateFeedUrl(quality);
8993
if (!this.url) {
94+
this.setState(State.Disabled(DisablementReason.InvalidConfiguration));
9095
this.logService.info('update#ctor - updates are disabled as the update URL is badly formed');
9196
return;
9297
}

src/vs/platform/update/electron-main/updateService.win32.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { INativeHostMainService } from 'vs/platform/native/electron-main/nativeH
2222
import { IProductService } from 'vs/platform/product/common/productService';
2323
import { asJson, IRequestService } from 'vs/platform/request/common/request';
2424
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
25-
import { AvailableForDownload, IUpdate, State, StateType, UpdateType } from 'vs/platform/update/common/update';
25+
import { AvailableForDownload, DisablementReason, IUpdate, State, StateType, UpdateType } from 'vs/platform/update/common/update';
2626
import { AbstractUpdateService, createUpdateURL, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
2727

2828
async function pollUntil(fn: () => boolean, millis = 1000): Promise<void> {
@@ -73,6 +73,7 @@ export class Win32UpdateService extends AbstractUpdateService {
7373

7474
protected override async initialize(): Promise<void> {
7575
if (this.productService.target === 'user' && await this.nativeHostMainService.isAdmin(undefined)) {
76+
this.setState(State.Disabled(DisablementReason.RunningAsAdmin));
7677
this.logService.info('update#ctor - updates are disabled due to running as Admin in user setup');
7778
return;
7879
}

src/vs/workbench/browser/parts/titlebar/menubarControl.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,6 @@ export class CustomMenubarControl extends MenubarControl {
459459
const state = this.updateService.state;
460460

461461
switch (state.type) {
462-
case StateType.Uninitialized:
463-
return null;
464-
465462
case StateType.Idle:
466463
return new Action('update.check', localize({ key: 'checkForUpdates', comment: ['&& denotes a mnemonic'] }, "Check for &&Updates..."), undefined, true, () =>
467464
this.updateService.checkForUpdates(true));
@@ -486,6 +483,9 @@ export class CustomMenubarControl extends MenubarControl {
486483
case StateType.Ready:
487484
return new Action('update.restart', localize({ key: 'restartToUpdate', comment: ['&& denotes a mnemonic'] }, "Restart to &&Update"), undefined, true, () =>
488485
this.updateService.quitAndInstall());
486+
487+
default:
488+
return null;
489489
}
490490
}
491491

src/vs/workbench/contrib/update/browser/update.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati
1212
import { IOpenerService } from 'vs/platform/opener/common/opener';
1313
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
1414
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
15-
import { IUpdateService, State as UpdateState, StateType, IUpdate } from 'vs/platform/update/common/update';
15+
import { IUpdateService, State as UpdateState, StateType, IUpdate, DisablementReason } from 'vs/platform/update/common/update';
1616
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
1717
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
1818
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
@@ -29,6 +29,7 @@ import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
2929
import { Promises } from 'vs/base/common/async';
3030
import { IUserDataSyncWorkbenchService } from 'vs/workbench/services/userDataSync/common/userDataSync';
3131
import { Event } from 'vs/base/common/event';
32+
import { Action } from 'vs/base/common/actions';
3233

3334
export const CONTEXT_UPDATE_STATE = new RawContextKey<string>('updateState', StateType.Uninitialized);
3435
export const RELEASE_NOTES_URL = new RawContextKey<string>('releaseNotesUrl', '');
@@ -169,6 +170,7 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu
169170
@IActivityService private readonly activityService: IActivityService,
170171
@IContextKeyService private readonly contextKeyService: IContextKeyService,
171172
@IProductService private readonly productService: IProductService,
173+
@IOpenerService private readonly openerService: IOpenerService,
172174
@IHostService private readonly hostService: IHostService
173175
) {
174176
super();
@@ -202,6 +204,23 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu
202204
this.updateStateContextKey.set(state.type);
203205

204206
switch (state.type) {
207+
case StateType.Disabled:
208+
if (state.reason === DisablementReason.RunningAsAdmin) {
209+
this.notificationService.notify({
210+
severity: Severity.Info,
211+
message: nls.localize('update service disabled', "Updates are disabled because you are running the user-scope installation of {0} as Administrator.", this.productService.nameLong),
212+
actions: {
213+
primary: [
214+
new Action('', nls.localize('learn more', "Learn More"), undefined, undefined, () => {
215+
this.openerService.open('https://aka.ms/vscode-windows-setup');
216+
})
217+
]
218+
},
219+
neverShowAgain: { id: 'no-updates-running-as-admin', }
220+
});
221+
}
222+
break;
223+
205224
case StateType.Idle:
206225
if (state.error) {
207226
this.onError(state.error);

0 commit comments

Comments
 (0)