diff --git a/src/RoslynCodeTaskFactory.UnitTests/RoslynCodeTaskFactory.UnitTests.csproj b/src/RoslynCodeTaskFactory.UnitTests/RoslynCodeTaskFactory.UnitTests.csproj
index bddb5a5..1294de0 100644
--- a/src/RoslynCodeTaskFactory.UnitTests/RoslynCodeTaskFactory.UnitTests.csproj
+++ b/src/RoslynCodeTaskFactory.UnitTests/RoslynCodeTaskFactory.UnitTests.csproj
@@ -19,4 +19,8 @@
+
+
+
+
diff --git a/src/RoslynCodeTaskFactory/CodeTaskFactory.cs b/src/RoslynCodeTaskFactory/CodeTaskFactory.cs
index 691aa37..7c4491a 100644
--- a/src/RoslynCodeTaskFactory/CodeTaskFactory.cs
+++ b/src/RoslynCodeTaskFactory/CodeTaskFactory.cs
@@ -4,9 +4,11 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Threading;
using System.Xml;
using System.Xml.Linq;
@@ -160,6 +162,8 @@ public TaskPropertyInfo[] GetTaskParameters()
///
public bool Initialize(string taskName, IDictionary parameterGroup, string taskBody, IBuildEngine taskFactoryLoggingHost)
{
+ WaitForDebuggerIfConfigured();
+
_log = new TaskLoggingHelper(taskFactoryLoggingHost, taskName)
{
TaskResources = Strings.ResourceManager,
@@ -807,5 +811,27 @@ private bool TryCompileInMemoryAssembly(IBuildEngine buildEngine, TaskInfo taskI
}
}
}
+
+ ///
+ /// Waits for a user to attach a debugger.
+ ///
+ private void WaitForDebuggerIfConfigured()
+ {
+ if (!String.Equals(Environment.GetEnvironmentVariable("ROSLYNCODETASKFACTORY_DEBUG"), "1"))
+ {
+ return;
+ }
+
+ Process currentProcess = Process.GetCurrentProcess();
+
+ Console.WriteLine(Strings.CodeTaskFactory_WaitingForDebugger, currentProcess.MainModule.FileName, currentProcess.Id);
+
+ while (!Debugger.IsAttached)
+ {
+ Thread.Sleep(200);
+ }
+
+ Debugger.Break();
+ }
}
}
\ No newline at end of file
diff --git a/src/RoslynCodeTaskFactory/Internal/ManagedCompiler.cs b/src/RoslynCodeTaskFactory/Internal/ManagedCompiler.cs
index ad78ab7..12bdabf 100644
--- a/src/RoslynCodeTaskFactory/Internal/ManagedCompiler.cs
+++ b/src/RoslynCodeTaskFactory/Internal/ManagedCompiler.cs
@@ -1,13 +1,38 @@
-using System;
-using System.IO;
-using Microsoft.Build.Framework;
+using Microsoft.Build.Framework;
using Microsoft.Build.Tasks;
using Microsoft.Build.Utilities;
+using System;
+using System.IO;
+using System.Linq;
namespace RoslynCodeTaskFactory.Internal
{
internal abstract class ManagedCompiler : ToolTask
{
+ private static readonly string DotnetCliPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH");
+
+ private readonly Lazy _executablePath;
+
+ protected ManagedCompiler()
+ {
+ _executablePath = new Lazy(() =>
+ {
+ string pathToBuildTools = ToolLocationHelper.GetPathToBuildTools(ToolLocationHelper.CurrentToolsVersion, DotNetFrameworkArchitecture.Bitness32);
+
+ Func[] possibleLocations =
+ {
+ // Standard MSBuild and legacy .NET Core
+ () => Path.Combine(pathToBuildTools, "Roslyn", ToolName),
+ // Legacy .NET Core
+ () => Path.Combine(pathToBuildTools, "Roslyn", Path.ChangeExtension(ToolName, ".dll")),
+ // .NET Core 2.0
+ () => Path.Combine(pathToBuildTools, "Roslyn", "bincore", Path.ChangeExtension(ToolName, ".dll")),
+ };
+
+ return possibleLocations.Select(possibleLocation => possibleLocation()).FirstOrDefault(File.Exists);
+ }, isThreadSafe: true);
+ }
+
public bool? Deterministic { get; set; }
public bool? NoConfig { get; set; }
@@ -26,6 +51,8 @@ internal abstract class ManagedCompiler : ToolTask
public bool? UseSharedCompilation { get; set; }
+ protected bool IsDotnetCli => !String.IsNullOrWhiteSpace(DotnetCliPath);
+
protected internal virtual void AddResponseFileCommands(CommandLineBuilderExtension commandLine)
{
commandLine.AppendPlusOrMinusSwitch("/deterministic", Deterministic);
@@ -45,6 +72,13 @@ protected override string GenerateCommandLineCommands()
{
CommandLineBuilderExtension commandLineBuilder = new CommandLineBuilderExtension();
+ if (IsDotnetCli)
+ {
+ commandLineBuilder.AppendFileNameIfNotNull(_executablePath.Value);
+
+ commandLineBuilder.AppendTextUnquoted(" ");
+ }
+
AddCommandLineCommands(commandLineBuilder);
return commandLineBuilder.ToString();
@@ -57,19 +91,12 @@ protected override string GenerateFullPathToTool()
return ToolExe;
}
- string pathToBuildTools = ToolLocationHelper.GetPathToBuildTools(ToolLocationHelper.CurrentToolsVersion, DotNetFrameworkArchitecture.Bitness32);
-
- if (pathToBuildTools != null)
+ if (IsDotnetCli)
{
- string toolMSBuildLocation = Path.Combine(pathToBuildTools, "Roslyn", ToolName);
-
- if (File.Exists(toolMSBuildLocation))
- {
- return toolMSBuildLocation;
- }
+ return DotnetCliPath;
}
- return null;
+ return _executablePath.Value;
}
protected override string GenerateResponseFileCommands()
diff --git a/src/RoslynCodeTaskFactory/Strings.Designer.cs b/src/RoslynCodeTaskFactory/Strings.Designer.cs
index 8cf1d94..e7ad8a5 100644
--- a/src/RoslynCodeTaskFactory/Strings.Designer.cs
+++ b/src/RoslynCodeTaskFactory/Strings.Designer.cs
@@ -160,5 +160,14 @@ internal static string CodeTaskFactory_NoSourceCode {
return ResourceManager.GetString("CodeTaskFactory_NoSourceCode", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Waiting for debugger to attach ({0} PID {1}). Press enter to continue....
+ ///
+ internal static string CodeTaskFactory_WaitingForDebugger {
+ get {
+ return ResourceManager.GetString("CodeTaskFactory_WaitingForDebugger", resourceCulture);
+ }
+ }
}
}
diff --git a/src/RoslynCodeTaskFactory/Strings.resx b/src/RoslynCodeTaskFactory/Strings.resx
index 52d55f4..f9e148b 100644
--- a/src/RoslynCodeTaskFactory/Strings.resx
+++ b/src/RoslynCodeTaskFactory/Strings.resx
@@ -159,4 +159,7 @@
MSB3428: You must specify source code within the Code element or a path to a file containing source code.
{StrBegin="MSB3428: "}
+
+ Waiting for debugger to attach ({0} PID {1}). Press enter to continue...
+
\ No newline at end of file