我正在构建一个C#程序,该程序处理现有项目,然后尝试编译它们。
我的程序目前正在使用net6.0
构建。
我已经在我的机器上找到了SDK(新的dotnet.exe和旧的MSBuild.exe(。如果我使用dotnet.exe,它运行良好,我没有遇到任何问题。
然而,旧的非sdk风格的项目无法使用dotnet构建,所以我试图回到MSBuild.exe
现在我使用Process.Start执行它(为了方便使用,我使用了CliWrap,但也尝试了使用标准Process.Start(ProcessStartInfo)
,结果相同(来启动MSBuild.exe,并将项目和一些参数传递给它。这看起来像这样:
var processStartInfo = new ProcessStartInfo
{
FileName = Path.Combine(MSBuildDirectory, "MSBuild.exe"),
WorkingDirectory = Path.GetDirectoryName(projectToBuild),
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
Arguments = $""{Path.GetFileName(projectToBuild)}" /restore -t:build /p:Configuration=Release",
};
var process = Process.Start(processStartInfo);
这基本上会生成以下命令:
C:Usersmerepo > "C:Program FilesMicrosoft Visual Studio2022ProfessionalMSBuildCurrentBinMSBuild.exe" "MyProject.csproj" /restore -t:build /p:Configuration=Release
这成功地开始了构建,但随后开始在一些任务中失败,但有趣的是它使用了新的.NET Core SDK?当我把它传给老式的MSBuild.exe
时,为什么会发生这种情况?
我得到的错误是:
Build Error: Microsoft (R) Build Engine version 17.2.1+52cd2da31 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 04/08/2022 14:32:26.
Project "C:UsersmerepoMyProject.csproj" on node 1 (build target(s)).
Project "C:UsersmerepoMyProject.csproj" (1) is building "C:UsersmerepoDependentProject.csproj" (2) on node 1 (GetTargetFrameworks target(s)).
C:UsersmerepoDependentProject.csproj : error MSB4244: The SDK resolver assembly "C:Program Filesdotnetsdk6.0.302Microsoft.Build.NuGetSdkResolver.dll" could not be loaded. Could not load file or assembly 'Microsoft.Build.NuGetSdkResolver, Version=6.2.1.7, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. An attempt was made to load a program with an incorrect format.
Done Building Project "C:UsersmerepoDependentProject.csproj" (GetTargetFrameworks target(s)) -- FAILED.
Done Building Project "C:UsersmerepoMyProject.csproj" (build target(s)) -- FAILED.
Build FAILED.
"C:UsersmerepoMyProject.csproj" (build target) (1) ->
"C:UsersmerepoDependentProject.csproj" (GetTargetFrameworks target) (2) ->
C:UsersmerepoDependentProject.csproj : error MSB4244: The SDK resolver assembly "C:Program Filesdotnetsdk6.0.302Microsoft.Build.NuGetSdkResolver.dll" could not be loaded. Could not load file or assembly 'Microsoft.Build.NuGetSdkResolver, Version=6.2.1.7, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. An attempt was made to load a program with an incorrect format.
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.15
但是,如果我使用上面生成的命令,设置相同的工作目录,并在新的命令提示符窗口中手动运行它,那么它就可以工作了。
为什么以及发生了什么?
我认为Process.Start会产生一个新的进程,所以无论是我手动完成的,还是我的程序完成的,它们的行为都是一样的?
我试过32位和64位MSBuild.exe,结果都一样。两者都给出了一个错误,其中包含指向thet.NET6SDK文件夹的路径。
就好像在.NET Core中启动Process.Start会保留某种.NET Core上下文?
有人能帮忙吗?
感谢
我是通过Microsoft Build Structured Logging发现的。差异在于环境变量。我的.NET核心程序在生成新进程时传递了一些环境变量。这些是SDK的位置——我不想让它使用的位置。我已经将这些设置为空,现在它正在工作!
["MsBuildExtensionPath"] = null,
["MsBuildSDKsPath"] = null,
["MSBUILD_EXE_PATH"] = null