Using Microsoft.NET.Sdk.Publish differs per platform
See original GitHub issueHi,
Not sure If the question should be asked here, or over at MSBuild.
We are in the progress of upgrading our applications to .netcore. Being .netcore does not necessarly mean we can run cross platform. One of the issues we have is that we use TransformXML as a build task. For this we use
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
This works fine when building with VisualStudio or at least visual studio installed. It won’t however work on a Mac or Unix machine. I shared a solution which works for the moment here https://stackoverflow.com/questions/16646698/the-transformxml-task-was-not-found-error-msb4036-on-teamcity-build/66748601#66748601
The solution I came up with consistst of the following (got lucky finding the DLL on google, the rest was done using MSBuild knowledge and peaking at dotnet/arcade)
<PropertyGroup>
<XmlTransformDllPath Condition="'$(XmlTransformDllPath)' == '' AND '$(MSBuildRuntimeType)' == 'core'">$(MSBuildSDKsPath)/Microsoft.NET.Sdk.Publish/tools/net5.0/Microsoft.NET.Sdk.Publish.Tasks.dll</XmlTransformDllPath>
<XmlTransformDllPath Condition="'$(XmlTransformDllPath)' == '' AND '$(MSBuildRuntimeType)' != 'core'">$(MSBuildSDKsPath)/Microsoft.NET.Sdk.Publish/tools/net472/Microsoft.NET.Sdk.Publish.Tasks.dll</XmlTransformDllPath>
<XmlTransformDllPath Condition="!Exists($(XmlTransformDllPath))">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll</XmlTransformDllPath>
</PropertyGroup>
<UsingTask TaskName="TransformXml" AssemblyFile="$(XmlTransformDllPath)" />
I have two problems with this solution
1) For some reason MSBuildSDKsPath and MSBuildExtensionsPath32 are different on windows when using CLI vs VS2019
CLI
MSBuildSDKsPath = C:\Program Files\dotnet\sdk\5.0.103\Sdks
MSBuildExtensionsPath32 = C:\Program Files\dotnet\sdk\5.0.103
Vs2019
MSBuildSDKsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Sdks
MSBuildExtensionsPath32 = C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild
Which on my Mac returns /usr/local/share/dotnet/sdk/5.0.201
Is there a consistent way of getting the SDK directory? Since if I can get that directory I can load the assembly
2) The TFM change on each version
If I have the NET5 SDK installed I get the directories
C:\Program Files\dotnet\sdk\5.0.103\Sdks\Microsoft.NET.Sdk.Publish\tools\net5.0 C:\Program Files\dotnet\sdk\5.0.103\Sdks\Microsoft.NET.Sdk.Publish\tools\net472
If I have the netcore3 sdk installed I get the directories
C:\Program Files\dotnet\sdk\3.1.406\Sdks\Microsoft.NET.Sdk.Publish\tools\netcoreapp2.1 C:\Program Files\dotnet\sdk\3.1.406\Sdks\Microsoft.NET.Sdk.Publish\tools\net46
Is there a safe way to get the full path to this dll?
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:12 (2 by maintainers)
After quite a lot of digging (and to save someone else the trouble)…
I had the following inside Directory.Build.targets
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
this line of code behaves differently if the solution is build from VisualStudio (it works as expected), vs if it is build via command line with
dotnet build
(it doesn’t work). The issue is that different MSBuild(s) are used: one comes packed with dotnet cli, and the other is from VisualStudio. The simplest way to resolve this is to remove the line and after the <Project> tag add<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Publish"/>
What this does is to load all the tasks recursively from the SDK the respectable point of the executable MSBuild, making it possible for both VisualStudio and dotnet cli to find the Task.
These differences are to be expected as the SDKs wil be resoved from different consumers (full-framwork msbuild aka msbuild.exe or in-process in Visual Stodio vs the .NET Core based msbuild version avilable via
dotnet msbuild
and used by other CLI commands) and can also exist in multiple versions and/or locations.Anyway, if your project is already using a web SDK (asp.net core apps, blazor, razor library, worker service, …) then the
TransformXml
task should already be available. If not, you should be able to use this SDK via<Project SDK="Microsoft.NET.Sdk;Microsoft.NET.Sdk.Publish">
in the csproj and the task should be available.