Skip to content

Commit 0726e24

Browse files
committed
Run the .NET 6 build with dotnet OmniSharp.dll, rather than OmniSharp.exe. Support setting the path to the dotnet executable for this.
1 parent 00267a2 commit 0726e24

21 files changed

+244
-101
lines changed

package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,15 @@
906906
"scope": "machine",
907907
"description": "Specifies the path to a mono installation to use when \"useGlobalMono\" is set to \"always\", instead of the default system one. Example: \"/Library/Frameworks/Mono.framework/Versions/Current\""
908908
},
909+
"omnisharp.dotnetPath": {
910+
"type": [
911+
"string",
912+
"null"
913+
],
914+
"default": null,
915+
"scope": "window",
916+
"description": "Specified the path to a dotnet installation to use when \"useModernNet\" is set to true, instead of the default system one. Example: \"/home/username/mycustomdotnetdirectory\"."
917+
},
909918
"omnisharp.waitForDebugger": {
910919
"type": "boolean",
911920
"default": false,

src/constants/MonoInformation.ts renamed to src/constants/HostExecutableInformation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
export interface MonoInformation {
6+
export interface HostExecutableInformation {
77
version: string;
88
path: string;
99
env: NodeJS.ProcessEnv;

src/constants/IMonoResolver.ts renamed to src/constants/IHostExecutableResolver.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { Options } from "../omnisharp/options";
7-
import { MonoInformation } from "./MonoInformation";
7+
import { HostExecutableInformation } from "./HostExecutableInformation";
88

9-
export interface IMonoResolver {
10-
getGlobalMonoInfo(options: Options): Promise<MonoInformation>;
11-
}
9+
export interface IHostExecutableResolver {
10+
getHostExecutableInfo(options: Options): Promise<HostExecutableInformation>;
11+
}

src/features/commands.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ import { PlatformInformation } from '../platform';
1919
import CompositeDisposable from '../CompositeDisposable';
2020
import OptionProvider from '../observers/OptionProvider';
2121
import reportIssue from './reportIssue';
22-
import { IMonoResolver } from '../constants/IMonoResolver';
22+
import { IHostExecutableResolver } from '../constants/IHostExecutableResolver';
2323
import { getDotnetInfo } from '../utils/getDotnetInfo';
2424
import { getDecompilationAuthorization, resetDecompilationAuthorization } from '../omnisharp/decompilationPrompt';
2525

26-
export default function registerCommands(context: vscode.ExtensionContext, server: OmniSharpServer, platformInfo: PlatformInformation, eventStream: EventStream, optionProvider: OptionProvider, monoResolver: IMonoResolver, packageJSON: any, extensionPath: string): CompositeDisposable {
26+
export default function registerCommands(context: vscode.ExtensionContext, server: OmniSharpServer, platformInfo: PlatformInformation, eventStream: EventStream, optionProvider: OptionProvider, monoResolver: IHostExecutableResolver, packageJSON: any, extensionPath: string): CompositeDisposable {
2727
let disposable = new CompositeDisposable();
2828
disposable.add(vscode.commands.registerCommand('o.restart', async () => restartOmniSharp(context, server, optionProvider)));
2929
disposable.add(vscode.commands.registerCommand('o.pickProjectAndStart', async () => pickProjectAndStart(server, optionProvider)));

src/features/reportIssue.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import { CSharpExtensionId } from "../constants/CSharpExtensionId";
99
import { EventStream } from "../EventStream";
1010
import { OpenURL } from "../omnisharp/loggingEvents";
1111
import { Options } from "../omnisharp/options";
12-
import { IMonoResolver } from "../constants/IMonoResolver";
12+
import { IHostExecutableResolver } from "../constants/IHostExecutableResolver";
1313
import { IGetDotnetInfo } from "../constants/IGetDotnetInfo";
1414

1515
const issuesUrl = "https://github.com/OmniSharp/omnisharp-vscode/issues/new";
1616

17-
export default async function reportIssue(vscode: vscode, eventStream: EventStream, getDotnetInfo: IGetDotnetInfo, isValidPlatformForMono: boolean, options: Options, monoResolver: IMonoResolver) {
17+
export default async function reportIssue(vscode: vscode, eventStream: EventStream, getDotnetInfo: IGetDotnetInfo, isValidPlatformForMono: boolean, options: Options, monoResolver: IHostExecutableResolver) {
1818
const dotnetInfo = await getDotnetInfo();
1919
const monoInfo = await getMonoIfPlatformValid(isValidPlatformForMono, options, monoResolver);
2020
let extensions = getInstalledExtensions(vscode);
@@ -81,11 +81,11 @@ ${tableHeader}\n${table};
8181
return extensionTable;
8282
}
8383

84-
async function getMonoIfPlatformValid(isValidPlatformForMono: boolean, options: Options, monoResolver: IMonoResolver): Promise<string> {
84+
async function getMonoIfPlatformValid(isValidPlatformForMono: boolean, options: Options, monoResolver: IHostExecutableResolver): Promise<string> {
8585
if (isValidPlatformForMono) {
8686
let monoVersion: string;
8787
try {
88-
let globalMonoInfo = await monoResolver.getGlobalMonoInfo(options);
88+
let globalMonoInfo = await monoResolver.getHostExecutableInfo(options);
8989
if (globalMonoInfo) {
9090
monoVersion = `OmniSharp using global mono :${globalMonoInfo.version}`;
9191
}
@@ -116,4 +116,4 @@ function getInstalledExtensions(vscode: vscode) {
116116
function getCsharpExtensionVersion(vscode: vscode): string {
117117
const extension = vscode.extensions.getExtension(CSharpExtensionId);
118118
return extension.packageJSON.version;
119-
}
119+
}

src/observers/OmnisharpLoggerObserver.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ export class OmnisharpLoggerObserver extends BaseLoggerObserver {
5656

5757
private handleOmnisharpLaunch(event: OmnisharpLaunch) {
5858
this.logger.append(`OmniSharp server started`);
59-
if (event.monoVersion) {
60-
this.logger.append(` with Mono ${event.monoVersion}`);
61-
if (event.monoPath !== undefined) {
62-
this.logger.append(` (${event.monoPath})`);
59+
if (event.hostVersion) {
60+
this.logger.append(` with ${event.hostIsMono ? 'Mono' : '.NET'} ${event.hostVersion}`);
61+
if (event.hostPath !== undefined) {
62+
this.logger.append(` (${event.hostPath})`);
6363
}
6464
}
6565
this.logger.appendLine('.');
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { exec } from "child_process";
7+
import * as path from 'path';
8+
import { promisify } from "util";
9+
import { HostExecutableInformation } from "../constants/HostExecutableInformation";
10+
import { IHostExecutableResolver } from "../constants/IHostExecutableResolver";
11+
import { PlatformInformation } from "../platform";
12+
import { Options } from "./options";
13+
14+
const minimumDotnetMajor = 6;
15+
const minimumDotnetMinor = 0;
16+
const minimumDotnetPatch = 100;
17+
18+
export class OmniSharpDotnetResolver implements IHostExecutableResolver {
19+
20+
constructor(private platformInfo: PlatformInformation) { }
21+
22+
public async getHostExecutableInfo(options: Options): Promise<HostExecutableInformation> {
23+
const dotnet = this.platformInfo.isWindows() ? 'dotnet.exe' : 'dotnet';
24+
const env = { ...process.env };
25+
26+
if (options.dotnetPath) {
27+
env['PATH'] = options.dotnetPath + path.delimiter + env['PATH'];
28+
}
29+
30+
// Test the dotnet exe for version
31+
const result = await promisify(exec)(`${dotnet} --version`, { env });
32+
33+
if (result.stderr) {
34+
throw new Error(`Unable to read dotnet version information. Error ${result.stderr}`);
35+
}
36+
37+
const segments = result.stdout.split('.').map(str => Number.parseInt(str));
38+
if (segments.length != 3) {
39+
throw new Error(`Unknown result output from 'dotnet --version'. Received ${result.stdout}`);
40+
}
41+
42+
if (this.testVersionPart(segments[0], minimumDotnetMajor, result.stdout)
43+
|| this.testVersionPart(segments[1], minimumDotnetMinor, result.stdout)) {
44+
return {
45+
version: result.stdout,
46+
path: options.dotnetPath,
47+
env
48+
};
49+
}
50+
51+
this.testVersionPart(segments[2], minimumDotnetPatch, result.stdout);
52+
53+
return {
54+
version: result.stdout,
55+
path: options.dotnetPath,
56+
env
57+
};
58+
}
59+
60+
private testVersionPart(actualVersion: number, minimumRequired: number, foundVersion: string): boolean {
61+
if (actualVersion < minimumRequired) {
62+
throw new Error(`Found dotnet version ${foundVersion}. Minimum required version is ${minimumDotnetMajor}.${minimumDotnetMinor}.${minimumDotnetPatch}.`);
63+
}
64+
65+
return actualVersion === minimumRequired;
66+
}
67+
}

src/omnisharp/OmniSharpMonoResolver.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
import { satisfies } from 'semver';
77
import * as path from 'path';
88
import { Options } from './options';
9-
import { IMonoResolver } from '../constants/IMonoResolver';
10-
import { MonoInformation } from '../constants/MonoInformation';
9+
import { IHostExecutableResolver } from '../constants/IHostExecutableResolver';
10+
import { HostExecutableInformation } from '../constants/HostExecutableInformation';
1111
import { IGetMonoVersion } from '../constants/IGetMonoVersion';
1212

13-
export class OmniSharpMonoResolver implements IMonoResolver {
13+
export class OmniSharpMonoResolver implements IHostExecutableResolver {
1414
private minimumMonoVersion = "6.4.0";
1515

1616
constructor(private getMonoVersion: IGetMonoVersion) {
1717
}
1818

19-
private async configureEnvironmentAndGetInfo(options: Options): Promise<MonoInformation> {
19+
private async configureEnvironmentAndGetInfo(options: Options): Promise<HostExecutableInformation> {
2020
let env = { ...process.env };
2121
let monoPath: string;
2222
if (options.useGlobalMono !== "never" && options.monoPath !== undefined) {
@@ -34,7 +34,7 @@ export class OmniSharpMonoResolver implements IMonoResolver {
3434
};
3535
}
3636

37-
public async getGlobalMonoInfo(options: Options): Promise<MonoInformation> {
37+
public async getHostExecutableInfo(options: Options): Promise<HostExecutableInformation> {
3838
let monoInfo = await this.configureEnvironmentAndGetInfo(options);
3939
let isValid = monoInfo.version && satisfies(monoInfo.version, `>=${this.minimumMonoVersion}`);
4040
if (options.useGlobalMono === "always") {
@@ -45,7 +45,7 @@ export class OmniSharpMonoResolver implements IMonoResolver {
4545
: "Ensure that Mono's '/bin' folder is added to your environment's PATH variable.";
4646
throw new Error(`Unable to find Mono. ${suggestedAction}`);
4747
}
48-
48+
4949
if (!isValid) {
5050
throw new Error(`Found Mono version ${monoInfo.version}. Cannot start OmniSharp because Mono version >=${this.minimumMonoVersion} is required.`);
5151
}

src/omnisharp/OmnisharpManager.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import { PlatformInformation } from '../platform';
1111
import { modernNetVersion } from './OmnisharpPackageCreator';
1212

1313
export interface LaunchInfo {
14-
LaunchPath: string;
14+
LaunchPath?: string;
1515
MonoLaunchPath?: string;
16+
DotnetLaunchPath?: string;
1617
}
1718

1819
export class OmnisharpManager {
@@ -72,14 +73,14 @@ export class OmnisharpManager {
7273
}
7374

7475
private GetLaunchInfo(platformInfo: PlatformInformation, isFramework: boolean, basePath: string): LaunchInfo {
75-
if (platformInfo.isWindows()) {
76+
if (!isFramework) {
7677
return {
77-
LaunchPath: path.join(basePath, 'OmniSharp.exe')
78+
DotnetLaunchPath: path.join(basePath, 'OmniSharp.dll')
7879
};
7980
}
80-
else if (!isFramework) {
81+
else if (platformInfo.isWindows()) {
8182
return {
82-
LaunchPath: path.join(basePath, 'OmniSharp')
83+
LaunchPath: path.join(basePath, 'OmniSharp.exe')
8384
};
8485
}
8586

src/omnisharp/OmnisharpPackageCreator.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ export function GetPackagesFromVersion(version: string, useFramework: boolean, r
2424

2525
export function SetBinaryAndGetPackage(inputPackage: Package, useFramework: boolean, serverUrl: string, version: string, installPath: string): Package {
2626
let installBinary: string;
27-
if (inputPackage.platformId === "win-x86" || inputPackage.platformId === "win-x64") {
28-
installBinary = "OmniSharp.exe";
27+
if (!useFramework) {
28+
// .NET 6 packages use system `dotnet OmniSharp.dll`
29+
installBinary = 'OmniSharp.dll';
2930
}
30-
else if (!useFramework) {
31-
installBinary = 'OmniSharp';
31+
else if (inputPackage.platformId === 'win-x86' || inputPackage.platformId === 'win-x64' || inputPackage.platformId === 'win-arm64') {
32+
installBinary = 'OmniSharp.exe';
3233
}
3334
else {
34-
installBinary = "run";
35+
installBinary = 'run';
3536
}
3637

3738
return GetPackage(inputPackage, useFramework, serverUrl, version, installPath, installBinary);

0 commit comments

Comments
 (0)