Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I use Microsoft.Build within my app to load a project? #2839

Open
firelizzard18 opened this issue Jan 4, 2018 · 4 comments
Open

How do I use Microsoft.Build within my app to load a project? #2839

firelizzard18 opened this issue Jan 4, 2018 · 4 comments
Labels

Comments

@firelizzard18
Copy link

I want to use the Microsoft.Build nuget package in a .NET Core app to load a project file. I do not have Visual Studio installed. I am only using the dotnet cli.

Steps to reproduce

Project file

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Build" Version="15.5.180" />
  </ItemGroup>

</Project>

Directory contents:

/
- my-app.csproj
- Program.cs

Program.cs:

using System;
using System.IO;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Construction;
 
class Program
{
    static void Main(string[] args)
    {
        if (args.Length != 1)
        {
            Console.WriteLine("Usage: dotnet behave <project>");
            return;
        }
 
        var proj = new Project(Path.GetFullPath(args[0]));
        
        Console.WriteLine(proj);
    }
}

Command line

dotnet run ../other/other.csproj

Expected behavior

I can load the CS project file

Actual behavior

Initially:

Unhandled Exception: Microsoft.Build.Exceptions.InvalidProjectFileException: The SDK 'Microsoft.NET.Sdk' specified could not be found.  /path/to/other/other.csproj
   at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args) in E:\A\_work\17\s\src\Shared\ProjectErrorUtilities.cs:line 440
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(String directoryOfImportingFile, ProjectImportElement importElement, List`1& projects, Boolean throwOnFileNotExistsError) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2412
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImports(String directoryOfImportingFile, ProjectImportElement importElement) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2215
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2070
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 1006
   at Microsoft.Build.Evaluation.Evaluator`4.Evaluate(ILoggingService loggingService, BuildEventContext buildEventContext) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 794
   at Microsoft.Build.Evaluation.Project.Reevaluate(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 2641
   at Microsoft.Build.Evaluation.Project.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 2634
   at Microsoft.Build.Evaluation.Project.Initialize(IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 2711
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 512
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 410
   at Program.Main(String[] args) in /path/to/my-app/Program.cs:line 16

After setting MSBuildSDKsPath=/usr/local/share/dotnet/sdk/2.1.3/Sdks and MSBuildExtensionsPath=/usr/local/share/dotnet/sdk/2.1.3:

Unhandled Exception: Microsoft.Build.Exceptions.InvalidProjectFileException: The imported project "/path/to/my-app/bin/Debug/netcoreapp2.0/Microsoft.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.  /usr/local/share/dotnet/sdk/2.0.0/Sdks/Microsoft.NET.Sdk/Sdk/Sdk.targets
   at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args) in E:\A\_work\17\s\src\Shared\ProjectErrorUtilities.cs:line 440
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImportsFromUnescapedImportExpression(String directoryOfImportingFile, ProjectImportElement importElement, StringunescapedExpression, Boolean throwOnFileNotExistsError, List`1& imports) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2641
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(String directoryOfImportingFile, ProjectImportElement importElement, List`1& projects, Boolean throwOnFileNotExistsError) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2422
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImports(String directoryOfImportingFile, ProjectImportElement importElement) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2215
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2070
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 1109
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 2070
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 1175
   at Microsoft.Build.Evaluation.Evaluator`4.Evaluate(ILoggingService loggingService, BuildEventContext buildEventContext) in E:\A\_work\17\s\src\Build\Evaluation\Evaluator.cs:line 794
   at Microsoft.Build.Evaluation.Project.Reevaluate(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 2641
   at Microsoft.Build.Evaluation.Project.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 2634
   at Microsoft.Build.Evaluation.Project.Initialize(IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 2711
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings) in E:\A\_work\17\s\src\Build\Definition\Project.cs:line 512
   at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName, IDictionary`2 globalProperties, String toolsVersion) in E:\A\_work\17\s\src\Build\Definition\ProjectCollection.cs:line 1122
   at MSBuildDumper.Main(String[] args) in /path/to/my-app/Program.cs:line 18

Environment data

dotnet --version: 2.1.3

OS info: Mac

@mfilippov
Copy link
Contributor

@firelizzard18 You should set own SDK resolver or use https://github.com/Microsoft/msbuild/blob/497d797007410f43e1d7501b7d8254313b07b2a7/src/Build/BackEnd/Components/SdkResolution/DefaultSdkResolver.cs and put Sdk into correctly place. Also you can use SDK resolver from .NET CLI.

@firelizzard18
Copy link
Author

How would I set my own resolver? Looking through the source of Microsoft.Build.Evaluation.Project, I can find no way to alter how it resolves SDKs.

@dazinator
Copy link

dazinator commented Mar 20, 2018

I am having a similar problem, I am using 15.6.82 and attempting to load a project file that leverages an SDK.

My project file looks like this:

<Project Sdk="Foo.Sdk/0.0.1-alpha0001">
</Project>

Note: As per #2803 I have specified the package version hoping this will light up the nuget sdk resolver.

In the parent directory of this project file, I have a Nuget.config file that looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <packageSources> 
    <add key="local-packages" value="local-packages" />   
    <add key="msbuild" value="https://dotnet.myget.org/F/msbuild/api/v3/index.json" />      
  </packageSources>
</configuration>

In the "local-packages" folder I have the nuget package containing the SDK that I am wanting to be resolved.

The message I get when I try to load this project

Message: Microsoft.Build.Exceptions.InvalidProjectFileException : The SDK 'Foo.Sdk' specified could not be found. E:\Repos\Foo\src\Foo\TestFoo\AddsTargetAssembly.xml

The stack trace:

Result StackTrace:
at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args)
at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject[T1](IElementLocation elementLocation, String resourceName, T1 arg0)
at Microsoft.Build.Evaluation.Evaluator4.ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(String directoryOfImportingFile, ProjectImportElement importElement, List1& projects, Boolean throwOnFileNotExistsError)
at Microsoft.Build.Evaluation.Evaluator4.ExpandAndLoadImports(String directoryOfImportingFile, ProjectImportElement importElement) at Microsoft.Build.Evaluation.Evaluator4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.Evaluate(ILoggingService loggingService, BuildEventContext buildEventContext)
at Microsoft.Build.Evaluation.Evaluator4.Evaluate(IEvaluatorData4 data, ProjectRootElement root, ProjectLoadSettings loadSettings, Int32 maxNodeCount, PropertyDictionary1 environmentProperties, ILoggingService loggingService, IItemFactory2 itemFactory, IToolsetProvider toolsetProvider, ProjectRootElementCache projectRootElementCache, BuildEventContext buildEventContext, ProjectInstance projectInstanceIfAnyForDebuggerOnly, ISdkResolverService sdkResolverService, Int32 submissionId)
at Microsoft.Build.Evaluation.Project.Reevaluate(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings)
at Microsoft.Build.Evaluation.Project.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings)
at Microsoft.Build.Evaluation.Project.Initialize(IDictionary2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings) at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings)
at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName, IDictionary`2 globalProperties, String toolsVersion)
at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName)

I set the following environment variables at runtime before attempting to load the project using msbuild:

  • VSINSTALLDIR = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community";
  • VisualStudioVersion = "15.0";
  • MSBuildSDKsPath = @"C:\Program Files\dotnet\sdk\2.1.100\Sdks";

What gives?

@dazinator
Copy link

I am not sure what has changed, but this has started working for me today. The nuget based sdk resolver suddenly finds and restored my sdk package. The only thing I can think of is either that a recent VS upgrade fixed it, or perhaps it was related to nuget cache.

@AR-May AR-May added the triaged label Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants