Skip to content

Commit 48b9672

Browse files
Merge pull request #10985 from MicrosoftDocs/main638895980300757107sync_temp
For protected branch, push strategy should use PR and merge to target branch method to work around git push error
2 parents c8ad660 + 0b97d8f commit 48b9672

6 files changed

+98
-320
lines changed

.openpublishing.redirection.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
{
22
"redirections": [
3+
{
4+
"source_path": "docs/msbuild/walkthrough-creating-an-inline-task.md",
5+
"redirect_url": "/visualstudio/msbuild/msbuild-roslyncodetaskfactory",
6+
"redirect_document_id": false
7+
},
38
{
49
"source_path": "docs/ide/reference/pre-build-event-post-build-event-command-line-dialog-box.md",
510
"redirect_url": "/previous-versions/visualstudio/visual-studio-2017/ide/reference/pre-build-event-post-build-event-command-line-dialog-box",

docs/msbuild/how-to-configure-targets-and-tasks.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ The following `UsingTask` attributes affect all operations of a task in a partic
2929
<UsingTask TaskName="SimpleTask"
3030
Runtime="CLR2"
3131
Architecture="x86"
32-
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v3.5.dll" />
32+
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" />
3333
```
3434

3535
You can also use the `MSBuildRuntime` and `MSBuildArchitecture` parameters to set the target context of an individual task invocation.
@@ -84,7 +84,7 @@ By default, MSBuild handles UsingTask's as "first one wins." Starting in 17.2, M
8484
8585
## Task factories
8686

87-
THe following table shows the task factories provided by the MSBuild installation:
87+
The following table shows the task factories provided by the MSBuild installation:
8888

8989
| Task factory | Description |
9090
| - | - |

docs/msbuild/msbuild-inline-tasks.md

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
title: Create MSBuild inline tasks
33
description: Create MSBuild inline tasks by compiling a class that implements the Microsoft.Build.Framework.ITask interface in Visual Studio.
4-
ms.date: 10/31/2023
5-
ms.topic: how-to
4+
ms.date: 7/14/2025
5+
ms.topic: concept-article
66
helpviewer_keywords:
77
- MSBuild, tasks
88
author: ghogen
@@ -14,20 +14,21 @@ ms.subservice: msbuild
1414

1515
MSBuild tasks are typically created by compiling a class that implements the <xref:Microsoft.Build.Framework.ITask> interface. For more information, see [Tasks](../msbuild/msbuild-tasks.md).
1616

17-
Starting in .NET Framework version 4, you can create tasks inline in the project file. You do not have to create a separate assembly to host the task. This makes it easier to keep track of source code and easier to deploy the task. The source code is integrated into the script.
17+
When you want to avoid the overhead of creating a compiled task, you can create a task inline in the project file or in an imported file. You don't have to create a separate assembly to host the task. Using an inline task makes it easier to keep track of source code and easier to deploy the task. The source code is integrated into the MSBuild project file or imported file, typically a `.targets` file.
18+
19+
You create an inline task by using a *code task factory*. For current development, be sure to use [RoslynCodeTaskFactory](../msbuild/msbuild-roslyncodetaskfactory.md), not `CodeTaskFactory`. `CodeTaskFactory` only supports C# versions up to 4.0.
20+
21+
Inline tasks are intended as a convenience for small tasks that don't require complicated dependencies. Debugging support for inline tasks is limited. It's recommended to create a compiled task instead of inline task when you want to write more complex code, reference a NuGet package, run external tools, or perform operations that could produce error conditions. Also, inline tasks are compiled every time you build, so there can be a noticeable impact on build performance.
1822

19-
In MSBuild 15.8, the [RoslynCodeTaskFactory](../msbuild/msbuild-roslyncodetaskfactory.md) was added. For current development, be sure to use the RoslynCodeTaskFactory, not CodeTaskFactory. CodeTaskFactory only supports C# versions up to 4.0.
20-
2123
## The structure of an inline task
2224

23-
An inline task is contained by a [UsingTask](../msbuild/usingtask-element-msbuild.md) element. The inline task and the `UsingTask` element that contains it are typically included in a *.targets* file and imported into other project files as required. Here is a basic inline task. Notice that it does nothing.
25+
An inline task is contained by a [UsingTask](../msbuild/usingtask-element-msbuild.md) element. The inline task and the `UsingTask` element that contains it are typically included in a `.targets` file and imported into other project files as required. Here's a basic inline task that does nothing, but illustrates the syntax:
2426

2527
```xml
26-
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
27-
<!-- This simple inline task does nothing. -->
28+
<!-- This simple inline task does nothing. -->
2829
<UsingTask
2930
TaskName="DoNothing"
30-
TaskFactory="CodeTaskFactory"
31+
TaskFactory="RoslynCodeTaskFactory"
3132
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
3233
<ParameterGroup />
3334
<Task>
@@ -37,8 +38,7 @@ MSBuild tasks are typically created by compiling a class that implements the <xr
3738
</Code>
3839
</Task>
3940
</UsingTask>
40-
</Project>
41-
```
41+
```
4242

4343
The `UsingTask` element in the example has three attributes that describe the task and the inline task factory that compiles it.
4444

@@ -48,17 +48,17 @@ MSBuild tasks are typically created by compiling a class that implements the <xr
4848

4949
- The `AssemblyFile` attribute gives the location of the inline task factory. Alternatively, you can use the `AssemblyName` attribute to specify the fully qualified name of the inline task factory class, which is typically located in `$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll`.
5050

51-
The remaining elements of the `DoNothing` task are empty and are provided to illustrate the order and structure of an inline task. A more robust example is presented later in this topic.
51+
The remaining elements of the `DoNothing` task are empty and are provided to illustrate the order and structure of an inline task. A complete example is presented later in this article.
5252

53-
- The `ParameterGroup` element is optional. When specified, it declares the parameters for the task. For more information about input and output parameters, see [Input and output parameters](#input-and-output-parameters) later in this topic.
53+
- The `ParameterGroup` element is optional. When specified, it declares the parameters for the task. For more information about input and output parameters, see [Input and output parameters](#input-and-output-parameters) later in this article.
5454

5555
- The `Task` element describes and contains the task source code.
5656

57-
- The `Reference` element specifies references to the .NET assemblies that you are using in your code. This is equivalent to adding a reference to a project in Visual Studio. The `Include` attribute specifies the path of the referenced assembly.
57+
- The `Reference` element specifies references to the .NET assemblies that you are using in your code. Using this element is equivalent to adding a reference to a project in Visual Studio. The `Include` attribute specifies the path of the referenced assembly. Assemblies in mscorlib, .NET Standard, [Microsoft.Build.Framework](https://www.nuget.org/packages/Microsoft.Build.Framework/), and [Microsoft.Build.Utilities.Core](https://www.nuget.org/packages/Microsoft.Build.Utilities.Core), as well as some assemblies that are transitively referenced as dependencies, are available without a `Reference`.
5858

59-
- The `Using` element lists the namespaces that you want to access. This resembles the `Using` statement in Visual C#. The `Namespace` attribute specifies the namespace to include.
59+
- The `Using` element lists the namespaces that you want to access. This element is equivalent to the `using` directive in C#. The `Namespace` attribute specifies the namespace to include. It doesn't work to put a `using` directive in the inline code, because that code is put into a method body, where `using` directives aren't allowed.
6060

61-
`Reference` and `Using` elements are language-agnostic. Inline tasks can be written in any one of the supported .NET CodeDom languages, for example, Visual Basic or Visual C#.
61+
`Reference` and `Using` elements are language-agnostic. Inline tasks can be written in Visual Basic or C#.
6262

6363
> [!NOTE]
6464
> Elements contained by the `Task` element are specific to the task factory, in this case, the code task factory.
@@ -77,27 +77,26 @@ The remaining elements of the `DoNothing` task are empty and are provided to ill
7777

7878
- If the value of `Type` is `Fragment`, then the code defines the contents of the `Execute` method, but not the signature or the `return` statement.
7979

80-
The code itself typically appears between a `<![CDATA[` marker and a `]]>` marker. Because the code is in a CDATA section, you do not have to worry about escaping reserved characters, for example, "\<" or ">".
80+
The code itself typically appears between a `<![CDATA[` marker and a `]]>` marker. Because the code is in a CDATA section, you don't have to worry about escaping reserved characters, for example, "\<" or ">".
8181

82-
Alternatively, you can use the `Source` attribute of the `Code` element to specify the location of a file that contains the code for your task. The code in the source file must be of the type that is specified by the `Type` attribute. If the `Source` attribute is present, the default value of `Type` is `Class`. If `Source` is not present, the default value is `Fragment`.
82+
Alternatively, you can use the `Source` attribute of the `Code` element to specify the location of a file that contains the code for your task. The code in the source file must be of the type that is specified by the `Type` attribute. If the `Source` attribute is present, the default value of `Type` is `Class`. If `Source` isn't present, the default value is `Fragment`.
8383

8484
> [!NOTE]
8585
> When defining the task class in the source file, the class name must agree with the `TaskName` attribute of the corresponding [UsingTask](../msbuild/usingtask-element-msbuild.md) element.
8686
8787
## HelloWorld
8888

89-
Here is a more robust inline task. The HelloWorld task displays "Hello, world!" on the default error logging device, which is typically the system console or the Visual Studio **Output** window. The `Reference` element in the example is included just for illustration.
89+
Here's an example of a simple inline task. The HelloWorld task displays "Hello, world!" on the default error logging device, which is typically the system console or the Visual Studio **Output** window.
9090

9191
```xml
92-
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
92+
<Project>
9393
<!-- This simple inline task displays "Hello, world!" -->
9494
<UsingTask
9595
TaskName="HelloWorld"
96-
TaskFactory="CodeTaskFactory"
96+
TaskFactory="RoslynCodeTaskFactory"
9797
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
9898
<ParameterGroup />
9999
<Task>
100-
<Reference Include="System.Xml"/>
101100
<Using Namespace="System"/>
102101
<Using Namespace="System.IO"/>
103102
<Code Type="Fragment" Language="cs">
@@ -114,7 +113,7 @@ Log.LogError("Hello, world!");
114113
You could save the HelloWorld task in a file that is named *HelloWorld.targets*, and then invoke it from a project as follows.
115114

116115
```xml
117-
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
116+
<Project>
118117
<Import Project="HelloWorld.targets" />
119118
<Target Name="Hello">
120119
<HelloWorld />
@@ -135,9 +134,7 @@ Log.LogError("Hello, world!");
135134
Parameters may have one or more of these attributes:
136135

137136
- `Required` is an optional attribute that is `false` by default. If `true`, then the parameter is required and must be given a value before calling the task.
138-
139-
- `ParameterType` is an optional attribute that is `System.String` by default. It may be set to any fully qualified type that is either an item or a value that can be converted to and from a string by using System.Convert.ChangeType. (In other words, any type that can be passed to and from an external task.)
140-
137+
- `ParameterType` is an optional attribute that is `System.String` by default. It may be set to any fully qualified type that is either an item or a value that can be converted to and from a string by using <xref:System.Convert.ChangeType%2A>. (In other words, any type that can be passed to and from an external task.)
141138
- `Output` is an optional attribute that is `false` by default. If `true`, then the parameter must be given a value before returning from the Execute method.
142139

143140
For example,
@@ -160,14 +157,18 @@ defines these three parameters:
160157

161158
If the `Code` element has the `Type` attribute of `Fragment` or `Method`, then properties are automatically created for every parameter. Otherwise, properties must be explicitly declared in the task source code, and must exactly match their parameter definitions.
162159

163-
## Example
160+
## Debug an inline task
161+
162+
MSBuild generates a source file the inline task and writes the output to text file with a GUID filename in the temporary files folder, *AppData\Local\Temp\MSBuildTemp*. The output is normally deleted, but to preserve this output file, you can set the environment variable `MSBUILDLOGCODETASKFACTORYOUTPUT` to 1.
163+
164+
## Example 1
164165

165166
The following inline task replaces every occurrence of a token in the given file with the given value.
166167

167168
```xml
168-
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="15.0">
169+
<Project>
169170

170-
<UsingTask TaskName="TokenReplace" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
171+
<UsingTask TaskName="TokenReplace" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
171172
<ParameterGroup>
172173
<Path ParameterType="System.String" Required="true" />
173174
<Token ParameterType="System.String" Required="true" />
@@ -184,7 +185,46 @@ File.WriteAllText(Path, content);
184185
</UsingTask>
185186

186187
<Target Name='Demo' >
187-
<TokenReplace Path="C:\Project\Target.config" Token="$MyToken$" Replacement="MyValue"/>
188+
<TokenReplace Path="Target.config" Token="$MyToken$" Replacement="MyValue"/>
189+
</Target>
190+
</Project>
191+
192+
```
193+
194+
## Example 2
195+
196+
The following inline task generates serialized output. This example shows the use of an output parameter and a reference.
197+
198+
```xml
199+
<Project>
200+
<PropertyGroup>
201+
<RoslynCodeTaskFactoryAssembly Condition="$(RoslynCodeTaskFactoryAssembly) == ''">$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll</RoslynCodeTaskFactoryAssembly>
202+
</PropertyGroup>
203+
204+
<UsingTask
205+
TaskName="MyInlineTask"
206+
TaskFactory="RoslynCodeTaskFactory"
207+
AssemblyFile="$(RoslynCodeTaskFactoryAssembly)">
208+
<ParameterGroup>
209+
<Input ParameterType="System.String" Required="true" />
210+
<Output ParameterType="System.String" Output="true" />
211+
</ParameterGroup>
212+
<Task>
213+
<Reference Include="System.Text.Json" /> <!-- Reference an assembly -->
214+
<Using Namespace="System.Text.Json" /> <!-- Use a namespace -->
215+
<Code Type="Fragment" Language="cs">
216+
<![CDATA[
217+
Output = JsonSerializer.Serialize(new { Message = Input });
218+
]]>
219+
</Code>
220+
</Task>
221+
</UsingTask>
222+
223+
<Target Name="RunInlineTask">
224+
<MyInlineTask Input="Hello, Roslyn!" >
225+
<Output TaskParameter="Output" PropertyName="SerializedOutput" />
226+
</MyInlineTask>
227+
<Message Text="Serialized Output: $(SerializedOutput)" />
188228
</Target>
189229
</Project>
190230
```

0 commit comments

Comments
 (0)