/// <summary> /// Starts the dotnet process. /// </summary> public async Task StartAsync(CancellationToken token) { string frameworkVersion = null; switch (FrameworkReference) { case DotNetFrameworkReference.Microsoft_AspNetCore_App: // Starting in .NET 6, the .NET SDK is emitting two framework references // into the .runtimeconfig.json file. This is preventing the --fx-version // parameter from having the correct effect of using the exact framework version // that we want. Disabling this forced version usage for ASP.NET 6+ applications // until it can be resolved. if (!TargetFramework.IsEffectively(TargetFrameworkMoniker.Net60)) { frameworkVersion = TargetFramework.GetAspNetCoreFrameworkVersionString(); } break; case DotNetFrameworkReference.Microsoft_NetCore_App: frameworkVersion = TargetFramework.GetNetCoreAppFrameworkVersionString(); break; default: throw new InvalidOperationException($"Unsupported framework reference: {FrameworkReference}"); } StringBuilder argsBuilder = new(); if (!string.IsNullOrEmpty(frameworkVersion)) { argsBuilder.Append("--fx-version "); argsBuilder.Append(frameworkVersion); argsBuilder.Append(" "); } argsBuilder.Append("\""); argsBuilder.Append(EntrypointAssemblyPath); argsBuilder.Append("\" "); argsBuilder.Append(Arguments); _process.StartInfo.Arguments = argsBuilder.ToString(); if (!_process.Start()) { throw new InvalidOperationException($"Unable to start: {_process.StartInfo.FileName} {_process.StartInfo.Arguments}"); } HasStarted = true; if (WaitForDiagnosticPipe) { // On Windows, named pipe connection will block until the named pipe is ready to connect so no need to block here if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // On Unix, we wait until the socket is created. while (true) { token.ThrowIfCancellationRequested(); var matchingFiles = Directory.GetFiles(Path.GetTempPath(), $"dotnet-diagnostic-{_process.Id}-*-socket"); if (matchingFiles.Length > 0) { break; } await Task.Delay(TimeSpan.FromMilliseconds(100)); } } } }