Skip to content

Commit 7eb406e

Browse files
authored
Merge pull request #10273 from MicrosoftDocs/main
8/8/2022 PM Publish
2 parents bb58694 + 466637b commit 7eb406e

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

docs/msbuild/tutorial-custom-task-code-generation.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -480,13 +480,10 @@ In this section, you'll wire up the task implementation in `.props` and `.target
480480
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
481481
<!--defining properties interesting for my task-->
482482
<PropertyGroup>
483-
<!--default directory where the .dll was published inside a nuget package-->
484-
<taskForldername>tasks</taskForldername>
485-
<taskFramework>netstandard2.0</taskFramework>
486483
<!--The folder where the custom task will be present. It points to inside the nuget package. -->
487-
<CustomTasksFolder>$(MSBuildThisFileDirectory)..\$(taskForldername)\$(taskFramework)</CustomTasksFolder>
484+
<_AppSettingsStronglyTyped_TaskFolder>$(MSBuildThisFileDirectory)..\tasks\netstandard2.0</_AppSettingsStronglyTyped_TaskFolder>
488485
<!--Reference to the assembly which contains the MSBuild Task-->
489-
<CustomTasksAssembly>$(CustomTasksFolder)\$(MSBuildThisFileName).dll</CustomTasksAssembly>
486+
<CustomTasksAssembly>$(_AppSettingsStronglyTyped_TaskFolder)\$(MSBuildThisFileName).dll</CustomTasksAssembly>
490487
</PropertyGroup>
491488

492489
<!--Register our custom task-->
@@ -554,6 +551,39 @@ Congratulations! You've generated a NuGet package named *\AppSettingStronglyType
554551

555552
The package has an extension `.nupkg` and is a compressed zip file. You can open it with a zip tool. The `.target` and `.props` files are in the `build` folder. The `.dll` file is in the `lib\netstandard2.0\` folder. The `AppSettingStronglyTyped.nuspec` file is at the root level.
556553

554+
## (Optional) Support multitargeting
555+
556+
You should consider supporting both `Full` (.NET Framework) and `Core` (including .NET 5 and later) MSBuild distributions to support the broadest possible user base.
557+
558+
For 'normal' .NET SDK projects, multitargeting means setting multiple TargetFrameworks in your project file. When you do this, builds will be triggered for both TargetFrameworkMonikers, and the overall results can be packaged as a single artifact.
559+
560+
That's not the full story for MSBuild. MSBuild has two primary shipping vehicles: Visual Studio and the .NET SDK. These are very different runtime environments; one runs on the .NET Framework runtime, and other runs on the CoreCLR. What this means is that while your code can target netstandard2.0, your task logic may have differences based on what MSBuild runtime type is currently in use. Practically, since there are so many new APIs in .NET 5.0 and up, it makes sense to both multitarget your MSBuild task source code for multiple TargetFrameworkMonikers as well as multitarget your MSBuild target logic for multiple MSBuild runtime types.
561+
562+
### Changes required to multitarget
563+
564+
To target multiple TargetFrameworkMonikers (TFM):
565+
566+
1. Change your project file to use the `net472` and `net6.0` TFMs (the latter may change based on which SDK level you want to target). You might want to target `netcoreapp3.1` until .NET Core 3.1 goes out of support. When you do this, the package folder structure changes from `tasks/` to `tasks/<TFM>/`.
567+
568+
```xml
569+
<TargetFrameworks>net472;net6.0</TargetFrameworks>
570+
```
571+
572+
2. Update your `.targets` files to use the correct TFM to load your tasks. The TFM required will change based on what .NET TFM you chose above, but for a project targeting `net472` and `net6.0`, you would have a property like:
573+
574+
```xml
575+
<AppSettingStronglyTyped_TFM Condition=" '$(MSBuildRuntimeType)' != 'Core' ">net472</AppSettingStronglyTyped_TFM>
576+
<AppSettingStronglyTyped_TFM Condition=" '$(MSBuildRuntimeType)' == 'Core' ">net6.0</AppSettingStronglyTyped_TFM>
577+
```
578+
579+
This code uses the `MSBuildRuntimeType` property as a proxy for the active hosting environment. Once this property is set, you can use it in the `UsingTask` to load the correct `AssemblyFile`:
580+
581+
```xml
582+
<UsingTask
583+
AssemblyFile="$(MSBuildThisFileDirectory)../tasks/$(AppSettingStronglyTyped_TFM)/AppSettingStronglyTyped.dll"
584+
TaskName="AppSettingStrongTyped.AppSettingStronglyTyped" />
585+
```
586+
557587
## Next steps
558588

559589
Many tasks involve calling an executable. In some scenarios, you can use the Exec task, but if the limitations of the Exec task are an issue, you can also create a custom task. The following tutorial walks through both options with a more realistic code-generation scenario: creating a custom task to generate client code for a REST API.

0 commit comments

Comments
 (0)