在c#中使用ProjectCollection.LoadProject方法时出错

问题描述 投票:0回答:2

我正在尝试加载一个项目并构建它,但是每次我尝试加载它时都会抛出此错误:

Microsoft.Build.Exceptions.InvalidProjectFileException: 'The default XML namespace of the project must be the MSBuild XML namespace. If the project is authored in the MSBuild 2003 format, please add xmlns="http://schemas.microsoft.com/developer/msbuild/2003" to the <Project> element. If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format.  C:\Users\mega\source\repos\Logger Builder\Logger Builder\bin\Debug\net472\git\discord-token-logger-zip\logger\logger.csproj'

目标项目文件如下所示: .csproj

我的代码是:

            var collection = new ProjectCollection();

            var project = collection.LoadProject(@"./git\logger-zip\logger\logger.csproj");
        
            project.Build();
c# .net msbuild
2个回答
0
投票

.Net Framework 项目通常使用“遗留”项目样式。 (在 Visual Studio 2022 中,创建新的 .Net Framework 项目将创建旧样式项目。)

旧式项目需要在

Project
元素上使用特定的命名空间:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ...>

您尝试加载的项目是“SDK”样式的项目。在 SDK 风格的项目中,命名空间是可选的。

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

SDK 风格于 2017 年左右引入,以支持 .Net Core/.Net 5 及更高版本。

我的猜测是,包含失败的

collection.LoadProject()
调用的项目正在使用本地安装的 .Net Framework 版本的 Microsoft.Build 程序集,该版本可能是 4.0.0.0。该版本早于 SDK 样式项目格式的创建。 (MSBuild 4 大约是 2010 年。)

如果您使用的是旧库,请将其替换为 Microsoft.Build NuGet 包。


0
投票

查看Roslyn如何加载解决方案和项目,我发现这可能是因为您没有事先设置这些环境变量:

  • MSBUILD_EXE_PATH
  • MSBuildExtensionsPath
  • MSBuildSDKs路径

如果您尝试加载 Microsoft.NET.Sdk.* 类型项目,您可以尝试使用

MSBuildLocator
包中的
Microsoft.Build.Locator
类来确定这些环境变量的值。

以下代码从您最新的 Visual Studio 版本中提取它们。

using Microsoft.Build.Construction; // Package: Microsoft.Build
using Microsoft.Build.Evaluation;   // Package: Microsoft.Build
using Microsoft.Build.Locator;      // Package: Microsoft.Build.Locator

var solutionFilePath = @"PATH TO YOUR SOLUTION FILE";

if (!MSBuildLocator.IsRegistered)
{
    // Locate the right SDK for this particular project; MSBuildLocator ensures in this case the first one is the preferred one.
    var options = new VisualStudioInstanceQueryOptions
    {
        DiscoveryTypes = DiscoveryType.DotNetSdk, 
        WorkingDirectory = Path.GetDirectoryName(solutionFilePath)
    };

    VisualStudioInstance instance = 
        MSBuildLocator.QueryVisualStudioInstances(options)
            .OrderByDescending(o => o.Version)
            .First();

    string dotNetSdkPath = instance.MSBuildPath;
    foreach (KeyValuePair<string, string> item in new Dictionary<string, string>
             {
                 ["MSBUILD_EXE_PATH"] = Path.Combine(dotNetSdkPath, "MSBuild.dll"),
                 ["MSBuildExtensionsPath"] = dotNetSdkPath,
                 ["MSBuildSDKsPath"] = Path.Combine(dotNetSdkPath, "Sdks")
             })
    {
        Environment.SetEnvironmentVariable(item.Key, item.Value);
    }
}

SolutionFile solutionFile = SolutionFile.Parse(solutionFilePath);
ProjectCollection projects = new ProjectCollection();

foreach (ProjectInSolution projectInSolution in solutionFile
             .ProjectsInOrder
             .Where(pr => pr.ProjectType is SolutionProjectType.KnownToBeMSBuildFormat))
{
    projects.LoadProject(projectInSolution.AbsolutePath);
}

此答案假设您没有使用 Mono 或 .NET Framework 或其他版本的 MSBuild。如果您这样做,只需参考上面链接的 Roslyn 存储库即可。

© www.soinside.com 2019 - 2024. All rights reserved.