Skip to content
This repository was archived by the owner on Dec 6, 2022. It is now read-only.

Commit fec31d5

Browse files
committed
Call host to launch Chrome unelevated if
host sends supportsLaunchUnelevatedProcessRequest flag.
1 parent 4c0aa81 commit fec31d5

1 file changed

Lines changed: 53 additions & 18 deletions

File tree

src/chromeDebugAdapter.ts

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,20 @@ const DefaultWebSourceMapPathOverrides: ISourceMapPathOverrides = {
2828
'meteor://💻app/*': '${webRoot}/*'
2929
};
3030

31+
interface IExtendedInitializeRequestArguments extends DebugProtocol.InitializeRequestArguments{
32+
supportsLaunchUnelevatedProcessRequest?: boolean
33+
}
34+
3135
export class ChromeDebugAdapter extends CoreDebugAdapter {
3236
private _pagePauseMessage = 'Paused in Visual Studio Code';
3337

3438
private _chromeProc: ChildProcess;
3539
private _overlayHelper: utils.DebounceHelper;
3640
private _chromePID: number;
3741
private _userRequestedUrl: string;
42+
private _doesHostSupportLaunchUnelevatedProcessRequest: boolean;
3843

39-
public initialize(args: DebugProtocol.InitializeRequestArguments): VSDebugProtocolCapabilities {
44+
public initialize(args: IExtendedInitializeRequestArguments): VSDebugProtocolCapabilities {
4045
this._overlayHelper = new utils.DebounceHelper(/*timeoutMs=*/200);
4146
const capabilities: VSDebugProtocolCapabilities = super.initialize(args);
4247
capabilities.supportsRestartRequest = true;
@@ -47,6 +52,8 @@ export class ChromeDebugAdapter extends CoreDebugAdapter {
4752
localize = nls.config({ locale: args.locale })();
4853
}
4954

55+
this._doesHostSupportLaunchUnelevatedProcessRequest = args.supportsLaunchUnelevatedProcessRequest || false;
56+
5057
return capabilities;
5158
}
5259

@@ -353,26 +360,15 @@ export class ChromeDebugAdapter extends CoreDebugAdapter {
353360
this.events.emitStepStarted('LaunchTarget.LaunchExe');
354361
const platform = coreUtils.getPlatform();
355362
if (platform === coreUtils.Platform.Windows && shouldLaunchUnelevated) {
356-
const semaphoreFile = path.join(os.tmpdir(), 'launchedUnelevatedChromeProcess.id');
357-
if (fs.existsSync(semaphoreFile)) { // remove the previous semaphoreFile if it exists.
358-
fs.unlinkSync(semaphoreFile);
359-
}
360-
const chromeProc = fork(getChromeSpawnHelperPath(),
361-
[`${process.env.windir}\\System32\\cscript.exe`, path.join(__dirname, 'launchUnelevated.js'),
362-
semaphoreFile, chromePath, ...chromeArgs], {});
363-
364-
chromeProc.unref();
365-
await new Promise<void>((resolve, reject) => {
366-
chromeProc.on('message', resolve);
367-
});
368-
369-
const pidStr = await findNewlyLaunchedChromeProcess(semaphoreFile);
363+
let chromePid: number;
370364

371-
if (pidStr) {
372-
logger.log(`Parsed output file and got Chrome PID ${pidStr}`);
373-
this._chromePID = parseInt(pidStr, 10);
365+
if (this._doesHostSupportLaunchUnelevatedProcessRequest) {
366+
chromePid = await this.spawnChromeUnelevatedWithClient(chromePath, chromeArgs);
367+
} else {
368+
chromePid = await this.spawnChromeUnelevatedWithWindowsScriptHost(chromePath, chromeArgs);
374369
}
375370

371+
this._chromePID = chromePid;
376372
// Cannot get the real Chrome process, so return null.
377373
return null;
378374
} else if (platform === coreUtils.Platform.Windows && !usingRuntimeExecutable) {
@@ -433,6 +429,45 @@ export class ChromeDebugAdapter extends CoreDebugAdapter {
433429
}
434430
}
435431

432+
private async spawnChromeUnelevatedWithWindowsScriptHost(chromePath: string, chromeArgs: string[]): Promise<number> {
433+
const semaphoreFile = path.join(os.tmpdir(), 'launchedUnelevatedChromeProcess.id');
434+
if (fs.existsSync(semaphoreFile)) { // remove the previous semaphoreFile if it exists.
435+
fs.unlinkSync(semaphoreFile);
436+
}
437+
const chromeProc = fork(getChromeSpawnHelperPath(),
438+
[`${process.env.windir}\\System32\\cscript.exe`, path.join(__dirname, 'launchUnelevated.js'),
439+
semaphoreFile, chromePath, ...chromeArgs], {});
440+
441+
chromeProc.unref();
442+
await new Promise<void>((resolve, reject) => {
443+
chromeProc.on('message', resolve);
444+
});
445+
446+
const pidStr = await findNewlyLaunchedChromeProcess(semaphoreFile);
447+
448+
if (pidStr) {
449+
logger.log(`Parsed output file and got Chrome PID ${pidStr}`);
450+
return parseInt(pidStr, 10);
451+
}
452+
453+
return null
454+
}
455+
456+
private async spawnChromeUnelevatedWithClient(chromePath: string, chromeArgs: string[]): Promise<number> {
457+
return new Promise<number>((resolve, reject) => {
458+
this._session.sendRequest("launchUnelevated", {
459+
"process": chromePath,
460+
"args": chromeArgs
461+
}, 10000, (response) => {
462+
if (!response.success) {
463+
reject(new Error(response.message));
464+
} else {
465+
resolve(response.body.processId);
466+
}
467+
});
468+
});
469+
}
470+
436471
public async setExpression(args: ISetExpressionArgs): Promise<ISetExpressionResponseBody> {
437472
const reconstructedExpression = `${args.expression} = ${args.value}`;
438473
const evaluateEventArgs: DebugProtocol.EvaluateArguments = {

0 commit comments

Comments
 (0)