@@ -14,7 +14,8 @@ import { existsSync } from 'fs';
1414import { CSharpExtensionId } from '../constants/csharpExtensionId' ;
1515import { promisify } from 'util' ;
1616import { exec } from 'child_process' ;
17- import { pathExistsSync } from 'fs-extra' ;
17+ import { getDotnetInfo } from '../shared/utils/getDotnetInfo' ;
18+ import { readFile } from 'fs/promises' ;
1819
1920export const DotNetRuntimeVersion = '7.0' ;
2021
@@ -33,7 +34,8 @@ export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
3334 * This is a function instead of a string because the server path can change while the extension is active (when the option changes).
3435 */
3536 private getServerPath : ( options : Options , platform : PlatformInformation ) => string ,
36- private channel : vscode . OutputChannel
37+ private channel : vscode . OutputChannel ,
38+ private extensionPath : string
3739 ) { }
3840
3941 private hostInfo : HostExecutableInformation | undefined ;
@@ -129,16 +131,23 @@ export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
129131 */
130132 private async findDotnetFromPath ( ) : Promise < string | undefined > {
131133 try {
132- // Run dotnet version to see if there is a valid dotnet on the path with a high enough version.
133- const result = await promisify ( exec ) ( `dotnet --version` ) ;
134+ const dotnetInfo = await getDotnetInfo ( [ ] ) ;
135+ const dotnetVersionStr = dotnetInfo . Version ;
134136
135- if ( result . stderr ) {
136- throw new Error ( `Unable to read dotnet version information. Error ${ result . stderr } ` ) ;
137+ const extensionArchitecture = await this . getArchitectureFromTargetPlatform ( ) ;
138+ const dotnetArchitecture = dotnetInfo . Architecture ;
139+
140+ // If the extension arhcitecture is defined, we check that it matches the dotnet architecture.
141+ // If its undefined we likely have a platform neutral server and assume it can run on any architecture.
142+ if ( extensionArchitecture && extensionArchitecture !== dotnetArchitecture ) {
143+ throw new Error (
144+ `The architecture of the .NET runtime (${ dotnetArchitecture } ) does not match the architecture of the extension (${ extensionArchitecture } ).`
145+ ) ;
137146 }
138147
139- const dotnetVersion = semver . parse ( result . stdout . trimEnd ( ) ) ;
148+ const dotnetVersion = semver . parse ( dotnetVersionStr ) ;
140149 if ( ! dotnetVersion ) {
141- throw new Error ( `Unknown result output from 'dotnet --version'. Received ${ result . stdout } ` ) ;
150+ throw new Error ( `Unknown result output from 'dotnet --version'. Received ${ dotnetVersionStr } ` ) ;
142151 }
143152
144153 if ( semver . lt ( dotnetVersion , this . minimumDotnetVersion ) ) {
@@ -155,7 +164,7 @@ export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
155164 }
156165
157166 const path = whereOutput . stdout . trim ( ) ;
158- if ( ! pathExistsSync ( path ) ) {
167+ if ( ! existsSync ( path ) ) {
159168 throw new Error ( `dotnet path does not exist: ${ path } ` ) ;
160169 }
161170
@@ -172,4 +181,45 @@ export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
172181
173182 return undefined ;
174183 }
184+
185+ private async getArchitectureFromTargetPlatform ( ) : Promise < string | undefined > {
186+ const vsixManifestFile = path . join ( this . extensionPath , '.vsixmanifest' ) ;
187+ if ( ! existsSync ( vsixManifestFile ) ) {
188+ // This is not an error as normal development F5 builds do not generate a .vsixmanifest file.
189+ this . channel . appendLine (
190+ `Unable to find extension target platform - no vsix manifest file exists at ${ vsixManifestFile } `
191+ ) ;
192+ return undefined ;
193+ }
194+
195+ const contents = await readFile ( vsixManifestFile , 'utf-8' ) ;
196+ const targetPlatformMatch = / T a r g e t P l a t f o r m = " ( .* ) " / . exec ( contents ) ;
197+ if ( ! targetPlatformMatch ) {
198+ throw new Error ( `Could not find extension target platform in ${ vsixManifestFile } ` ) ;
199+ }
200+
201+ const targetPlatform = targetPlatformMatch [ 1 ] ;
202+
203+ // The currently known extension platforms are taken from here:
204+ // https://code.visualstudio.com/api/working-with-extensions/publishing-extension#platformspecific-extensions
205+ switch ( targetPlatform ) {
206+ case 'win32-x64' :
207+ case 'linux-x64' :
208+ case 'alpine-x64' :
209+ case 'darwin-x64' :
210+ return 'x64' ;
211+ case 'win32-ia32' :
212+ return 'x86' ;
213+ case 'win32-arm64' :
214+ case 'linux-arm64' :
215+ case 'alpine-arm64' :
216+ case 'darwin-arm64' :
217+ return 'arm64' ;
218+ case 'linux-armhf' :
219+ case 'web' :
220+ return undefined ;
221+ default :
222+ throw new Error ( `Unknown extension target platform: ${ targetPlatform } ` ) ;
223+ }
224+ }
175225}
0 commit comments