You've already forked com.unity.ide.cursor
mirror of
https://github.com/boxqkrtm/com.unity.ide.cursor.git
synced 2026-05-14 22:30:10 +00:00
com.unity.ide.visualstudio@2.0.17
## [2.0.17] - 2022-12-06 Integration: - Fix rare deadlocks while discovering or launching Visual Studio on Windows. - Improve launching Visual Studio on macOs. Project generation: - Include analyzers from response files. - Update supported C# versions. - Performance improvements.
This commit is contained in:
96
Editor/ProcessRunner.cs
Normal file
96
Editor/ProcessRunner.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
internal class ProcessRunnerResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Output { get; set; }
|
||||
public string Error { get; set; }
|
||||
}
|
||||
|
||||
internal static class ProcessRunner
|
||||
{
|
||||
public const int DefaultTimeoutInMilliseconds = 300000;
|
||||
|
||||
public static ProcessStartInfo ProcessStartInfoFor(string filename, string arguments)
|
||||
{
|
||||
return new ProcessStartInfo
|
||||
{
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
FileName = filename,
|
||||
Arguments = arguments
|
||||
};
|
||||
}
|
||||
|
||||
public static ProcessRunnerResult StartAndWaitForExit(string filename, string arguments, int timeoutms = DefaultTimeoutInMilliseconds, Action<string> onOutputReceived = null)
|
||||
{
|
||||
return StartAndWaitForExit(ProcessStartInfoFor(filename, arguments), timeoutms, onOutputReceived);
|
||||
}
|
||||
|
||||
public static ProcessRunnerResult StartAndWaitForExit(ProcessStartInfo processStartInfo, int timeoutms = DefaultTimeoutInMilliseconds, Action<string> onOutputReceived = null)
|
||||
{
|
||||
var process = new Process { StartInfo = processStartInfo };
|
||||
|
||||
using (process)
|
||||
{
|
||||
var sbOutput = new StringBuilder();
|
||||
var sbError = new StringBuilder();
|
||||
|
||||
var outputSource = new TaskCompletionSource<bool>();
|
||||
var errorSource = new TaskCompletionSource<bool>();
|
||||
|
||||
process.OutputDataReceived += (_, e) =>
|
||||
{
|
||||
Append(sbOutput, e.Data, outputSource);
|
||||
if (onOutputReceived != null && e.Data != null)
|
||||
onOutputReceived(e.Data);
|
||||
};
|
||||
process.ErrorDataReceived += (_, e) => Append(sbError, e.Data, errorSource);
|
||||
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
var run = Task.Run(() => process.WaitForExit(timeoutms));
|
||||
var processTask = Task.WhenAll(run, outputSource.Task, errorSource.Task);
|
||||
|
||||
if (Task.WhenAny(Task.Delay(timeoutms), processTask).Result == processTask && run.Result)
|
||||
return new ProcessRunnerResult {Success = true, Error = sbError.ToString(), Output = sbOutput.ToString()};
|
||||
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
catch
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
return new ProcessRunnerResult {Success = false, Error = sbError.ToString(), Output = sbOutput.ToString()};
|
||||
}
|
||||
}
|
||||
|
||||
private static void Append(StringBuilder sb, string data, TaskCompletionSource<bool> taskSource)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
taskSource.SetResult(true);
|
||||
return;
|
||||
}
|
||||
|
||||
sb?.Append(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user