Skip to content

Commit 27c5cd1

Browse files
committed
Allow rzls to launch using standard dotnet (Redo)
- Updates where to pick up dotnet.exe. - Contributes to making rzls move away from being self-contained. - Unifies how roslyn and razor servers acquire dotnet path/env variables. - Picks up leftover changes from #5855 into main
1 parent 26d9328 commit 27c5cd1

File tree

4 files changed

+32
-49
lines changed

4 files changed

+32
-49
lines changed

src/lsptoolshost/dotnetRuntimeExtensionResolver.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as semver from 'semver';
99
import { HostExecutableInformation } from '../shared/constants/hostExecutableInformation';
1010
import { IHostExecutableResolver } from '../shared/constants/IHostExecutableResolver';
1111
import { PlatformInformation } from '../shared/platform';
12-
import { commonOptions } from '../shared/options';
12+
import { commonOptions, languageServerOptions } from '../shared/options';
1313
import { existsSync } from 'fs';
1414
import { CSharpExtensionId } from '../constants/csharpExtensionId';
1515
import { getDotnetInfo } from '../shared/utils/getDotnetInfo';
@@ -67,6 +67,25 @@ export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
6767
throw new Error(`Cannot find dotnet path '${dotnetExecutablePath}'`);
6868
}
6969

70+
// Take care to always run .NET processes on the runtime that we intend.
71+
// The dotnet.exe we point to should not go looking for other runtimes.
72+
const env: NodeJS.ProcessEnv = { ...process.env };
73+
env.DOTNET_ROOT = path.dirname(dotnetExecutablePath);
74+
env.DOTNET_MULTILEVEL_LOOKUP = '0';
75+
// Save user's DOTNET_ROOT env-var value so server can recover the user setting when needed
76+
env.DOTNET_ROOT_USER = process.env.DOTNET_ROOT ?? 'EMPTY';
77+
78+
if (languageServerOptions.crashDumpPath) {
79+
// Enable dump collection
80+
env.DOTNET_DbgEnableMiniDump = '1';
81+
// Collect heap dump
82+
env.DOTNET_DbgMiniDumpType = '2';
83+
// Collect crashreport.json with additional thread and stack frame information.
84+
env.DOTNET_EnableCrashReport = '1';
85+
// The dump file name format is <executable>.<pid>.dmp
86+
env.DOTNET_DbgMiniDumpName = path.join(languageServerOptions.crashDumpPath, '%e.%p.dmp');
87+
}
88+
7089
return {
7190
version: '' /* We don't need to know the version - we've already downloaded the correct one */,
7291
path: dotnetExecutablePath,

src/lsptoolshost/roslynLanguageServer.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -491,30 +491,10 @@ export class RoslynLanguageServer {
491491
const serverPath = getServerPath(platformInfo);
492492

493493
const dotnetInfo = await hostExecutableResolver.getHostExecutableInfo();
494-
const dotnetRuntimePath = path.dirname(dotnetInfo.path);
495494
const dotnetExecutablePath = dotnetInfo.path;
496495

497496
_channel.appendLine('Dotnet path: ' + dotnetExecutablePath);
498497

499-
// Take care to always run .NET processes on the runtime that we intend.
500-
// The dotnet.exe we point to should not go looking for other runtimes.
501-
const env: NodeJS.ProcessEnv = { ...process.env };
502-
env.DOTNET_ROOT = dotnetRuntimePath;
503-
env.DOTNET_MULTILEVEL_LOOKUP = '0';
504-
// Save user's DOTNET_ROOT env-var value so server can recover the user setting when needed
505-
env.DOTNET_ROOT_USER = process.env.DOTNET_ROOT ?? 'EMPTY';
506-
507-
if (languageServerOptions.crashDumpPath) {
508-
// Enable dump collection
509-
env.DOTNET_DbgEnableMiniDump = '1';
510-
// Collect heap dump
511-
env.DOTNET_DbgMiniDumpType = '2';
512-
// Collect crashreport.json with additional thread and stack frame information.
513-
env.DOTNET_EnableCrashReport = '1';
514-
// The dump file name format is <executable>.<pid>.dmp
515-
env.DOTNET_DbgMiniDumpName = path.join(languageServerOptions.crashDumpPath, '%e.%p.dmp');
516-
}
517-
518498
let args: string[] = [];
519499

520500
if (commonOptions.waitForDebugger) {
@@ -557,7 +537,7 @@ export class RoslynLanguageServer {
557537
const csharpDevKitArgs = this.getCSharpDevKitExportArgs();
558538
args = args.concat(csharpDevKitArgs);
559539

560-
await this.setupDevKitEnvironment(env, csharpDevkitExtension);
540+
await this.setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension);
561541
} else {
562542
// C# Dev Kit is not installed - continue C#-only activation.
563543
_channel.appendLine('Activating C# standalone...');
@@ -580,7 +560,7 @@ export class RoslynLanguageServer {
580560
const cpOptions: cp.SpawnOptionsWithoutStdio = {
581561
detached: true,
582562
windowsHide: true,
583-
env: env,
563+
env: dotnetInfo.env,
584564
};
585565

586566
if (serverPath.endsWith('.dll')) {

src/razor/src/extension.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,11 @@ export async function activate(
9090
);
9191

9292
const dotnetInfo = await hostExecutableResolver.getHostExecutableInfo();
93-
const dotnetRuntimePath = path.dirname(dotnetInfo.path);
94-
95-
// Take care to always run .NET processes on the runtime that we intend.
96-
// The dotnet.exe we point to should not go looking for other runtimes.
97-
const env: NodeJS.ProcessEnv = { ...process.env };
98-
env.DOTNET_ROOT = dotnetRuntimePath;
99-
env.DOTNET_MULTILEVEL_LOOKUP = '0';
100-
// Save user's DOTNET_ROOT env-var value so server can recover the user setting when needed
101-
env.DOTNET_ROOT_USER = process.env.DOTNET_ROOT ?? 'EMPTY';
10293

10394
let telemetryExtensionDllPath = '';
10495
// Set up DevKit environment for telemetry
10596
if (csharpDevkitExtension) {
106-
await setupDevKitEnvironment(env, csharpDevkitExtension, logger);
97+
await setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension, logger);
10798

10899
const telemetryExtensionPath = path.join(
109100
util.getExtensionPath(),
@@ -121,7 +112,7 @@ export async function activate(
121112
razorTelemetryReporter,
122113
vscodeTelemetryReporter,
123114
telemetryExtensionDllPath,
124-
env,
115+
dotnetInfo.env,
125116
dotnetInfo.path,
126117
logger
127118
);

src/razor/src/razorLanguageServerOptionsResolver.ts

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import * as fs from 'fs';
77
import * as os from 'os';
88
import * as path from 'path';
99
import * as vscodeAdapter from './vscodeAdapter';
10-
import * as vscode from 'vscode';
1110
import { RazorLanguageServerOptions } from './razorLanguageServerOptions';
1211
import { RazorLogger } from './razorLogger';
1312
import { LogLevel } from './logLevel';
@@ -35,23 +34,17 @@ export function resolveRazorLanguageServerOptions(
3534
}
3635

3736
function findLanguageServerExecutable(withinDir: string) {
38-
const extension = isWindows() ? '.exe' : '';
39-
const executablePath = path.join(withinDir, `rzls${extension}`);
37+
const isSelfContained = fs.existsSync(path.join(withinDir, 'coreclr.dll'));
4038
let fullPath = '';
41-
42-
if (fs.existsSync(executablePath)) {
43-
fullPath = executablePath;
39+
if (isSelfContained) {
40+
const fileName = isWindows() ? 'rzls.exe' : 'rzls';
41+
fullPath = path.join(withinDir, fileName);
4442
} else {
45-
// Exe doesn't exist.
46-
const dllPath = path.join(withinDir, 'rzls.dll');
47-
48-
if (!fs.existsSync(dllPath)) {
49-
throw new Error(
50-
vscode.l10n.t("Could not find Razor Language Server executable within directory '{0}'", withinDir)
51-
);
52-
}
43+
fullPath = path.join(withinDir, 'rzls.dll');
44+
}
5345

54-
fullPath = dllPath;
46+
if (!fs.existsSync(fullPath)) {
47+
throw new Error(`Could not find Razor Language Server executable within directory '${withinDir}'`);
5548
}
5649

5750
return fullPath;

0 commit comments

Comments
 (0)