Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show notification when running as admin on user setup #186986

Merged
merged 1 commit into from
Jul 4, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/vs/platform/menubar/electron-main/menubar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,9 +596,6 @@ export class Menubar {
const state = this.updateService.state;

switch (state.type) {
case StateType.Uninitialized:
return [];

case StateType.Idle:
return [new MenuItem({
label: this.mnemonicLabel(nls.localize('miCheckForUpdates', "Check for &&Updates...")), click: () => setTimeout(() => {
Expand Down Expand Up @@ -638,6 +635,9 @@ export class Menubar {
this.updateService.quitAndInstall();
}
})];

default:
return [];
}
}

Expand Down
14 changes: 13 additions & 1 deletion src/vs/platform/update/common/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface IUpdate {
export const enum StateType {
Uninitialized = 'uninitialized',
Idle = 'idle',
Disabled = 'disabled',
CheckingForUpdates = 'checking for updates',
AvailableForDownload = 'available for download',
Downloading = 'downloading',
Expand All @@ -49,7 +50,17 @@ export const enum UpdateType {
Snap
}

export const enum DisablementReason {
NotBuilt,
DisabledByEnvironment,
ManuallyDisabled,
MissingConfiguration,
InvalidConfiguration,
RunningAsAdmin,
}

export type Uninitialized = { type: StateType.Uninitialized };
export type Disabled = { type: StateType.Disabled; reason: DisablementReason };
export type Idle = { type: StateType.Idle; updateType: UpdateType; error?: string };
export type CheckingForUpdates = { type: StateType.CheckingForUpdates; explicit: boolean };
export type AvailableForDownload = { type: StateType.AvailableForDownload; update: IUpdate };
Expand All @@ -58,10 +69,11 @@ export type Downloaded = { type: StateType.Downloaded; update: IUpdate };
export type Updating = { type: StateType.Updating; update: IUpdate };
export type Ready = { type: StateType.Ready; update: IUpdate };

export type State = Uninitialized | Idle | CheckingForUpdates | AvailableForDownload | Downloading | Downloaded | Updating | Ready;
export type State = Uninitialized | Disabled | Idle | CheckingForUpdates | AvailableForDownload | Downloading | Downloaded | Updating | Ready;

export const State = {
Uninitialized: { type: StateType.Uninitialized } as Uninitialized,
Disabled: (reason: DisablementReason) => ({ type: StateType.Disabled, reason }) as Disabled,
Idle: (updateType: UpdateType, error?: string) => ({ type: StateType.Idle, updateType, error }) as Idle,
CheckingForUpdates: (explicit: boolean) => ({ type: StateType.CheckingForUpdates, explicit } as CheckingForUpdates),
AvailableForDownload: (update: IUpdate) => ({ type: StateType.AvailableForDownload, update } as AvailableForDownload),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle
import { ILogService } from 'vs/platform/log/common/log';
import { IProductService } from 'vs/platform/product/common/productService';
import { IRequestService } from 'vs/platform/request/common/request';
import { AvailableForDownload, IUpdateService, State, StateType, UpdateType } from 'vs/platform/update/common/update';
import { AvailableForDownload, DisablementReason, IUpdateService, State, StateType, UpdateType } from 'vs/platform/update/common/update';

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

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

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

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

this.url = this.buildUpdateFeedUrl(quality);
if (!this.url) {
this.setState(State.Disabled(DisablementReason.InvalidConfiguration));
this.logService.info('update#ctor - updates are disabled as the update URL is badly formed');
return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/vs/platform/update/electron-main/updateService.win32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { INativeHostMainService } from 'vs/platform/native/electron-main/nativeH
import { IProductService } from 'vs/platform/product/common/productService';
import { asJson, IRequestService } from 'vs/platform/request/common/request';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { AvailableForDownload, IUpdate, State, StateType, UpdateType } from 'vs/platform/update/common/update';
import { AvailableForDownload, DisablementReason, IUpdate, State, StateType, UpdateType } from 'vs/platform/update/common/update';
import { AbstractUpdateService, createUpdateURL, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';

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

protected override async initialize(): Promise<void> {
if (this.productService.target === 'user' && await this.nativeHostMainService.isAdmin(undefined)) {
this.setState(State.Disabled(DisablementReason.RunningAsAdmin));
this.logService.info('update#ctor - updates are disabled due to running as Admin in user setup');
return;
}
Expand Down
6 changes: 3 additions & 3 deletions src/vs/workbench/browser/parts/titlebar/menubarControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,9 +459,6 @@ export class CustomMenubarControl extends MenubarControl {
const state = this.updateService.state;

switch (state.type) {
case StateType.Uninitialized:
return null;

case StateType.Idle:
return new Action('update.check', localize({ key: 'checkForUpdates', comment: ['&& denotes a mnemonic'] }, "Check for &&Updates..."), undefined, true, () =>
this.updateService.checkForUpdates(true));
Expand All @@ -486,6 +483,9 @@ export class CustomMenubarControl extends MenubarControl {
case StateType.Ready:
return new Action('update.restart', localize({ key: 'restartToUpdate', comment: ['&& denotes a mnemonic'] }, "Restart to &&Update"), undefined, true, () =>
this.updateService.quitAndInstall());

default:
return null;
}
}

Expand Down
21 changes: 20 additions & 1 deletion src/vs/workbench/contrib/update/browser/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { IUpdateService, State as UpdateState, StateType, IUpdate } from 'vs/platform/update/common/update';
import { IUpdateService, State as UpdateState, StateType, IUpdate, DisablementReason } from 'vs/platform/update/common/update';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
Expand All @@ -29,6 +29,7 @@ import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
import { Promises } from 'vs/base/common/async';
import { IUserDataSyncWorkbenchService } from 'vs/workbench/services/userDataSync/common/userDataSync';
import { Event } from 'vs/base/common/event';
import { Action } from 'vs/base/common/actions';

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

switch (state.type) {
case StateType.Disabled:
if (state.reason === DisablementReason.RunningAsAdmin) {
this.notificationService.notify({
severity: Severity.Info,
message: nls.localize('update service disabled', "Updates are disabled because you are running the user-scope installation of {0} as Administrator.", this.productService.nameLong),
actions: {
primary: [
new Action('', nls.localize('learn more', "Learn More"), undefined, undefined, () => {
this.openerService.open('https://aka.ms/vscode-windows-setup');
})
]
},
neverShowAgain: { id: 'no-updates-running-as-admin', }
});
}
break;

case StateType.Idle:
if (state.error) {
this.onError(state.error);
Expand Down