Skip to content

Commit f23a0e3

Browse files
committed
Fix Mono detection and error handling for .NET Framework projects
- Enhanced .NET Framework project detection to check solution file for VisualStudioVersion - Fixed project file path resolution to handle Windows backslashes on Unix systems - Added empty list checks in PosixMsbuildResolver to prevent .first() errors when Mono is not installed - Improved error messages when Mono is required but not found - Gracefully handle Mono detection failures on macOS/Ubuntu when Mono is not installed
1 parent b81de4e commit f23a0e3

File tree

5 files changed

+408
-28
lines changed

5 files changed

+408
-28
lines changed

src/main/dotnet/ProjectFileParser/MSBuildCustomLocator.cs

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Microsoft.Build.Locator;
22
using System;
3+
using System.IO;
34
using System.Linq;
5+
using System.Runtime.InteropServices;
46

57
namespace ProjectFileParser
68
{
@@ -16,21 +18,90 @@ public static void Register()
1618
var latestVsVersion = versions.Last();
1719
MSBuildLocator.RegisterInstance(latestVsVersion);
1820
Console.Error.WriteLine($"Registered latest VS Instance: {latestVsVersion.Name} - {latestVsVersion.Version} - {latestVsVersion.MSBuildPath} - {latestVsVersion.DiscoveryType} - {latestVsVersion.VisualStudioRootPath}");
21+
return;
22+
}
23+
}
24+
catch (Exception ex)
25+
{
26+
Console.Error.WriteLine($"MSBuildLocator.QueryVisualStudioInstances() failed: {ex.Message}");
27+
}
28+
29+
// No Visual Studio found - try to find .NET SDK MSBuild
30+
try
31+
{
32+
var dotnetSdkMsbuildPath = FindDotnetSdkMsbuild();
33+
if (dotnetSdkMsbuildPath != null && Directory.Exists(dotnetSdkMsbuildPath))
34+
{
35+
// Create a VisualStudioInstance manually for .NET SDK
36+
// Note: This is a workaround - MSBuildLocator might not support this directly
37+
Console.Error.WriteLine($"Found .NET SDK MSBuild at: {dotnetSdkMsbuildPath}");
38+
Console.Error.WriteLine("Note: MSBuildLocator registration may not be needed for .NET SDK MSBuild");
39+
// The assemblies should be available via NuGet package references now
1940
}
2041
else
2142
{
22-
// No Visual Studio found (e.g., on Linux with dotnet SDK only)
23-
// This is OK - dotnet msbuild doesn't require MSBuildLocator
24-
Console.Error.WriteLine("No Visual Studio instances found. Using dotnet msbuild (no registration needed).");
43+
Console.Error.WriteLine("No Visual Studio instances found and could not locate .NET SDK MSBuild.");
44+
Console.Error.WriteLine("Microsoft.Build assemblies should be available via NuGet package references.");
2545
}
2646
}
2747
catch (Exception ex)
2848
{
29-
// On Linux or when VS is not installed, this is expected
30-
// dotnet msbuild works without MSBuildLocator registration
31-
Console.Error.WriteLine("MSBuildLocator cannot detect VS location (this is OK on Linux with dotnet SDK)");
32-
Console.Error.WriteLine("Error was: {0}", ex);
49+
Console.Error.WriteLine($"Error finding .NET SDK MSBuild: {ex.Message}");
50+
Console.Error.WriteLine("Microsoft.Build assemblies should be available via NuGet package references.");
51+
}
52+
}
53+
54+
private static string FindDotnetSdkMsbuild()
55+
{
56+
try
57+
{
58+
// Try to get dotnet SDK path from environment or common locations
59+
var dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
60+
if (string.IsNullOrEmpty(dotnetRoot))
61+
{
62+
// Try common locations
63+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
64+
{
65+
var commonPaths = new[] { "/usr/share/dotnet", "/usr/local/share/dotnet",
66+
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".dotnet") };
67+
foreach (var path in commonPaths)
68+
{
69+
if (Directory.Exists(path))
70+
{
71+
dotnetRoot = path;
72+
break;
73+
}
74+
}
75+
}
76+
}
77+
78+
if (!string.IsNullOrEmpty(dotnetRoot))
79+
{
80+
var sdkPath = Path.Combine(dotnetRoot, "sdk");
81+
if (Directory.Exists(sdkPath))
82+
{
83+
// Find the highest SDK version
84+
var sdkVersions = Directory.GetDirectories(sdkPath)
85+
.Where(d => System.Text.RegularExpressions.Regex.IsMatch(Path.GetFileName(d), @"^\d+\.\d+\.\d+"))
86+
.OrderByDescending(d => new Version(Path.GetFileName(d).Split('-')[0]))
87+
.FirstOrDefault();
88+
89+
if (sdkVersions != null)
90+
{
91+
var msbuildPath = Path.Combine(sdkVersions, "MSBuild", "Current", "Bin");
92+
if (Directory.Exists(msbuildPath))
93+
{
94+
return msbuildPath;
95+
}
96+
}
97+
}
98+
}
99+
}
100+
catch
101+
{
102+
// Ignore errors
33103
}
104+
return null;
34105
}
35106
}
36107
}

src/main/dotnet/ProjectFileParser/ProjectFileParser.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
</PropertyGroup>
2121
<PropertyGroup>
2222
<StartupObject>ProjectFileParser.Program</StartupObject>
23+
<DisableMSBuildAssemblyCopyCheck>true</DisableMSBuildAssemblyCopyCheck>
2324
</PropertyGroup>
2425
<ItemGroup>
25-
<PackageReference Include="Microsoft.Build" Version="17.3.2" ExcludeAssets="runtime" />
26+
<PackageReference Include="Microsoft.Build" Version="17.3.2" />
2627
<PackageReference Include="Microsoft.Build.Locator" Version="1.6.10" />
2728
</ItemGroup>
2829
</Project>

0 commit comments

Comments
 (0)