mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 02:48:30 -05:00
Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 (#14050)
* Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 * Fix breaks * Extension management fixes * Fix breaks in windows bundling * Fix/skip failing tests * Update distro * Add clear to nuget.config * Add hygiene task * Bump distro * Fix hygiene issue * Add build to hygiene exclusion * Update distro * Update hygiene * Hygiene exclusions * Update tsconfig * Bump distro for server breaks * Update build config * Update darwin path * Add done calls to notebook tests * Skip failing tests * Disable smoke tests
This commit is contained in:
@@ -3,13 +3,13 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, protocol, IpcMainEvent, BrowserWindow, dialog, session } from 'electron';
|
||||
import { IProcessEnvironment, isWindows, isMacintosh } from 'vs/base/common/platform';
|
||||
import { app, ipcMain, systemPreferences, contentTracing, protocol, BrowserWindow, dialog, session } from 'electron';
|
||||
import { IProcessEnvironment, isWindows, isMacintosh, isLinux } from 'vs/base/common/platform';
|
||||
import { WindowsMainService } from 'vs/platform/windows/electron-main/windowsMainService';
|
||||
import { IWindowOpenable } from 'vs/platform/windows/common/windows';
|
||||
import { OpenContext } from 'vs/platform/windows/node/window';
|
||||
import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { getShellEnvironment } from 'vs/code/node/shellEnv';
|
||||
import { resolveShellEnv } from 'vs/code/node/shellEnv';
|
||||
import { IUpdateService } from 'vs/platform/update/common/update';
|
||||
import { UpdateChannel } from 'vs/platform/update/electron-main/updateIpc';
|
||||
import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main';
|
||||
@@ -22,21 +22,22 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IStateService } from 'vs/platform/state/node/state';
|
||||
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import { IOpenURLOptions, IURLService } from 'vs/platform/url/common/url';
|
||||
import { URLHandlerChannelClient, URLHandlerRouter } from 'vs/platform/url/common/urlIpc';
|
||||
import { ITelemetryService, machineIdKey } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
|
||||
import { getDelayedChannel, StaticRouter, createChannelReceiver } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { getDelayedChannel, StaticRouter, createChannelReceiver, createChannelSender } from 'vs/base/parts/ipc/common/ipc';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { ProxyAuthHandler } from 'vs/code/electron-main/auth';
|
||||
import { ProxyAuthHandler2 } from 'vs/code/electron-main/auth2';
|
||||
import { FileProtocolHandler } from 'vs/code/electron-main/protocol';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
|
||||
import { ActiveWindowManager } from 'vs/platform/windows/electron-main/windowTracker';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { hasWorkspaceFileExtension, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { WorkspacesService } from 'vs/platform/workspaces/electron-main/workspacesService';
|
||||
@@ -50,10 +51,10 @@ import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/err
|
||||
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
|
||||
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
||||
import { IMenubarMainService, MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService';
|
||||
import { RunOnceScheduler, timeout } from 'vs/base/common/async';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
|
||||
import { homedir } from 'os';
|
||||
import { join, sep, posix } from 'vs/base/common/path';
|
||||
import { sep, posix, join, isAbsolute } from 'vs/base/common/path';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { SnapUpdateService } from 'vs/platform/update/electron-main/updateService.snap';
|
||||
@@ -65,17 +66,13 @@ import { WorkspacesHistoryMainService, IWorkspacesHistoryMainService } from 'vs/
|
||||
import { NativeURLService } from 'vs/platform/url/common/urlService';
|
||||
import { WorkspacesMainService, IWorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { statSync } from 'fs';
|
||||
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
|
||||
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
|
||||
import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/electron-main/extensionHostDebugIpc';
|
||||
import { IElectronMainService, ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService';
|
||||
import { INativeHostMainService, NativeHostMainService } from 'vs/platform/native/electron-main/nativeHostMainService';
|
||||
import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService';
|
||||
import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
|
||||
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
|
||||
import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService';
|
||||
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
|
||||
@@ -83,20 +80,32 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { stripComments } from 'vs/base/common/json';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { EncryptionMainService, IEncryptionMainService } from 'vs/platform/encryption/electron-main/encryptionMainService';
|
||||
import { ActiveWindowManager } from 'vs/platform/windows/common/windowTracker';
|
||||
import { IKeyboardLayoutMainService, KeyboardLayoutMainService } from 'vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { DisplayMainService, IDisplayMainService } from 'vs/platform/display/electron-main/displayMainService';
|
||||
import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper';
|
||||
import { isEqualOrParent } from 'vs/base/common/extpath';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { ExtensionUrlTrustService } from 'vs/platform/extensionManagement/node/extensionUrlTrustService';
|
||||
|
||||
export class CodeApplication extends Disposable {
|
||||
private windowsMainService: IWindowsMainService | undefined;
|
||||
private dialogMainService: IDialogMainService | undefined;
|
||||
private nativeHostMainService: INativeHostMainService | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly mainIpcServer: Server,
|
||||
private readonly userEnv: IProcessEnvironment,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IEnvironmentService private readonly environmentService: INativeEnvironmentService,
|
||||
@IEnvironmentMainService private readonly environmentService: IEnvironmentMainService,
|
||||
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IStateService private readonly stateService: IStateService
|
||||
@IStateService private readonly stateService: IStateService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -116,18 +125,18 @@ export class CodeApplication extends Disposable {
|
||||
// Contextmenu via IPC support
|
||||
registerContextMenuListener();
|
||||
|
||||
app.on('accessibility-support-changed', (event: Event, accessibilitySupportEnabled: boolean) => {
|
||||
if (this.windowsMainService) {
|
||||
this.windowsMainService.sendToAll('vscode:accessibilitySupportChanged', accessibilitySupportEnabled);
|
||||
}
|
||||
// Accessibility change event
|
||||
app.on('accessibility-support-changed', (event, accessibilitySupportEnabled) => {
|
||||
this.windowsMainService?.sendToAll('vscode:accessibilitySupportChanged', accessibilitySupportEnabled);
|
||||
});
|
||||
|
||||
app.on('activate', (event: Event, hasVisibleWindows: boolean) => {
|
||||
this.logService.trace('App#activate');
|
||||
// macOS dock activate
|
||||
app.on('activate', (event, hasVisibleWindows) => {
|
||||
this.logService.trace('app#activate');
|
||||
|
||||
// Mac only event: open new window when we get activated
|
||||
if (!hasVisibleWindows && this.windowsMainService) {
|
||||
this.windowsMainService.openEmptyWindow({ context: OpenContext.DOCK });
|
||||
if (!hasVisibleWindows) {
|
||||
this.windowsMainService?.openEmptyWindow({ context: OpenContext.DOCK });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -136,7 +145,7 @@ export class CodeApplication extends Disposable {
|
||||
// !!! DO NOT CHANGE without consulting the documentation !!!
|
||||
//
|
||||
app.on('remote-require', (event, sender, module) => {
|
||||
this.logService.trace('App#on(remote-require): prevented');
|
||||
this.logService.trace('app#on(remote-require): prevented');
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
@@ -166,8 +175,8 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
app.on('web-contents-created', (_event: Event, contents) => {
|
||||
contents.on('will-attach-webview', (event: Event, webPreferences, params) => {
|
||||
app.on('web-contents-created', (event, contents) => {
|
||||
contents.on('will-attach-webview', (event, webPreferences, params) => {
|
||||
|
||||
const isValidWebviewSource = (source: string | undefined): boolean => {
|
||||
if (!source) {
|
||||
@@ -209,10 +218,10 @@ export class CodeApplication extends Disposable {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
contents.on('new-window', (event: Event, url: string) => {
|
||||
contents.on('new-window', (event, url) => {
|
||||
event.preventDefault(); // prevent code that wants to open links
|
||||
|
||||
shell.openExternal(url);
|
||||
this.nativeHostMainService?.openExternal(undefined, url);
|
||||
});
|
||||
|
||||
session.defaultSession.setPermissionRequestHandler((webContents, permission /* 'media' | 'geolocation' | 'notifications' | 'midiSysex' | 'pointerLock' | 'fullscreen' | 'openExternal' */, callback) => {
|
||||
@@ -228,8 +237,8 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
let macOpenFileURIs: IWindowOpenable[] = [];
|
||||
let runningTimeout: NodeJS.Timeout | null = null;
|
||||
app.on('open-file', (event: Event, path: string) => {
|
||||
this.logService.trace('App#open-file: ', path);
|
||||
app.on('open-file', (event, path) => {
|
||||
this.logService.trace('app#open-file: ', path);
|
||||
event.preventDefault();
|
||||
|
||||
// Keep in array because more might come!
|
||||
@@ -243,67 +252,119 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
// Handle paths delayed in case more are coming!
|
||||
runningTimeout = setTimeout(() => {
|
||||
if (this.windowsMainService) {
|
||||
this.windowsMainService.open({
|
||||
context: OpenContext.DOCK /* can also be opening from finder while app is running */,
|
||||
cli: this.environmentService.args,
|
||||
urisToOpen: macOpenFileURIs,
|
||||
gotoLineMode: false,
|
||||
preferNewWindow: true /* dropping on the dock or opening from finder prefers to open in a new window */
|
||||
});
|
||||
this.windowsMainService?.open({
|
||||
context: OpenContext.DOCK /* can also be opening from finder while app is running */,
|
||||
cli: this.environmentService.args,
|
||||
urisToOpen: macOpenFileURIs,
|
||||
gotoLineMode: false,
|
||||
preferNewWindow: true /* dropping on the dock or opening from finder prefers to open in a new window */
|
||||
});
|
||||
|
||||
macOpenFileURIs = [];
|
||||
runningTimeout = null;
|
||||
}
|
||||
macOpenFileURIs = [];
|
||||
runningTimeout = null;
|
||||
}, 100);
|
||||
});
|
||||
|
||||
app.on('new-window-for-tab', () => {
|
||||
if (this.windowsMainService) {
|
||||
this.windowsMainService.openEmptyWindow({ context: OpenContext.DESKTOP }); //macOS native tab "+" button
|
||||
}
|
||||
this.windowsMainService?.openEmptyWindow({ context: OpenContext.DESKTOP }); //macOS native tab "+" button
|
||||
});
|
||||
|
||||
ipc.on('vscode:fetchShellEnv', async (event: IpcMainEvent) => {
|
||||
//#region Bootstrap IPC Handlers
|
||||
|
||||
ipcMain.on('vscode:fetchShellEnv', async event => {
|
||||
const webContents = event.sender;
|
||||
const window = this.windowsMainService?.getWindowByWebContents(event.sender);
|
||||
|
||||
try {
|
||||
const shellEnv = await getShellEnvironment(this.logService, this.environmentService);
|
||||
let replied = false;
|
||||
|
||||
// TODO@sandbox workaround for https://github.com/electron/electron/issues/25119
|
||||
if (this.environmentService.sandbox) {
|
||||
await timeout(100);
|
||||
function acceptShellEnv(env: NodeJS.ProcessEnv): void {
|
||||
clearTimeout(shellEnvSlowWarningHandle);
|
||||
clearTimeout(shellEnvTimeoutErrorHandle);
|
||||
|
||||
if (!replied) {
|
||||
replied = true;
|
||||
|
||||
if (!webContents.isDestroyed()) {
|
||||
webContents.send('vscode:acceptShellEnv', env);
|
||||
}
|
||||
}
|
||||
|
||||
if (!webContents.isDestroyed()) {
|
||||
webContents.send('vscode:acceptShellEnv', shellEnv);
|
||||
}
|
||||
} catch (error) {
|
||||
if (!webContents.isDestroyed()) {
|
||||
webContents.send('vscode:acceptShellEnv', {});
|
||||
}
|
||||
|
||||
this.logService.error('Error fetching shell env', error);
|
||||
}
|
||||
|
||||
// Handle slow shell environment resolve calls:
|
||||
// - a warning after 3s but continue to resolve
|
||||
// - an error after 10s and stop trying to resolve
|
||||
const cts = new CancellationTokenSource();
|
||||
const shellEnvSlowWarningHandle = setTimeout(() => window?.sendWhenReady('vscode:showShellEnvSlowWarning', cts.token), 3000);
|
||||
const shellEnvTimeoutErrorHandle = setTimeout(function () {
|
||||
cts.dispose(true);
|
||||
window?.sendWhenReady('vscode:showShellEnvTimeoutError', CancellationToken.None);
|
||||
acceptShellEnv({});
|
||||
}, 10000);
|
||||
|
||||
// Prefer to use the args and env from the target window
|
||||
// when resolving the shell env. It is possible that
|
||||
// a first window was opened from the UI but a second
|
||||
// from the CLI and that has implications for wether to
|
||||
// resolve the shell environment or not.
|
||||
let args: NativeParsedArgs;
|
||||
let env: NodeJS.ProcessEnv;
|
||||
if (window?.config) {
|
||||
args = window.config;
|
||||
env = { ...process.env, ...window.config.userEnv };
|
||||
} else {
|
||||
args = this.environmentService.args;
|
||||
env = process.env;
|
||||
}
|
||||
|
||||
// Resolve shell env
|
||||
const shellEnv = await resolveShellEnv(this.logService, args, env);
|
||||
acceptShellEnv(shellEnv);
|
||||
});
|
||||
|
||||
ipc.on('vscode:toggleDevTools', (event: IpcMainEvent) => event.sender.toggleDevTools());
|
||||
ipc.on('vscode:openDevTools', (event: IpcMainEvent) => event.sender.openDevTools());
|
||||
ipcMain.handle('vscode:writeNlsFile', (event, path: unknown, data: unknown) => {
|
||||
const uri = this.validateNlsPath([path]);
|
||||
if (!uri || typeof data !== 'string') {
|
||||
return Promise.reject('Invalid operation (vscode:writeNlsFile)');
|
||||
}
|
||||
|
||||
ipc.on('vscode:reloadWindow', (event: IpcMainEvent) => event.sender.reload());
|
||||
return this.fileService.writeFile(uri, VSBuffer.fromString(data));
|
||||
});
|
||||
|
||||
// Some listeners after window opened
|
||||
(async () => {
|
||||
await this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen);
|
||||
ipcMain.handle('vscode:readNlsFile', async (event, ...paths: unknown[]) => {
|
||||
const uri = this.validateNlsPath(paths);
|
||||
if (!uri) {
|
||||
return Promise.reject('Invalid operation (vscode:readNlsFile)');
|
||||
}
|
||||
|
||||
// Keyboard layout changes (after window opened)
|
||||
const nativeKeymap = await import('native-keymap');
|
||||
nativeKeymap.onDidChangeKeyboardLayout(() => {
|
||||
if (this.windowsMainService) {
|
||||
this.windowsMainService.sendToAll('vscode:keyboardLayoutChanged');
|
||||
return (await this.fileService.readFile(uri)).value.toString();
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:toggleDevTools', event => event.sender.toggleDevTools());
|
||||
ipcMain.on('vscode:openDevTools', event => event.sender.openDevTools());
|
||||
|
||||
ipcMain.on('vscode:reloadWindow', event => event.sender.reload());
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
private validateNlsPath(pathSegments: unknown[]): URI | undefined {
|
||||
let path: string | undefined = undefined;
|
||||
|
||||
for (const pathSegment of pathSegments) {
|
||||
if (typeof pathSegment === 'string') {
|
||||
if (typeof path !== 'string') {
|
||||
path = pathSegment;
|
||||
} else {
|
||||
path = join(path, pathSegment);
|
||||
}
|
||||
});
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof path !== 'string' || !isAbsolute(path) || !isEqualOrParent(path, this.environmentService.cachedLanguagesPath, !isLinux)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return URI.file(path);
|
||||
}
|
||||
|
||||
private onUnexpectedError(err: Error): void {
|
||||
@@ -316,9 +377,7 @@ export class CodeApplication extends Disposable {
|
||||
};
|
||||
|
||||
// handle on client side
|
||||
if (this.windowsMainService) {
|
||||
this.windowsMainService.sendToFocused('vscode:reportError', JSON.stringify(friendlyError));
|
||||
}
|
||||
this.windowsMainService?.sendToFocused('vscode:reportError', JSON.stringify(friendlyError));
|
||||
}
|
||||
|
||||
this.logService.error(`[uncaught exception in main]: ${err}`);
|
||||
@@ -346,7 +405,7 @@ export class CodeApplication extends Disposable {
|
||||
// "com.microsoft.", which breaks native tabs for VS Code when using this
|
||||
// identifier (from the official build).
|
||||
// Explicitly opt out of the patch here before creating any windows.
|
||||
// See: https://github.com/Microsoft/vscode/issues/35361#issuecomment-399794085
|
||||
// See: https://github.com/microsoft/vscode/issues/35361#issuecomment-399794085
|
||||
try {
|
||||
if (isMacintosh && this.configurationService.getValue<boolean>('window.nativeTabs') === true && !systemPreferences.getUserDefault('NSUseImprovedLayoutPass', 'boolean')) {
|
||||
systemPreferences.setUserDefault('NSUseImprovedLayoutPass', 'boolean', true as any);
|
||||
@@ -355,6 +414,9 @@ export class CodeApplication extends Disposable {
|
||||
this.logService.error(error);
|
||||
}
|
||||
|
||||
// Setup Protocol Handler
|
||||
const fileProtocolHandler = this._register(this.instantiationService.createInstance(FileProtocolHandler));
|
||||
|
||||
// Create Electron IPC Server
|
||||
const electronIpcServer = new ElectronIPCServer();
|
||||
|
||||
@@ -377,7 +439,7 @@ export class CodeApplication extends Disposable {
|
||||
});
|
||||
this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => {
|
||||
this._register(new RunOnceScheduler(async () => {
|
||||
sharedProcess.spawn(await getShellEnvironment(this.logService, this.environmentService));
|
||||
sharedProcess.spawn(await resolveShellEnv(this.logService, this.environmentService.args, process.env));
|
||||
}, 3000)).schedule();
|
||||
});
|
||||
|
||||
@@ -392,11 +454,15 @@ export class CodeApplication extends Disposable {
|
||||
this._register(server);
|
||||
}
|
||||
|
||||
// Setup Auth Handler
|
||||
this._register(new ProxyAuthHandler());
|
||||
// Setup Auth Handler (TODO@ben remove old auth handler eventually)
|
||||
if (this.configurationService.getValue('window.enableExperimentalProxyLoginDialog') === false) {
|
||||
this._register(new ProxyAuthHandler());
|
||||
} else {
|
||||
this._register(appInstantiationService.createInstance(<any>ProxyAuthHandler2));
|
||||
}
|
||||
|
||||
// Open Windows
|
||||
const windows = appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor, electronIpcServer, sharedProcessClient));
|
||||
const windows = appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor, electronIpcServer, sharedProcessClient, fileProtocolHandler));
|
||||
|
||||
// Post Open Windows Tasks
|
||||
appInstantiationService.invokeFunction(accessor => this.afterWindowOpen(accessor));
|
||||
@@ -446,15 +512,17 @@ export class CodeApplication extends Disposable {
|
||||
services.set(IDialogMainService, new SyncDescriptor(DialogMainService));
|
||||
services.set(ISharedProcessMainService, new SyncDescriptor(SharedProcessMainService, [sharedProcess]));
|
||||
services.set(ILaunchMainService, new SyncDescriptor(LaunchMainService));
|
||||
|
||||
const diagnosticsChannel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('diagnostics')));
|
||||
services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService, [diagnosticsChannel]));
|
||||
services.set(IDiagnosticsService, createChannelSender(getDelayedChannel(sharedProcessReady.then(client => client.getChannel('diagnostics')))));
|
||||
|
||||
services.set(IIssueMainService, new SyncDescriptor(IssueMainService, [machineId, this.userEnv]));
|
||||
services.set(IElectronMainService, new SyncDescriptor(ElectronMainService));
|
||||
services.set(IEncryptionMainService, new SyncDescriptor(EncryptionMainService, [machineId]));
|
||||
services.set(IKeyboardLayoutMainService, new SyncDescriptor(KeyboardLayoutMainService));
|
||||
services.set(IDisplayMainService, new SyncDescriptor(DisplayMainService));
|
||||
services.set(INativeHostMainService, new SyncDescriptor(NativeHostMainService));
|
||||
services.set(IWebviewManagerService, new SyncDescriptor(WebviewMainService));
|
||||
services.set(IWorkspacesService, new SyncDescriptor(WorkspacesService));
|
||||
services.set(IMenubarMainService, new SyncDescriptor(MenubarMainService));
|
||||
services.set(IExtensionUrlTrustService, new SyncDescriptor(ExtensionUrlTrustService));
|
||||
|
||||
const storageMainService = new StorageMainService(this.logService, this.environmentService);
|
||||
services.set(IStorageMainService, storageMainService);
|
||||
@@ -470,9 +538,9 @@ export class CodeApplication extends Disposable {
|
||||
// Telemetry
|
||||
if (!this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
|
||||
const channel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('telemetryAppender')));
|
||||
const appender = combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(this.logService));
|
||||
const appender = new TelemetryAppenderClient(channel);
|
||||
const commonProperties = resolveCommonProperties(product.commit, product.version, machineId, product.msftInternalDomains, this.environmentService.installSourcePath);
|
||||
const piiPaths = this.environmentService.extensionsPath ? [this.environmentService.appRoot, this.environmentService.extensionsPath] : [this.environmentService.appRoot];
|
||||
const piiPaths = [this.environmentService.appRoot, this.environmentService.extensionsPath];
|
||||
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths, sendErrorTelemetry: true };
|
||||
|
||||
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config]));
|
||||
@@ -497,17 +565,15 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
recordingStopped = true; // only once
|
||||
|
||||
const path = await contentTracing.stopRecording(join(homedir(), `${product.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`));
|
||||
const path = await contentTracing.stopRecording(joinPath(this.environmentService.userHome, `${product.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`).fsPath);
|
||||
|
||||
if (!timeout) {
|
||||
if (this.dialogMainService) {
|
||||
this.dialogMainService.showMessageBox({
|
||||
type: 'info',
|
||||
message: localize('trace.message', "Successfully created trace."),
|
||||
detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),
|
||||
buttons: [localize('trace.ok', "OK")]
|
||||
}, withNullAsUndefined(BrowserWindow.getFocusedWindow()));
|
||||
}
|
||||
this.dialogMainService?.showMessageBox({
|
||||
type: 'info',
|
||||
message: localize('trace.message', "Successfully created trace."),
|
||||
detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),
|
||||
buttons: [localize('trace.ok', "OK")]
|
||||
}, withNullAsUndefined(BrowserWindow.getFocusedWindow()));
|
||||
} else {
|
||||
this.logService.info(`Tracing: data recorded (after 30s timeout) to ${path}`);
|
||||
}
|
||||
@@ -523,7 +589,7 @@ export class CodeApplication extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private openFirstWindow(accessor: ServicesAccessor, electronIpcServer: ElectronIPCServer, sharedProcessClient: Promise<Client<string>>): ICodeWindow[] {
|
||||
private openFirstWindow(accessor: ServicesAccessor, electronIpcServer: ElectronIPCServer, sharedProcessClient: Promise<Client<string>>, fileProtocolHandler: FileProtocolHandler): ICodeWindow[] {
|
||||
|
||||
// Register more Main IPC services
|
||||
const launchMainService = accessor.get(ILaunchMainService);
|
||||
@@ -539,10 +605,22 @@ export class CodeApplication extends Disposable {
|
||||
const issueChannel = createChannelReceiver(issueMainService);
|
||||
electronIpcServer.registerChannel('issue', issueChannel);
|
||||
|
||||
const electronMainService = accessor.get(IElectronMainService);
|
||||
const electronChannel = createChannelReceiver(electronMainService);
|
||||
electronIpcServer.registerChannel('electron', electronChannel);
|
||||
sharedProcessClient.then(client => client.registerChannel('electron', electronChannel));
|
||||
const encryptionMainService = accessor.get(IEncryptionMainService);
|
||||
const encryptionChannel = createChannelReceiver(encryptionMainService);
|
||||
electronIpcServer.registerChannel('encryption', encryptionChannel);
|
||||
|
||||
const keyboardLayoutMainService = accessor.get(IKeyboardLayoutMainService);
|
||||
const keyboardLayoutChannel = createChannelReceiver(keyboardLayoutMainService);
|
||||
electronIpcServer.registerChannel('keyboardLayout', keyboardLayoutChannel);
|
||||
|
||||
const displayMainService = accessor.get(IDisplayMainService);
|
||||
const displayChannel = createChannelReceiver(displayMainService);
|
||||
electronIpcServer.registerChannel('display', displayChannel);
|
||||
|
||||
const nativeHostMainService = this.nativeHostMainService = accessor.get(INativeHostMainService);
|
||||
const nativeHostChannel = createChannelReceiver(this.nativeHostMainService);
|
||||
electronIpcServer.registerChannel('nativeHost', nativeHostChannel);
|
||||
sharedProcessClient.then(client => client.registerChannel('nativeHost', nativeHostChannel));
|
||||
|
||||
const sharedProcessMainService = accessor.get(ISharedProcessMainService);
|
||||
const sharedProcessChannel = createChannelReceiver(sharedProcessMainService);
|
||||
@@ -560,6 +638,10 @@ export class CodeApplication extends Disposable {
|
||||
const urlChannel = createChannelReceiver(urlService);
|
||||
electronIpcServer.registerChannel('url', urlChannel);
|
||||
|
||||
const extensionUrlTrustService = accessor.get(IExtensionUrlTrustService);
|
||||
const extensionUrlTrustChannel = createChannelReceiver(extensionUrlTrustService);
|
||||
electronIpcServer.registerChannel('extensionUrlTrust', extensionUrlTrustChannel);
|
||||
|
||||
const webviewManagerService = accessor.get(IWebviewManagerService);
|
||||
const webviewChannel = createChannelReceiver(webviewManagerService);
|
||||
electronIpcServer.registerChannel('webview', webviewChannel);
|
||||
@@ -569,17 +651,14 @@ export class CodeApplication extends Disposable {
|
||||
electronIpcServer.registerChannel('storage', storageChannel);
|
||||
sharedProcessClient.then(client => client.registerChannel('storage', storageChannel));
|
||||
|
||||
const storageKeysSyncRegistryService = accessor.get(IStorageKeysSyncRegistryService);
|
||||
const storageKeysSyncChannel = new StorageKeysSyncRegistryChannel(storageKeysSyncRegistryService);
|
||||
electronIpcServer.registerChannel('storageKeysSyncRegistryService', storageKeysSyncChannel);
|
||||
sharedProcessClient.then(client => client.registerChannel('storageKeysSyncRegistryService', storageKeysSyncChannel));
|
||||
|
||||
const loggerChannel = new LoggerChannel(accessor.get(ILogService));
|
||||
electronIpcServer.registerChannel('logger', loggerChannel);
|
||||
sharedProcessClient.then(client => client.registerChannel('logger', loggerChannel));
|
||||
|
||||
// ExtensionHost Debug broadcast service
|
||||
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService);
|
||||
fileProtocolHandler.injectWindowsMainService(windowsMainService);
|
||||
|
||||
// ExtensionHost Debug broadcast service
|
||||
electronIpcServer.registerChannel(ExtensionHostDebugBroadcastChannel.ChannelName, new ElectronExtensionHostDebugBroadcastChannel(windowsMainService));
|
||||
|
||||
// Signal phase: ready (services set)
|
||||
@@ -590,29 +669,32 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
// Check for initial URLs to handle from protocol link invocations
|
||||
const pendingWindowOpenablesFromProtocolLinks: IWindowOpenable[] = [];
|
||||
const pendingProtocolLinksToHandle = coalesce([
|
||||
|
||||
const pendingProtocolLinksToHandle = [
|
||||
// Windows/Linux: protocol handler invokes CLI with --open-url
|
||||
...this.environmentService.args['open-url'] ? this.environmentService.args._urls || [] : [],
|
||||
|
||||
// macOS: open-url events
|
||||
...((<any>global).getOpenUrls() || []) as string[]
|
||||
].map(pendingUrlToHandle => {
|
||||
].map(url => {
|
||||
try {
|
||||
return URI.parse(pendingUrlToHandle);
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
return { uri: URI.parse(url), url };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
})).filter(pendingUriToHandle => {
|
||||
// if URI should be blocked, filter it out
|
||||
if (this.shouldBlockURI(pendingUriToHandle)) {
|
||||
}).filter((obj): obj is { uri: URI, url: string } => {
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// filter out any protocol link that wants to open as window so that
|
||||
// If URI should be blocked, filter it out
|
||||
if (this.shouldBlockURI(obj.uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filter out any protocol link that wants to open as window so that
|
||||
// we open the right set of windows on startup and not restore the
|
||||
// previous workspace too.
|
||||
const windowOpenable = this.getWindowOpenableFromProtocolLink(pendingUriToHandle);
|
||||
const windowOpenable = this.getWindowOpenableFromProtocolLink(obj.uri);
|
||||
if (windowOpenable) {
|
||||
pendingWindowOpenablesFromProtocolLinks.push(windowOpenable);
|
||||
|
||||
@@ -626,8 +708,9 @@ export class CodeApplication extends Disposable {
|
||||
const app = this;
|
||||
const environmentService = this.environmentService;
|
||||
urlService.registerHandler({
|
||||
async handleURL(uri: URI): Promise<boolean> {
|
||||
// if URI should be blocked, behave as if it's handled
|
||||
async handleURL(uri: URI, options?: IOpenURLOptions): Promise<boolean> {
|
||||
|
||||
// If URI should be blocked, behave as if it's handled
|
||||
if (app.shouldBlockURI(uri)) {
|
||||
return true;
|
||||
}
|
||||
@@ -657,7 +740,7 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
await window.ready();
|
||||
|
||||
return urlService.open(uri);
|
||||
return urlService.open(uri, options);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -665,7 +748,11 @@ export class CodeApplication extends Disposable {
|
||||
});
|
||||
|
||||
// Create a URL handler which forwards to the last active window
|
||||
const activeWindowManager = new ActiveWindowManager(electronMainService);
|
||||
const activeWindowManager = this._register(new ActiveWindowManager({
|
||||
onDidOpenWindow: nativeHostMainService.onDidOpenWindow,
|
||||
onDidFocusWindow: nativeHostMainService.onDidFocusWindow,
|
||||
getActiveWindowId: () => nativeHostMainService.getActiveWindowId(-1)
|
||||
}));
|
||||
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
|
||||
const urlHandlerRouter = new URLHandlerRouter(activeWindowRouter);
|
||||
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', urlHandlerRouter);
|
||||
@@ -677,7 +764,7 @@ export class CodeApplication extends Disposable {
|
||||
// Open our first window
|
||||
const args = this.environmentService.args;
|
||||
const macOpenFiles: string[] = (<any>global).macOpenFiles;
|
||||
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
|
||||
const context = isLaunchedFromCli(process.env) ? OpenContext.CLI : OpenContext.DESKTOP;
|
||||
const hasCliArgs = args._.length;
|
||||
const hasFolderURIs = !!args['folder-uri'];
|
||||
const hasFileURIs = !!args['file-uri'];
|
||||
@@ -697,8 +784,8 @@ export class CodeApplication extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
// new window if "-n" or "--remote" was used without paths
|
||||
if ((args['new-window'] || args.remote) && !hasCliArgs && !hasFolderURIs && !hasFileURIs) {
|
||||
// new window if "-n"
|
||||
if (args['new-window'] && !hasCliArgs && !hasFolderURIs && !hasFileURIs) {
|
||||
return windowsMainService.open({
|
||||
context,
|
||||
cli: args,
|
||||
@@ -823,12 +910,14 @@ export class CodeApplication extends Disposable {
|
||||
updateService.initialize();
|
||||
}
|
||||
|
||||
// Start to fetch shell environment (if needed) after window has opened
|
||||
resolveShellEnv(this.logService, this.environmentService.args, process.env);
|
||||
|
||||
// If enable-crash-reporter argv is undefined then this is a fresh start,
|
||||
// based on telemetry.enableCrashreporter settings, generate a UUID which
|
||||
// will be used as crash reporter id and also update the json file.
|
||||
try {
|
||||
const fileService = accessor.get(IFileService);
|
||||
const argvContent = await fileService.readFile(this.environmentService.argvResource);
|
||||
const argvContent = await this.fileService.readFile(this.environmentService.argvResource);
|
||||
const argvString = argvContent.value.toString();
|
||||
const argvJSON = JSON.parse(stripComments(argvString));
|
||||
if (argvJSON['enable-crash-reporter'] === undefined) {
|
||||
@@ -845,14 +934,11 @@ export class CodeApplication extends Disposable {
|
||||
'}'
|
||||
];
|
||||
const newArgvString = argvString.substring(0, argvString.length - 2).concat(',\n', additionalArgvContent.join('\n'));
|
||||
await fileService.writeFile(this.environmentService.argvResource, VSBuffer.fromString(newArgvString));
|
||||
await this.fileService.writeFile(this.environmentService.argvResource, VSBuffer.fromString(newArgvString));
|
||||
}
|
||||
} catch (error) {
|
||||
this.logService.error(error);
|
||||
}
|
||||
|
||||
// Start to fetch shell environment after window has opened
|
||||
getShellEnvironment(this.logService, this.environmentService);
|
||||
}
|
||||
|
||||
private handleRemoteAuthorities(): void {
|
||||
|
||||
Reference in New Issue
Block a user