Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
d564eb1
wip
JanProvaznik May 30, 2025
4b37477
wip2
JanProvaznik Jun 3, 2025
5eee401
refactor envvar to traits
JanProvaznik Jun 3, 2025
f1ebda6
cleanup taskexecutionhost
JanProvaznik Jun 3, 2025
7a7b77b
inline task cache per dll
JanProvaznik Jun 3, 2025
9c5c01e
undo unnecessary path caching
JanProvaznik Jun 3, 2025
2bb1960
nit
JanProvaznik Jun 3, 2025
c76be28
small fixes
JanProvaznik Jun 9, 2025
efc743e
refactor
JanProvaznik Jun 10, 2025
86c24fb
other task factories
JanProvaznik Jun 10, 2025
ffa53f9
add error for custom taskfactories, cleanup
JanProvaznik Jun 10, 2025
e6f35e6
docstring
JanProvaznik Jun 10, 2025
26b2a3e
roslyncodetaskfactory outofproc tests, fix excluding intrinsictaskfac…
JanProvaznik Jun 10, 2025
2e10e3e
hacks
JanProvaznik Jun 11, 2025
8edeef3
Support testhost.exe in TaskHost-launching tests (#11956)
rainersigwald Jun 6, 2025
f83e5be
fix test?
JanProvaznik Jun 12, 2025
56baac4
test?
JanProvaznik Jun 12, 2025
33fbac6
remove nonsense
JanProvaznik Jun 12, 2025
b8f8544
codetaskfactory adjustment
JanProvaznik Jun 13, 2025
4c9bf0a
nit
JanProvaznik Jun 13, 2025
af47117
reflect output/required parameters in generated class
JanProvaznik Jun 16, 2025
2af5fcd
also fix codetaskfactory output params
JanProvaznik Jun 16, 2025
7cf539d
adjust codegen tests
JanProvaznik Jun 16, 2025
08b5369
fix test
JanProvaznik Jun 16, 2025
26e2c8d
Merge branch 'main' into kickroslyntasks
JanProvaznik Jun 16, 2025
93201bd
reset formatting changes in resx
JanProvaznik Jun 16, 2025
fdf157f
new cleanup strategy
JanProvaznik Jun 16, 2025
77ab86e
add to docs
JanProvaznik Jun 16, 2025
7f42c45
cleanup
JanProvaznik Jun 16, 2025
2144eda
oops
JanProvaznik Jun 16, 2025
1b844f1
refactor duplicate assembly resolution and load manifest code
JanProvaznik Jun 23, 2025
603649c
cleanup
JanProvaznik Jun 23, 2025
01ea9a9
pr feedback
JanProvaznik Jun 25, 2025
89ed92d
rm tmp directories inproc mode
JanProvaznik Jun 26, 2025
2cf138d
Revert "rm tmp directories inproc mode"
JanProvaznik Jun 26, 2025
c6e012c
revert dll location when not opted in
JanProvaznik Jun 26, 2025
5824662
fix
JanProvaznik Jul 1, 2025
c7a8bb8
Merge branch 'main' into kickroslyntasks
JanProvaznik Jul 1, 2025
0f28704
feedback
JanProvaznik Jul 3, 2025
eda1b41
Merge branch 'kickroslyntasks' of https://github.com/JanProvaznik/msb…
JanProvaznik Jul 3, 2025
427d87c
feedback2
JanProvaznik Jul 3, 2025
d9f9697
Merge branch 'main' into kickroslyntasks
JanProvaznik Jul 8, 2025
4a41b78
Merge remote-tracking branch 'upstream/main' into kickroslyntasks
JanProvaznik Jul 18, 2025
67841ab
Merge branch 'main' into kickroslyntasks
SimaTian Aug 21, 2025
9e7641c
fix after merge
SimaTian Aug 21, 2025
37322a7
Merge branch 'main' into kickroslyntasks
JanProvaznik Sep 11, 2025
198764b
load inline tasks from bytes, cleanup at the end of build
JanProvaznik Sep 11, 2025
427a1d3
fix
JanProvaznik Sep 11, 2025
02956ca
different strategy for path propagation
JanProvaznik Sep 12, 2025
361b57f
fix out of proc factory caching, add test
JanProvaznik Sep 26, 2025
1e78ecb
nullable
JanProvaznik Sep 26, 2025
de40b50
fix tests
JanProvaznik Sep 26, 2025
1913eaa
simplify taskexecutionhost logic
JanProvaznik Sep 26, 2025
9e79373
prevent cache pollution
JanProvaznik Sep 29, 2025
9cfc104
Merge branch 'main' into kickroslyntasks
JanProvaznik Sep 29, 2025
23a9eea
make caching robust and refactor it
JanProvaznik Sep 30, 2025
e3be660
resolve comment in code
JanProvaznik Sep 30, 2025
b2d8f7f
Merge branch 'kickroslyntasks' of https://github.com/JanProvaznik/msb…
JanProvaznik Sep 30, 2025
4dbbc82
fix telemetry taskhost reporting for inline tasks
JanProvaznik Sep 30, 2025
4cb53de
resolve feedback
JanProvaznik Oct 2, 2025
d6d7d48
Merge branch 'main' into kickroslyntasks
JanProvaznik Oct 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 31 additions & 28 deletions documentation/wiki/MSBuild-Environment-Variables.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
# MSBuild environment variables list

This document describes the environment variables that are respected in MSBuild, its purpose and usage.
This document describes the environment variables that are respected in MSBuild, its purpose and usage.

Some of the env variables listed here are unsupported, meaning there is no guarantee that variable or a specific combination of multiple variables will be respected in upcoming release, so please use at your own risk.

* `MSBuildDebugEngine=1` & `MSBUILDDEBUGPATH=<DIRECTORY>`
* Set this to cause any MSBuild invocation launched within this environment to emit binary logs and additional debugging information to `<DIRECTORY>`. Useful when debugging build or evaluation issues when you can't directly influence the MSBuild invocation, such as in Visual Studio. More details on [capturing binary logs](./Providing-Binary-Logs.md)
* `MSBUILDTARGETOUTPUTLOGGING=1`
* Set this to enable [printing all target outputs to the log](https://learn.microsoft.com/archive/blogs/msbuild/displaying-target-output-items-using-the-console-logger).
* `MSBUILDLOGTASKINPUTS=1`
* Log task inputs (not needed if there are any diagnostic loggers already).
* `MSBUILDEMITSOLUTION=1`
* Save the generated .proj file for the .sln that is used to build the solution. The generated files are emitted into a binary log by default and their presence on disk can break subsequent builds.
* `MSBUILDENABLEALLPROPERTYFUNCTIONS=1`
* Enable [additional property functions](https://devblogs.microsoft.com/visualstudio/msbuild-property-functions/). If you need this level of detail you are generally served better with a binary log than the text log.
* `MSBUILDLOGVERBOSERARSEARCHRESULTS=1`
* In ResolveAssemblyReference task, log verbose search results.
* `MSBUILDLOGCODETASKFACTORYOUTPUT=1`
* Dump generated code for task to a <GUID>.txt file in the TEMP directory
* `MSBUILDDISABLENODEREUSE=1`
* Set this to not leave MSBuild processes behind (see `/nr:false`, but the environment variable is useful to also set this for Visual Studio for example).
* `MSBUILDLOGASYNC=1`
* Enable asynchronous logging.
* `MSBUILDDEBUGONSTART=1`
* Launches debugger on build start. Works on Windows operating systems only.
* Setting the value of 2 allows for manually attaching a debugger to a process ID. This works on Windows and non-Windows operating systems.
* `MSBUILDDEBUGSCHEDULER=1` & `MSBUILDDEBUGPATH=<DIRECTORY>`
* Dumps scheduler state at specified directory.

* `MsBuildSkipEagerWildCardEvaluationRegexes`
* If specified, overrides the default behavior of glob expansion. During glob expansion, if the path with wildcards that is being processed matches one of the regular expressions provided in the [environment variable](#msbuildskipeagerwildcardevaluationregexes), the path is not processed (expanded).
* The value of the environment variable is a list of regular expressions, separated by semicolon (;).
- `MSBuildDebugEngine=1` & `MSBUILDDEBUGPATH=<DIRECTORY>`
- Set this to cause any MSBuild invocation launched within this environment to emit binary logs and additional debugging information to `<DIRECTORY>`. Useful when debugging build or evaluation issues when you can't directly influence the MSBuild invocation, such as in Visual Studio. More details on [capturing binary logs](./Providing-Binary-Logs.md)
- `MSBUILDTARGETOUTPUTLOGGING=1`
- Set this to enable [printing all target outputs to the log](https://learn.microsoft.com/archive/blogs/msbuild/displaying-target-output-items-using-the-console-logger).
- `MSBUILDLOGTASKINPUTS=1`
- Log task inputs (not needed if there are any diagnostic loggers already).
- `MSBUILDEMITSOLUTION=1`
- Save the generated .proj file for the .sln that is used to build the solution. The generated files are emitted into a binary log by default and their presence on disk can break subsequent builds.
- `MSBUILDENABLEALLPROPERTYFUNCTIONS=1`
- Enable [additional property functions](https://devblogs.microsoft.com/visualstudio/msbuild-property-functions/). If you need this level of detail you are generally served better with a binary log than the text log.
- `MSBUILDLOGVERBOSERARSEARCHRESULTS=1`
- In ResolveAssemblyReference task, log verbose search results.
- `MSBUILDLOGCODETASKFACTORYOUTPUT=1`
- Dump generated code for task to a `<GUID>.txt` file in the TEMP directory
- `MSBUILDDISABLENODEREUSE=1`
- Set this to not leave MSBuild processes behind (see `/nr:false`, but the environment variable is useful to also set this for Visual Studio for example).
- `MSBUILDLOGASYNC=1`
- Enable asynchronous logging.
- `MSBUILDDEBUGONSTART=1`
- Launches debugger on build start. Works on Windows operating systems only.
- Setting the value of 2 allows for manually attaching a debugger to a process ID. This works on Windows and non-Windows operating systems.
- `MSBUILDDEBUGSCHEDULER=1` & `MSBUILDDEBUGPATH=<DIRECTORY>`
- Dumps scheduler state at specified directory.
- `MsBuildSkipEagerWildCardEvaluationRegexes`
- If specified, overrides the default behavior of glob expansion. During glob expansion, if the path with wildcards that is being processed matches one of the regular expressions provided in the [environment variable](#msbuildskipeagerwildcardevaluationregexes), the path is not processed (expanded).
- The value of the environment variable is a list of regular expressions, separated by semicolon (;).
- `MSBUILDFORCEALLTASKSOUTOFPROCESS`
- Set this to force all tasks to run out of process (except inline tasks).
- `MSBUILDFORCEINLINETASKFACTORIESOUTOFPROC`
- Set this to force all inline tasks to run out of process. It is not compatible with custom TaskFactories.
26 changes: 21 additions & 5 deletions documentation/wiki/Tasks.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,72 @@
# Tasks

A Task is a unit of execution in a Target and a method of extensibility in MSBuild.

## Basics

A task is a class implementing [`ITask`](https://github.com/dotnet/msbuild/blob/main/src/Framework/ITask.cs).
- The notable method of this interface is `bool Execute()`. Code in it will get executed when the task is run.

- The notable method of this interface is `bool Execute()`. Code in it will get executed when the task is run.
- A Task can have public properties that can be set by the user in the project file.
- These properties can be `string`, `bool`, `ITaskItem` (representation of a file system object), `string[]`, `bool[]`, `ITaskItem[]`
- the properties can have attributes `[Required]` which causes the engine to check that it has a value when the task is run and `[Output]` which exposes the property to be used again in XML
- These properties can be `string`, `bool`, `ITaskItem` (representation of a file system object), `string[]`, `bool[]`, `ITaskItem[]`
- the properties can have attributes `[Required]` which causes the engine to check that it has a value when the task is run and `[Output]` which exposes the property to be used again in XML

- Tasks have the `Log` property set by the engine to log messages/errors/warnings.

## Internals

- [`TaskRegistry`](https://github.com/dotnet/msbuild/blob/main/src/Build/Instance/TaskRegistry.cs) - has a list of all available tasks for the build, and resolves them.
- [`TaskExecutionHost`](https://github.com/dotnet/msbuild/tree/main/src/Build/BackEnd/TaskExecutionHost) - finds task in TaskRegistry, calls TaskFactory to create an instance of the task and sets its properties using reflection from the values in the XML. Then calls Execute on the task and gathers the outputs.
- TaskFactory - initializes the task, creates instance of the task
- ITask class - runs `Execute()` method

## Custom Tasks

Users can implement `ITask` and compile it into a .dll.
Then they can use in project file:

```xml
<UsingTask TaskName="MyTaskClass" AssemblyFile="MyTasks.dll"/>
```

This uses the AssemblyTaskFactory to load the task from the .dll and create an instance of it.

## Diagram of task lifecycle

```mermaid
graph
graph

I["Implement:<br/>extend ITask interface in .dll"] --> R["Register:<br/>&lt;UsingTask /&gt;"] --> U["Use in XML:<br/>&lt;Target&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;MyTask /&gt;<br/>&lt;/Target&gt;"] --> In["Initialize:<br/> compile inline or load from assembly <br/>(TaskFactory)"] --> S["Setup:<br/> Set input properties<br/> (TaskExecutionHost)"] --> E["ITask.Execute()"] --> O["Gather outputs: <br/> (TaskExecutionHost)"]
```

## Task Factories

Task factories create instances of tasks. They implement [`ITaskFactory`](https://github.com/dotnet/msbuild/blob/main/src/Framework/ITaskFactory.cs) or [`ITaskFactory2`](https://github.com/dotnet/msbuild/blob/main/src/Framework/ITaskFactory2.cs).
This interface defines `bool Initialize(...)` and `ITask CreateTask(...)`.
They are e.g. responsible for loading a task from an assembly and initializing it.

The trait `MSBUILDFORCEINLINETASKFACTORIESOUTOFPROC` forces inline tasks in an out of process TaskHost. It is not compatible with custom TaskFactories.

### Built-in Task Factories

- [`AssemblyTaskFactory`](https://github.com/dotnet/msbuild/blob/main/src/Build/Instance/TaskFactories/AssemblyTaskFactory.cs) - constructs tasks from .NET assemblies
- [`RoslynCodeTaskFactory`](https://github.com/dotnet/msbuild/blob/main/src/Tasks/RoslynCodeTaskFactory/RoslynCodeTaskFactory.cs) - inline code tasks
- CodeTaskFactory, XamlTaskFactory - old, rarely used

### Custom Task Factories

This is a rarely used method of extensibility.
Users can implement `ITaskFactory` to create custom task factories.
Then they can use in project file:

```xml
<UsingTask TaskName="MyTask" AssemblyFile="Factory.dll" Factory="MyTaskFactory">
<Task>Insides that the MyTaskFactory uses to initialize</Task>
</UsingTask>
```

# Microsoft Learn Resources
## Microsoft Learn Resources

- [MSBuild task](https://learn.microsoft.com/visualstudio/msbuild/msbuild-task)
- [Task reference](https://learn.microsoft.com/visualstudio/msbuild/msbuild-task-reference)
- [Task Writing](https://learn.microsoft.com/visualstudio/msbuild/task-writing)
Expand Down
5 changes: 5 additions & 0 deletions src/Build/BackEnd/BuildManager/BuildManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,11 @@ public void EndBuild()
Reset();
_buildManagerState = BuildManagerState.Idle;

if (Traits.Instance.ForceTaskFactoryOutOfProc)
{
TaskFactoryUtilities.CleanCurrentProcessInlineTaskDirectory();
}

MSBuildEventSource.Log.BuildStop();

_threadException?.Throw();
Expand Down
106 changes: 101 additions & 5 deletions src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -980,14 +980,37 @@ private ITask InstantiateTask(IDictionary<string, string> taskIdentityParameters
else
{
TaskFactoryLoggingHost loggingHost = new TaskFactoryLoggingHost(_buildEngine.IsRunningMultipleNodes, _taskLocation, _taskLoggingContext);
bool isTaskHost = false;
try
{
task = _taskFactoryWrapper.TaskFactory is ITaskFactory2 taskFactory2 ?
taskFactory2.CreateTask(loggingHost, taskIdentityParameters) :
_taskFactoryWrapper.TaskFactory.CreateTask(loggingHost);
// Check if we should force out-of-process execution for non-AssemblyTaskFactory instances
// IntrinsicTaskFactory tasks run in proc always
if (Traits.Instance.ForceTaskFactoryOutOfProc && _taskFactoryWrapper.TaskFactory is not IntrinsicTaskFactory)
{
// Custom Task factories are not supported, internal TaskFactories implement this marker interface
if (_taskFactoryWrapper.TaskFactory is not IOutOfProcTaskFactory outOfProcTaskFactory)
{
_taskLoggingContext.LogError(
new BuildEventFileInfo(_taskLocation),
"CustomTaskFactoryOutOfProcNotSupported",
_taskFactoryWrapper.TaskFactory.FactoryName,
_taskName);
return null;
}

task = CreateTaskHostTaskForOutOfProcFactory(taskIdentityParameters, loggingHost, outOfProcTaskFactory);
isTaskHost = true;
}
else
{
// Normal in-process execution for custom task factories
task = _taskFactoryWrapper.TaskFactory is ITaskFactory2 taskFactory2 ?
taskFactory2.CreateTask(loggingHost, taskIdentityParameters) :
_taskFactoryWrapper.TaskFactory.CreateTask(loggingHost);
}

// Track telemetry for non-AssemblyTaskFactory task factories. No task can go to the task host.
_taskLoggingContext?.TargetLoggingContext?.ProjectLoggingContext?.ProjectTelemetry?.AddTaskExecution(_taskFactoryWrapper.TaskFactory.GetType().FullName, isTaskHost: false);
// Track telemetry for non-AssemblyTaskFactory task factories
_taskLoggingContext?.TargetLoggingContext?.ProjectLoggingContext?.ProjectTelemetry?.AddTaskExecution(_taskFactoryWrapper.TaskFactory.GetType().FullName, isTaskHost);
}
finally
{
Expand Down Expand Up @@ -1703,5 +1726,78 @@ private void DisplayCancelWaitMessage()
// if the task logging context is no longer valid, we choose to eat the exception because we can't log the message anyway.
}
}

/// <summary>
/// Creates a <see cref="TaskHostTask"/> wrapper to run a non-AssemblyTaskFactory task out of process.
/// This is used when Traits.Instance.ForceTaskFactoryOutOfProc is true to ensure
/// non-AssemblyTaskFactory tasks run in isolation.
/// </summary>
/// <param name="taskIdentityParameters">Task identity parameters.</param>
/// <param name="loggingHost">The logging host to use for the task.</param>
/// <param name="outOfProcTaskFactory">The out-of-process task factory instance.</param>
/// <returns>A TaskHostTask that will execute the inner task out of process, or <code>null</code> if task creation fails.</returns>
private ITask CreateTaskHostTaskForOutOfProcFactory(IDictionary<string, string> taskIdentityParameters, TaskFactoryLoggingHost loggingHost, IOutOfProcTaskFactory outOfProcTaskFactory)
{
ITask innerTask;

innerTask = _taskFactoryWrapper.TaskFactory is ITaskFactory2 taskFactory2 ?
taskFactory2.CreateTask(loggingHost, taskIdentityParameters) :
_taskFactoryWrapper.TaskFactory.CreateTask(loggingHost);

if (innerTask == null)
{
return null;
}

// Create a LoadedType for the actual task type so we can wrap it in TaskHostTask
Type taskType = innerTask.GetType();

// For out-of-process inline tasks, get the assembly path from the factory
// (Assembly.Location is typically empty for inline tasks loaded from bytes)
string resolvedAssemblyLocation = outOfProcTaskFactory.GetAssemblyPath();

// This should never happen - if the factory can create a task, it should know where the assembly is
ErrorUtilities.VerifyThrow(!string.IsNullOrEmpty(resolvedAssemblyLocation),
$"IOutOfProcTaskFactory {_taskFactoryWrapper.TaskFactory.FactoryName} created a task but returned null/empty assembly path");

LoadedType taskLoadedType = new LoadedType(
taskType,
AssemblyLoadInfo.Create(null, resolvedAssemblyLocation),
taskType.Assembly,
typeof(ITaskItem));

// Default task host parameters for out-of-process execution for inline tasks
Dictionary<string, string> taskHostParameters = new Dictionary<string, string>
{
[XMakeAttributes.runtime] = XMakeAttributes.GetCurrentMSBuildRuntime(),
[XMakeAttributes.architecture] = XMakeAttributes.GetCurrentMSBuildArchitecture()
};

// Merge with any existing task identity parameters
if (taskIdentityParameters?.Count > 0)
{
foreach (var kvp in taskIdentityParameters.Where(kvp => !taskHostParameters.ContainsKey(kvp.Key)))
{
taskHostParameters[kvp.Key] = kvp.Value;
}
}

// Clean up the original task since we're going to wrap it
_taskFactoryWrapper.TaskFactory.CleanupTask(innerTask);

#pragma warning disable SA1111, SA1009 // Closing parenthesis should be on line of last parameter
return new TaskHostTask(
_taskLocation,
_taskLoggingContext,
_buildComponentHost,
taskHostParameters,
taskLoadedType,
true
#if FEATURE_APPDOMAIN
, AppDomainSetup
#endif
);
#pragma warning restore SA1111, SA1009 // Closing parenthesis should be on line of last parameter
}
}
}
9 changes: 8 additions & 1 deletion src/Build/Instance/TaskFactories/TaskHostTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ public bool Execute()
ErrorUtilities.VerifyThrowInternalNull(_taskHostProvider, "taskHostProvider");
}

string taskLocation = AssemblyUtilities.GetAssemblyLocation(_taskType.Type.GetTypeInfo().Assembly);
if (string.IsNullOrEmpty(taskLocation))
{
// fall back to the AssemblyLoadInfo location for inline tasks loaded from bytes
taskLocation = _taskType?.Assembly?.AssemblyLocation ?? string.Empty;
}

TaskHostConfiguration hostConfiguration =
new TaskHostConfiguration(
_buildComponentHost.BuildParameters.NodeId,
Expand All @@ -292,7 +299,7 @@ public bool Execute()
BuildEngine.ProjectFileOfTaskNode,
BuildEngine.ContinueOnError,
_taskType.Type.FullName,
AssemblyUtilities.GetAssemblyLocation(_taskType.Type.GetTypeInfo().Assembly),
taskLocation,
_buildComponentHost.BuildParameters.LogTaskInputs,
_setParameters,
new Dictionary<string, string>(_buildComponentHost.BuildParameters.GlobalProperties),
Expand Down
2 changes: 1 addition & 1 deletion src/Build/Instance/TaskRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,7 @@ public bool ComputeIfCustom()
!FileClassifier.IsMicrosoftAssembly(_taskFactoryAssemblyLoadInfo.AssemblyName)) ||
(!string.IsNullOrEmpty(_taskFactoryAssemblyLoadInfo.AssemblyFile) &&
// This condition will as well capture Microsoft tasks pulled from NuGet cache - since we decide based on assembly name.
// Hence we do not have to add the 'IsMicrosoftPackageInNugetCache' call anywhere here
// Hence we do not have to add the 'IsMicrosoftPackageInNugetCache' call anywhere here
!FileClassifier.IsMicrosoftAssembly(Path.GetFileName(_taskFactoryAssemblyLoadInfo.AssemblyFile)) &&
!FileClassifier.Shared.IsBuiltInLogic(_taskFactoryAssemblyLoadInfo.AssemblyFile)))
// and let's consider all tasks imported by common targets as non custom logic.
Expand Down
1 change: 1 addition & 0 deletions src/Build/Microsoft.Build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<Link>Collections\ReadOnlyEmptyCollection.cs</Link>
</Compile>
<Compile Include="..\Shared\BufferedReadStream.cs" />
<Compile Include="..\Shared\TaskFactoryUtilities.cs" />
<Compile Include="..\GlobalUsings.cs" Link="GlobalUsings.cs" />
<Compile Include="..\Shared\TaskHostConfiguration.cs" />
<Compile Include="..\Shared\TaskHostTaskCancelled.cs" />
Expand Down
Loading