├── .gitattributes
├── .gitignore
├── .idea
└── .idea.custom-msbuild-task
│ └── .idea
│ └── runConfigurations
│ ├── Pack__Unix_.xml
│ ├── Publish_CustomTasks__Unix_.xml
│ ├── Publish_CustomTasks__Win_net472_.xml
│ ├── Publish_CustomTasks__Win_netcoreapp6_0_.xml
│ ├── Run_TestProject__Unix_.xml
│ ├── Run_TestProject__Win_net472_.xml
│ └── Run_TestProject__Win_netcoreapp6_0_.xml
├── ExecTask
├── Class1.cs
└── ExecTask.csproj
├── Final
├── Final.csproj
└── Program.cs
├── InlineTask
└── InlineTask.csproj
├── README.md
├── custom-msbuild-task.sln
├── debugging.png
├── global.json
├── pack.cmd
└── src
├── CustomTasks
├── ContextAwareTask.cs
├── CustomTask.cs
├── CustomTasks.csproj
├── CustomTasks.props
└── CustomTasks.targets
├── Directory.Build.props
├── MainLibrary
├── MainLibrary.csproj
├── MainLibrary.props
├── MainLibrary.targets
└── Utility.cs
└── TestProject
├── Program.cs
├── TestProject.csproj
└── msbuild.binlog
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | *.DotSettings text eol=lf
7 | *.sh text eol=lf
8 |
9 | ###############################################################################
10 | # Set default behavior for command prompt diff.
11 | #
12 | # This is need for earlier builds of msysgit that does not have it on by
13 | # default for csharp files.
14 | # Note: This is only used by command line
15 | ###############################################################################
16 | #*.cs diff=csharp
17 |
18 | ###############################################################################
19 | # Set the merge driver for project and solution files
20 | #
21 | # Merging from the command prompt will add diff markers to the files if there
22 | # are conflicts (Merging from VS is not affected by the settings below, in VS
23 | # the diff markers are never inserted). Diff markers may cause the following
24 | # file extensions to fail to load in VS. An alternative would be to treat
25 | # these files as binary and thus will always conflict and require user
26 | # intervention with every merge. To do so, just uncomment the entries below
27 | ###############################################################################
28 | #*.sln merge=binary
29 | #*.csproj merge=binary
30 | #*.vbproj merge=binary
31 | #*.vcxproj merge=binary
32 | #*.vcproj merge=binary
33 | #*.dbproj merge=binary
34 | #*.fsproj merge=binary
35 | #*.lsproj merge=binary
36 | #*.wixproj merge=binary
37 | #*.modelproj merge=binary
38 | #*.sqlproj merge=binary
39 | #*.wwaproj merge=binary
40 |
41 | ###############################################################################
42 | # behavior for image files
43 | #
44 | # image files are treated as binary by default.
45 | ###############################################################################
46 | #*.jpg binary
47 | #*.png binary
48 | #*.gif binary
49 |
50 | ###############################################################################
51 | # diff behavior for common document formats
52 | #
53 | # Convert binary document formats to text before diffing them. This feature
54 | # is only available from the command line. Turn it on by uncommenting the
55 | # entries below.
56 | ###############################################################################
57 | #*.doc diff=astextplain
58 | #*.DOC diff=astextplain
59 | #*.docx diff=astextplain
60 | #*.DOCX diff=astextplain
61 | #*.dot diff=astextplain
62 | #*.DOT diff=astextplain
63 | #*.pdf diff=astextplain
64 | #*.PDF diff=astextplain
65 | #*.rtf diff=astextplain
66 | #*.RTF diff=astextplain
67 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | [Bb]in/
3 | [Oo]bj/
4 |
5 | ## Ignore Visual Studio temporary files, build results, and
6 | ## files generated by popular Visual Studio add-ons.
7 |
8 | # User-specific files
9 | *.suo
10 | *.user
11 | *.sln.docstates
12 | *.cache
13 |
14 | # Build results
15 | /output
16 | [Dd]ebug/
17 | [Rr]elease/
18 |
19 | /.vs
20 | /.idea
21 |
--------------------------------------------------------------------------------
/.idea/.idea.custom-msbuild-task/.idea/runConfigurations/Pack__Unix_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/.idea.custom-msbuild-task/.idea/runConfigurations/Publish_CustomTasks__Unix_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/.idea.custom-msbuild-task/.idea/runConfigurations/Publish_CustomTasks__Win_net472_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/.idea.custom-msbuild-task/.idea/runConfigurations/Publish_CustomTasks__Win_netcoreapp6_0_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/.idea.custom-msbuild-task/.idea/runConfigurations/Run_TestProject__Unix_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/.idea.custom-msbuild-task/.idea/runConfigurations/Run_TestProject__Win_net472_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/.idea.custom-msbuild-task/.idea/runConfigurations/Run_TestProject__Win_netcoreapp6_0_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ExecTask/Class1.cs:
--------------------------------------------------------------------------------
1 | namespace ExecTask;
2 |
3 | public class Class1
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/ExecTask/ExecTask.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Final/Final.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | enable
7 | enable
8 | true
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Final/Program.cs:
--------------------------------------------------------------------------------
1 | // See https://aka.ms/new-console-template for more information
2 |
3 | Console.WriteLine("Hello, World!");
4 |
5 | MainLibrary.Utility.Foo();
6 |
--------------------------------------------------------------------------------
/InlineTask/InlineTask.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Custom MSBuild Task
2 |
3 | Run Configurations for [JetBrains Rider](https://jetbrains.com/rider) are included and allow seamless debugging:
4 |
5 | 
6 |
7 | ⚠️ Note that the [specific SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1#3.1.6) according to the [`global.json` file](https://github.com/matkoch/custom-msbuild-task/blob/master/global.json#L3) must be installed. The best way is to use the [InstallSdkGlobalTool](https://www.nuget.org/packages/InstallSdkGlobalTool/) and call `dotnet-install-sdk` inside the repository.
8 |
--------------------------------------------------------------------------------
/custom-msbuild-task.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomTasks", ".\src\CustomTasks\CustomTasks.csproj", "{92C7175C-5076-4FEC-8B37-23D433F91694}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MainLibrary", "src\MainLibrary\MainLibrary.csproj", "{E005996F-DD54-49E7-B79C-171B6157F752}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "src\TestProject\TestProject.csproj", "{11ABD319-FF4C-47A5-A55D-7C91A9AF77C1}"
8 | EndProject
9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InlineTask", "InlineTask\InlineTask.csproj", "{04F8FABF-1D31-4C2F-85AC-9DDAC165BCEF}"
10 | EndProject
11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "alternatives", "alternatives", "{4C83D913-5F05-49D2-8B52-3802999C9200}"
12 | EndProject
13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExecTask", "ExecTask\ExecTask.csproj", "{F032095F-8850-4CEE-A141-6B1A35F008F6}"
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Final", "Final\Final.csproj", "{E9D1045C-8D0B-4E70-94C9-54CE37D1E416}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {92C7175C-5076-4FEC-8B37-23D433F91694}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {92C7175C-5076-4FEC-8B37-23D433F91694}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {92C7175C-5076-4FEC-8B37-23D433F91694}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {92C7175C-5076-4FEC-8B37-23D433F91694}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {E005996F-DD54-49E7-B79C-171B6157F752}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {E005996F-DD54-49E7-B79C-171B6157F752}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {E005996F-DD54-49E7-B79C-171B6157F752}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {E005996F-DD54-49E7-B79C-171B6157F752}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {11ABD319-FF4C-47A5-A55D-7C91A9AF77C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {11ABD319-FF4C-47A5-A55D-7C91A9AF77C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {11ABD319-FF4C-47A5-A55D-7C91A9AF77C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {11ABD319-FF4C-47A5-A55D-7C91A9AF77C1}.Release|Any CPU.Build.0 = Release|Any CPU
35 | {04F8FABF-1D31-4C2F-85AC-9DDAC165BCEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36 | {04F8FABF-1D31-4C2F-85AC-9DDAC165BCEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
37 | {04F8FABF-1D31-4C2F-85AC-9DDAC165BCEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {04F8FABF-1D31-4C2F-85AC-9DDAC165BCEF}.Release|Any CPU.Build.0 = Release|Any CPU
39 | {F032095F-8850-4CEE-A141-6B1A35F008F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {F032095F-8850-4CEE-A141-6B1A35F008F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {F032095F-8850-4CEE-A141-6B1A35F008F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 | {F032095F-8850-4CEE-A141-6B1A35F008F6}.Release|Any CPU.Build.0 = Release|Any CPU
43 | {E9D1045C-8D0B-4E70-94C9-54CE37D1E416}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44 | {E9D1045C-8D0B-4E70-94C9-54CE37D1E416}.Debug|Any CPU.Build.0 = Debug|Any CPU
45 | {E9D1045C-8D0B-4E70-94C9-54CE37D1E416}.Release|Any CPU.ActiveCfg = Release|Any CPU
46 | {E9D1045C-8D0B-4E70-94C9-54CE37D1E416}.Release|Any CPU.Build.0 = Release|Any CPU
47 | EndGlobalSection
48 | GlobalSection(NestedProjects) = preSolution
49 | {04F8FABF-1D31-4C2F-85AC-9DDAC165BCEF} = {4C83D913-5F05-49D2-8B52-3802999C9200}
50 | {F032095F-8850-4CEE-A141-6B1A35F008F6} = {4C83D913-5F05-49D2-8B52-3802999C9200}
51 | {E9D1045C-8D0B-4E70-94C9-54CE37D1E416} = {4C83D913-5F05-49D2-8B52-3802999C9200}
52 | EndGlobalSection
53 | EndGlobal
54 |
--------------------------------------------------------------------------------
/debugging.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matkoch/custom-msbuild-task/94fe4f658777dc01a35078ea6933c440fe92cc5e/debugging.png
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "6.0.100",
4 | "rollForward": "latestMajor",
5 | "allowPrerelease": false
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/pack.cmd:
--------------------------------------------------------------------------------
1 | dotnet publish ./src/CustomTasks --framework netcoreapp6.0
2 | dotnet publish ./src/CustomTasks --framework net472
3 | dotnet pack ./src/MainLibrary --output ./
4 |
--------------------------------------------------------------------------------
/src/CustomTasks/ContextAwareTask.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Microsoft.Build.Utilities;
6 | #if NETCOREAPP
7 | using System.Runtime.Loader;
8 | using Microsoft.Build.Framework;
9 | #endif
10 |
11 | namespace CustomTasks;
12 |
13 | public abstract class ContextAwareTask : Task
14 | {
15 | protected virtual string ManagedDllDirectory => Path.GetDirectoryName(new Uri(GetType().GetTypeInfo().Assembly.Location).LocalPath);
16 |
17 | protected virtual string UnmanagedDllDirectory => null;
18 |
19 | public sealed override bool Execute()
20 | {
21 | #if NETCOREAPP
22 | var taskAssemblyPath = new Uri(GetType().GetTypeInfo().Assembly.Location).LocalPath;
23 | var context = new CustomAssemblyLoader(this);
24 | var inContextAssembly = context.LoadFromAssemblyPath(taskAssemblyPath);
25 | var innerTaskType = inContextAssembly.GetType(GetType().FullName);
26 | var innerTask = Activator.CreateInstance(innerTaskType);
27 |
28 | var outerProperties = GetType().GetRuntimeProperties().ToDictionary(i => i.Name);
29 | var innerProperties = innerTaskType.GetRuntimeProperties().ToDictionary(i => i.Name);
30 | var propertiesDiscovery =
31 | from outerProperty in outerProperties.Values
32 | where outerProperty.SetMethod != null && outerProperty.GetMethod != null
33 | let innerProperty = innerProperties[outerProperty.Name]
34 | select new { outerProperty, innerProperty };
35 |
36 | var propertiesMap = propertiesDiscovery.ToArray();
37 | var outputPropertiesMap = propertiesMap.Where(pair => pair.outerProperty.GetCustomAttribute() != null).ToArray();
38 |
39 | foreach (var propertyPair in propertiesMap)
40 | {
41 | var outerPropertyValue = propertyPair.outerProperty.GetValue(this);
42 | propertyPair.innerProperty.SetValue(innerTask, outerPropertyValue);
43 | }
44 |
45 | var executeInnerMethod = innerTaskType.GetMethod(nameof(ExecuteInner), BindingFlags.Instance | BindingFlags.NonPublic);
46 | var result = (bool) executeInnerMethod.Invoke(innerTask, new object[0]);
47 |
48 | foreach (var propertyPair in outputPropertiesMap)
49 | propertyPair.outerProperty.SetValue(this, propertyPair.innerProperty.GetValue(innerTask));
50 |
51 | return result;
52 | #else
53 | // On .NET Framework (on Windows), we find native binaries by adding them to our PATH.
54 | if (UnmanagedDllDirectory != null)
55 | {
56 | var pathEnvVar = Environment.GetEnvironmentVariable("PATH");
57 | var searchPaths = pathEnvVar.Split(Path.PathSeparator);
58 | if (!searchPaths.Contains(UnmanagedDllDirectory, StringComparer.OrdinalIgnoreCase))
59 | {
60 | pathEnvVar += Path.PathSeparator + UnmanagedDllDirectory;
61 | Environment.SetEnvironmentVariable("PATH", pathEnvVar);
62 | }
63 | }
64 |
65 | return ExecuteInner();
66 | #endif
67 | }
68 |
69 | protected abstract bool ExecuteInner();
70 |
71 | #if NETCOREAPP
72 | private class CustomAssemblyLoader : AssemblyLoadContext
73 | {
74 | private readonly ContextAwareTask loaderTask;
75 |
76 | internal CustomAssemblyLoader(ContextAwareTask loaderTask)
77 | {
78 | this.loaderTask = loaderTask;
79 | }
80 |
81 | protected override Assembly Load(AssemblyName assemblyName)
82 | {
83 | var assemblyPath = Path.Combine(loaderTask.ManagedDllDirectory, assemblyName.Name) + ".dll";
84 | return File.Exists(assemblyPath)
85 | ? LoadFromAssemblyPath(assemblyPath)
86 | : Default.LoadFromAssemblyName(assemblyName);
87 | }
88 |
89 | protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
90 | {
91 | var unmanagedDllPath = Directory.EnumerateFiles(
92 | loaderTask.UnmanagedDllDirectory,
93 | $"{unmanagedDllName}.*").Concat(
94 | Directory.EnumerateFiles(
95 | loaderTask.UnmanagedDllDirectory,
96 | $"lib{unmanagedDllName}.*"))
97 | .FirstOrDefault();
98 |
99 | return unmanagedDllPath != null
100 | ? LoadUnmanagedDllFromPath(unmanagedDllPath)
101 | : base.LoadUnmanagedDll(unmanagedDllName);
102 | }
103 | }
104 | #endif
105 | }
106 |
--------------------------------------------------------------------------------
/src/CustomTasks/CustomTask.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Runtime.CompilerServices;
5 | using Microsoft.Build.Framework;
6 | using Microsoft.Build.Utilities;
7 |
8 | namespace CustomTasks;
9 |
10 | public class CustomTask : ContextAwareTask
11 | {
12 | [Required] public string StringParameter { get; set; }
13 | public ITaskItem[] FileItems { get; set; }
14 |
15 | [Output] public string OutputParameter { get; set; }
16 | [Output] public ITaskItem[] OutputItems { get; set; }
17 |
18 | protected override bool ExecuteInner()
19 | {
20 | string GetFile([CallerFilePath] string path = null) => path;
21 |
22 | Log.LogWarning(
23 | subcategory: "subcategory",
24 | warningCode: "CT1337",
25 | helpKeyword: "helpKeyword",
26 | helpLink: "helpLink",
27 | file: GetFile(),
28 | lineNumber: 100,
29 | columnNumber: 5,
30 | endLineNumber: 0,
31 | endColumnNumber: 0,
32 | message: "message");
33 |
34 | BuildEngine.LogWarningEvent(
35 | new BuildWarningEventArgs(
36 | subcategory: "subcategory",
37 | code: "code",
38 | file: GetFile(),
39 | lineNumber: 100,
40 | columnNumber: 10,
41 | endLineNumber: 0, // ignored if 0
42 | endColumnNumber: 0, // ignored if 0
43 | message: Assembly.GetExecutingAssembly().Location,
44 | helpKeyword: "helpKeyword",
45 | senderName: "senderName"));
46 |
47 | OutputParameter = StringParameter;
48 | OutputItems = new[] { new TaskItem($"{StringParameter}.cs") }.Concat(FileItems).ToArray();
49 |
50 | return true;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/CustomTasks/CustomTasks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp6.0;net472
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | PreserveNewest
19 | PreserveNewest
20 |
21 |
22 | PreserveNewest
23 | PreserveNewest
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/CustomTasks/CustomTasks.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Default
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/CustomTasks/CustomTasks.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildThisFileDirectory)\$(MSBuildThisFileName).dll
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | latest
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/MainLibrary/MainLibrary.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;net472
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/MainLibrary/MainLibrary.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildThisFileDirectory)\netcore
5 | $(MSBuildThisFileDirectory)\netfx
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/MainLibrary/MainLibrary.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/MainLibrary/Utility.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MainLibrary;
4 |
5 | public static class Utility
6 | {
7 | public static void Foo()
8 | {
9 | Console.WriteLine("Should we clap now? 🤔");
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/TestProject/Program.cs:
--------------------------------------------------------------------------------
1 | using MainLibrary;
2 |
3 | Utility.Foo();
4 |
--------------------------------------------------------------------------------
/src/TestProject/TestProject.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp6.0
5 | Exe
6 | False
7 | $(MSBuildThisFileDirectory)\..\CustomTasks\bin\Debug\$(TargetFramework)\publish
8 |
9 |
10 |
11 |
12 |
13 | Custom
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/TestProject/msbuild.binlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matkoch/custom-msbuild-task/94fe4f658777dc01a35078ea6933c440fe92cc5e/src/TestProject/msbuild.binlog
--------------------------------------------------------------------------------