You've already forked com.unity.ide.cursor
mirror of
https://github.com/boxqkrtm/com.unity.ide.cursor.git
synced 2026-05-14 14:20:09 +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:
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,19 @@
|
||||
# Code Editor Package for Visual Studio
|
||||
|
||||
## [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.
|
||||
|
||||
|
||||
## [2.0.16] - 2022-06-08
|
||||
|
||||
Integration:
|
||||
@@ -7,7 +21,6 @@ Integration:
|
||||
- Prevent ADB Refresh while being in safe-mode with a URP project
|
||||
- Fixed an issue keeping the progress bar visible even after opening a script with Visual Studio.
|
||||
|
||||
|
||||
## [2.0.15] - 2022-03-21
|
||||
|
||||
Integration:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define keyFileSender 1179872868
|
||||
|
||||
// 16 bit aligned legacy struct - this should total 20 bytes
|
||||
struct SelectionRange
|
||||
typedef struct _SelectionRange
|
||||
{
|
||||
int16_t unused1; // 0 (not used)
|
||||
int16_t lineNum; // line to select (<0 to specify range)
|
||||
@@ -19,7 +19,7 @@ struct SelectionRange
|
||||
int32_t endRange; // end of selection range (if line < 0)
|
||||
int32_t unused2; // 0 (not used)
|
||||
int32_t theDate; // modification date/time
|
||||
} __attribute__((packed));
|
||||
} __attribute__((packed)) SelectionRange;
|
||||
|
||||
static NSString* MakeNSString(const char* str)
|
||||
{
|
||||
@@ -200,18 +200,13 @@ static NSRunningApplication* QueryRunningApplicationOpenedOnSolution(NSString* a
|
||||
|
||||
static NSRunningApplication* LaunchApplicationOnSolution(NSString* appPath, NSString* solutionPath)
|
||||
{
|
||||
NSURL* appUrl = [NSURL fileURLWithPath: appPath];
|
||||
NSMutableDictionary* config = [[NSMutableDictionary alloc] init];
|
||||
|
||||
NSRunningApplication* runningApp = [[NSWorkspace sharedWorkspace]
|
||||
launchApplicationAtURL: appUrl
|
||||
return [[NSWorkspace sharedWorkspace]
|
||||
launchApplicationAtURL: [NSURL fileURLWithPath: appPath]
|
||||
options: NSWorkspaceLaunchDefault | NSWorkspaceLaunchNewInstance
|
||||
configuration: config
|
||||
configuration: @{
|
||||
NSWorkspaceLaunchConfigurationArguments: @[ solutionPath ],
|
||||
}
|
||||
error: nil];
|
||||
|
||||
OpenFileAtLineWithAppleEvent(runningApp, solutionPath, -1);
|
||||
|
||||
return runningApp;
|
||||
}
|
||||
|
||||
static NSRunningApplication* QueryOrLaunchApplication(NSString* appPath, NSString* solutionPath)
|
||||
|
||||
@@ -11,20 +11,24 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
internal class AsyncOperation<T>
|
||||
{
|
||||
private readonly Func<T> _producer;
|
||||
private readonly Func<Exception, T> _exceptionHandler;
|
||||
private readonly Action _finalHandler;
|
||||
private readonly ManualResetEventSlim _resetEvent;
|
||||
|
||||
private T _result;
|
||||
private Exception _exception;
|
||||
|
||||
private AsyncOperation(Func<T> producer)
|
||||
private AsyncOperation(Func<T> producer, Func<Exception, T> exceptionHandler, Action finalHandler)
|
||||
{
|
||||
_producer = producer;
|
||||
_exceptionHandler = exceptionHandler;
|
||||
_finalHandler = finalHandler;
|
||||
_resetEvent = new ManualResetEventSlim(initialState: false);
|
||||
}
|
||||
|
||||
public static AsyncOperation<T> Run(Func<T> producer)
|
||||
public static AsyncOperation<T> Run(Func<T> producer, Func<Exception, T> exceptionHandler = null, Action finalHandler = null)
|
||||
{
|
||||
var task = new AsyncOperation<T>(producer);
|
||||
var task = new AsyncOperation<T>(producer, exceptionHandler, finalHandler);
|
||||
task.Run();
|
||||
return task;
|
||||
}
|
||||
@@ -40,9 +44,15 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
catch (Exception e)
|
||||
{
|
||||
_exception = e;
|
||||
|
||||
if (_exceptionHandler != null)
|
||||
{
|
||||
_result = _exceptionHandler(e);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_finalHandler?.Invoke();
|
||||
_resetEvent.Set();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -205,6 +205,32 @@ static bool StartVisualStudioProcess(
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
MonikerIsVisualStudioProcess(const win::ComPtr<IMoniker> &moniker, const win::ComPtr<IBindCtx> &bindCtx, const DWORD dwProcessId = 0) {
|
||||
LPOLESTR oleMonikerName;
|
||||
if (FAILED(moniker->GetDisplayName(bindCtx, nullptr, &oleMonikerName)))
|
||||
return false;
|
||||
|
||||
std::wstring monikerName(oleMonikerName);
|
||||
|
||||
// VisualStudio Moniker is "!VisualStudio.DTE.$Version:$PID"
|
||||
// Example "!VisualStudio.DTE.14.0:1234"
|
||||
|
||||
if (monikerName.find(L"!VisualStudio.DTE") != 0)
|
||||
return false;
|
||||
|
||||
if (dwProcessId == 0)
|
||||
return true;
|
||||
|
||||
std::wstringstream suffixStream;
|
||||
suffixStream << ":";
|
||||
suffixStream << dwProcessId;
|
||||
|
||||
std::wstring suffix(suffixStream.str());
|
||||
|
||||
return monikerName.length() - suffix.length() == monikerName.find(suffix);
|
||||
}
|
||||
|
||||
static win::ComPtr<EnvDTE::_DTE> FindRunningVisualStudioWithSolution(
|
||||
const std::filesystem::path &visualStudioExecutablePath,
|
||||
const std::filesystem::path &solutionPath)
|
||||
@@ -232,6 +258,9 @@ static win::ComPtr<EnvDTE::_DTE> FindRunningVisualStudioWithSolution(
|
||||
win::ComPtr<IMoniker> moniker;
|
||||
ULONG monikersFetched = 0;
|
||||
while (SUCCEEDED(enumMoniker->Next(1, &moniker, &monikersFetched)) && monikersFetched) {
|
||||
if (!MonikerIsVisualStudioProcess(moniker, bindCtx))
|
||||
continue;
|
||||
|
||||
if (FAILED(ROT->GetObject(moniker, &punk)))
|
||||
continue;
|
||||
|
||||
@@ -285,29 +314,6 @@ static win::ComPtr<EnvDTE::_DTE> FindRunningVisualStudioWithSolution(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
MonikerIsVisualStudioProcess(const win::ComPtr<IMoniker> &moniker, const win::ComPtr<IBindCtx> &bindCtx, const DWORD dwProcessId) {
|
||||
LPOLESTR oleMonikerName;
|
||||
if (FAILED(moniker->GetDisplayName(bindCtx, nullptr, &oleMonikerName)))
|
||||
return false;
|
||||
|
||||
std::wstring monikerName(oleMonikerName);
|
||||
|
||||
// VisualStudio Moniker is "!VisualStudio.DTE.$Version:$PID"
|
||||
// Example "!VisualStudio.DTE.14.0:1234"
|
||||
|
||||
if (monikerName.find(L"!VisualStudio.DTE") != 0)
|
||||
return false;
|
||||
|
||||
std::wstringstream suffixStream;
|
||||
suffixStream << ":";
|
||||
suffixStream << dwProcessId;
|
||||
|
||||
std::wstring suffix(suffixStream.str());
|
||||
|
||||
return monikerName.length() - suffix.length() == monikerName.find(suffix);
|
||||
}
|
||||
|
||||
static win::ComPtr<EnvDTE::_DTE> FindRunningVisualStudioWithPID(const DWORD dwProcessId) {
|
||||
win::ComPtr<IUnknown> punk = nullptr;
|
||||
win::ComPtr<EnvDTE::_DTE> dte = nullptr;
|
||||
@@ -329,10 +335,10 @@ static win::ComPtr<EnvDTE::_DTE> FindRunningVisualStudioWithPID(const DWORD dwPr
|
||||
win::ComPtr<IMoniker> moniker;
|
||||
ULONG monikersFetched = 0;
|
||||
while (SUCCEEDED(enumMoniker->Next(1, &moniker, &monikersFetched)) && monikersFetched) {
|
||||
if (FAILED(ROT->GetObject(moniker, &punk)))
|
||||
if (!MonikerIsVisualStudioProcess(moniker, bindCtx, dwProcessId))
|
||||
continue;
|
||||
|
||||
if (!MonikerIsVisualStudioProcess(moniker, bindCtx, dwProcessId))
|
||||
if (FAILED(ROT->GetObject(moniker, &punk)))
|
||||
continue;
|
||||
|
||||
punk.As(&dte);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Direct style:
|
||||
cl /EHsc /std:c++17 COMIntegration.cpp /link Shlwapi.lib /out:"..\Release\COMIntegration.exe"
|
||||
|
||||
For a debug build with PDB:
|
||||
cl /EHsc /std:c++17 /Z7 /DEBUG:FULL COMIntegration.cpp /link Shlwapi.lib /out:"..\Release\COMIntegration.exe"
|
||||
|
||||
CMake style:
|
||||
cmake ../COMIntegration~ -B ./build
|
||||
cmake --build ./build --config=release -- /p:OutDir=..
|
||||
|
||||
Binary file not shown.
@@ -150,31 +150,15 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
if (string.IsNullOrWhiteSpace(progpath))
|
||||
return Enumerable.Empty<VisualStudioInstallation>();
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = progpath,
|
||||
Arguments = "-prerelease -format json -utf8",
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
}
|
||||
};
|
||||
var result = ProcessRunner.StartAndWaitForExit(progpath, "-prerelease -format json -utf8");
|
||||
|
||||
using (process)
|
||||
{
|
||||
var json = string.Empty;
|
||||
if (!result.Success)
|
||||
throw new Exception($"Failure while running vswhere: {result.Error}");
|
||||
|
||||
process.OutputDataReceived += (o, e) => json += e.Data;
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
process.WaitForExit();
|
||||
|
||||
var result = VsWhereResult.FromJson(json);
|
||||
return result.ToVisualStudioInstallations();
|
||||
}
|
||||
// Do not catch any JsonException here, this will be handled by the caller
|
||||
return VsWhereResult
|
||||
.FromJson(result.Output)
|
||||
.ToVisualStudioInstallations();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Editor/ProcessRunner.cs.meta
Normal file
11
Editor/ProcessRunner.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 957a5f2d2660a894d926660de2a9d577
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -43,6 +43,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
public IAssemblyNameProvider AssemblyNameProvider => m_AssemblyNameProvider;
|
||||
public string ProjectDirectory { get; }
|
||||
|
||||
// Use this to have the same newline ending on all platforms for consistency.
|
||||
const string k_WindowsNewline = "\r\n";
|
||||
|
||||
const string m_SolutionProjectEntryTemplate = @"Project(""{{{0}}}"") = ""{1}"", ""{2}"", ""{{{3}}}""{4}EndProject";
|
||||
@@ -126,11 +127,11 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
var affectedNames = affected
|
||||
.Select(asset => m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset))
|
||||
.Where(name => !string.IsNullOrWhiteSpace(name)).Select(name =>
|
||||
name.Split(new[] {".dll"}, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||||
name.Split(new[] { ".dll" }, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||||
var reimportedNames = reimported
|
||||
.Select(asset => m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset))
|
||||
.Where(name => !string.IsNullOrWhiteSpace(name)).Select(name =>
|
||||
name.Split(new[] {".dll"}, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||||
name.Split(new[] { ".dll" }, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||||
var affectedAndReimported = new HashSet<string>(affectedNames.Concat(reimportedNames));
|
||||
|
||||
foreach (var assembly in allProjectAssemblies)
|
||||
@@ -381,19 +382,19 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
var filename = EscapedRelativePathFor(asset, out var packageInfo);
|
||||
|
||||
builder.Append($" <{tag} Include=\"").Append(filename);
|
||||
builder.Append(" <").Append(tag).Append(@" Include=""").Append(filename);
|
||||
if (Path.IsPathRooted(filename) && packageInfo != null)
|
||||
{
|
||||
// We are outside the Unity project and using a package context
|
||||
var linkPath = SkipPathPrefix(asset.NormalizePathSeparators(), packageInfo.assetPath.NormalizePathSeparators());
|
||||
|
||||
builder.Append("\">").Append(k_WindowsNewline);
|
||||
builder.Append(@""">").Append(k_WindowsNewline);
|
||||
builder.Append(" <Link>").Append(linkPath).Append("</Link>").Append(k_WindowsNewline);
|
||||
builder.Append($" </{tag}>").Append(k_WindowsNewline);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("\" />").Append(k_WindowsNewline);
|
||||
builder.Append(@""" />").Append(k_WindowsNewline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,7 +505,8 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
Dictionary<string, string> allAssetsProjectParts,
|
||||
ResponseFileData[] responseFilesData)
|
||||
{
|
||||
var projectBuilder = new StringBuilder(ProjectHeader(assembly, responseFilesData));
|
||||
ProjectHeader(assembly, responseFilesData, out StringBuilder projectBuilder);
|
||||
|
||||
var references = new List<string>();
|
||||
|
||||
projectBuilder.Append(@" <ItemGroup>").Append(k_WindowsNewline);
|
||||
@@ -563,7 +565,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
// If the current assembly is a Player project, we want to project-reference the corresponding Player project
|
||||
var referenceName = m_AssemblyNameProvider.GetAssemblyName(assembly.outputPath, reference.name);
|
||||
|
||||
projectBuilder.Append(" <ProjectReference Include=\"").Append(referenceName).Append(GetProjectExtension()).Append("\">").Append(k_WindowsNewline);
|
||||
projectBuilder.Append(@" <ProjectReference Include=""").Append(referenceName).Append(GetProjectExtension()).Append(@""">").Append(k_WindowsNewline);
|
||||
projectBuilder.Append(" <Project>{").Append(ProjectGuid(referenceName)).Append("}</Project>").Append(k_WindowsNewline);
|
||||
projectBuilder.Append(" <Name>").Append(referenceName).Append("</Name>").Append(k_WindowsNewline);
|
||||
projectBuilder.Append(" </ProjectReference>").Append(k_WindowsNewline);
|
||||
@@ -595,7 +597,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
private void AppendReference(string fullReference, StringBuilder projectBuilder)
|
||||
{
|
||||
var escapedFullPath = EscapedRelativePathFor(fullReference, out _);
|
||||
projectBuilder.Append(" <Reference Include=\"").Append(Path.GetFileNameWithoutExtension(escapedFullPath)).Append("\">").Append(k_WindowsNewline);
|
||||
projectBuilder.Append(@" <Reference Include=""").Append(Path.GetFileNameWithoutExtension(escapedFullPath)).Append(@""">").Append(k_WindowsNewline);
|
||||
projectBuilder.Append(" <HintPath>").Append(escapedFullPath).Append("</HintPath>").Append(k_WindowsNewline);
|
||||
projectBuilder.Append(" </Reference>").Append(k_WindowsNewline);
|
||||
}
|
||||
@@ -632,25 +634,77 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
return targetLanguageVersion;
|
||||
}
|
||||
|
||||
private string ProjectHeader(
|
||||
private static IEnumerable<string> GetOtherArguments(ResponseFileData[] responseFilesData, HashSet<string> names)
|
||||
{
|
||||
var lines = responseFilesData
|
||||
.SelectMany(x => x.OtherArguments)
|
||||
.Where(l => !string.IsNullOrEmpty(l))
|
||||
.Select(l => l.Trim())
|
||||
.Where(l => l.StartsWith("/") || l.StartsWith("-"));
|
||||
|
||||
foreach (var argument in lines)
|
||||
{
|
||||
var index = argument.IndexOf(":", StringComparison.Ordinal);
|
||||
if (index == -1)
|
||||
continue;
|
||||
|
||||
var key = argument
|
||||
.Substring(1, index - 1)
|
||||
.Trim();
|
||||
|
||||
if (!names.Contains(key))
|
||||
continue;
|
||||
|
||||
if (argument.Length <= index)
|
||||
continue;
|
||||
|
||||
yield return argument
|
||||
.Substring(index + 1)
|
||||
.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
private string[] GetAnalyzers(Assembly assembly, ResponseFileData[] responseFilesData, out string rulesetPath)
|
||||
{
|
||||
rulesetPath = null;
|
||||
|
||||
if (m_CurrentInstallation == null || !m_CurrentInstallation.SupportsAnalyzers)
|
||||
return Array.Empty<string>();
|
||||
|
||||
// Analyzers provided by VisualStudio
|
||||
List<string> analyzers = new List<string>(m_CurrentInstallation.GetAnalyzers());
|
||||
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
// Analyzers + ruleset provided by Unity
|
||||
analyzers.AddRange(assembly.compilerOptions.RoslynAnalyzerDllPaths);
|
||||
|
||||
rulesetPath = assembly
|
||||
.compilerOptions
|
||||
.RoslynAnalyzerRulesetPath
|
||||
.MakeAbsolutePath()
|
||||
.NormalizePathSeparators();
|
||||
#endif
|
||||
|
||||
// Analyzers provided by csc.rsp
|
||||
analyzers.AddRange(GetOtherArguments(responseFilesData, new HashSet<string>(new[] { "analyzer", "a" })));
|
||||
|
||||
return analyzers
|
||||
.Where(a => !string.IsNullOrEmpty(a))
|
||||
.Select(a => a.MakeAbsolutePath().NormalizePathSeparators())
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private void ProjectHeader(
|
||||
Assembly assembly,
|
||||
ResponseFileData[] responseFilesData
|
||||
ResponseFileData[] responseFilesData,
|
||||
out StringBuilder headerBuilder
|
||||
)
|
||||
{
|
||||
var projectType = ProjectTypeOf(assembly.name);
|
||||
string rulesetPath = null;
|
||||
var analyzers = Array.Empty<string>();
|
||||
var analyzers = GetAnalyzers(assembly, responseFilesData, out var rulesetPath);
|
||||
|
||||
if (m_CurrentInstallation != null && m_CurrentInstallation.SupportsAnalyzers)
|
||||
{
|
||||
analyzers = m_CurrentInstallation.GetAnalyzers();
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
analyzers = analyzers != null ? analyzers.Concat(assembly.compilerOptions.RoslynAnalyzerDllPaths).ToArray() : assembly.compilerOptions.RoslynAnalyzerDllPaths;
|
||||
rulesetPath = assembly.compilerOptions.RoslynAnalyzerRulesetPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
var projectProperties = new ProjectProperties()
|
||||
var projectProperties = new ProjectProperties
|
||||
{
|
||||
ProjectGuid = ProjectGuid(assembly),
|
||||
LangVersion = GetLangVersion(assembly),
|
||||
@@ -658,9 +712,9 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
RootNamespace = GetRootNamespace(assembly),
|
||||
OutputPath = assembly.outputPath,
|
||||
// Analyzers
|
||||
Analyzers = analyzers,
|
||||
RulesetPath = rulesetPath,
|
||||
// RSP alterable
|
||||
Analyzers = analyzers,
|
||||
Defines = assembly.defines.Concat(responseFilesData.SelectMany(x => x.Defines)).Distinct().ToArray(),
|
||||
Unsafe = assembly.compilerOptions.AllowUnsafeCode | responseFilesData.Any(x => x.Unsafe),
|
||||
// VSTU Flavoring
|
||||
@@ -670,7 +724,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
FlavoringPackageVersion = VisualStudioIntegration.PackageVersion(),
|
||||
};
|
||||
|
||||
return GetProjectHeader(projectProperties);
|
||||
GetProjectHeader(projectProperties, out headerBuilder);
|
||||
}
|
||||
|
||||
private enum ProjectType
|
||||
@@ -696,102 +750,86 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
return ProjectType.Game;
|
||||
}
|
||||
|
||||
private string GetProjectHeader(ProjectProperties properties)
|
||||
private void GetProjectHeader(ProjectProperties properties, out StringBuilder headerBuilder)
|
||||
{
|
||||
var header = new[]
|
||||
{
|
||||
$@"<?xml version=""1.0"" encoding=""utf-8""?>",
|
||||
$@"<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">",
|
||||
$@" <PropertyGroup>",
|
||||
$@" <LangVersion>{properties.LangVersion}</LangVersion>",
|
||||
$@" </PropertyGroup>",
|
||||
$@" <PropertyGroup>",
|
||||
$@" <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>",
|
||||
$@" <Platform Condition="" '$(Platform)' == '' "">AnyCPU</Platform>",
|
||||
$@" <ProductVersion>10.0.20506</ProductVersion>",
|
||||
$@" <SchemaVersion>2.0</SchemaVersion>",
|
||||
$@" <RootNamespace>{properties.RootNamespace}</RootNamespace>",
|
||||
$@" <ProjectGuid>{{{properties.ProjectGuid}}}</ProjectGuid>",
|
||||
$@" <OutputType>Library</OutputType>",
|
||||
$@" <AppDesignerFolder>Properties</AppDesignerFolder>",
|
||||
$@" <AssemblyName>{properties.AssemblyName}</AssemblyName>",
|
||||
$@" <TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>",
|
||||
$@" <FileAlignment>512</FileAlignment>",
|
||||
$@" <BaseDirectory>.</BaseDirectory>",
|
||||
$@" </PropertyGroup>",
|
||||
$@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "">",
|
||||
$@" <DebugSymbols>true</DebugSymbols>",
|
||||
$@" <DebugType>full</DebugType>",
|
||||
$@" <Optimize>false</Optimize>",
|
||||
$@" <OutputPath>{properties.OutputPath}</OutputPath>",
|
||||
$@" <DefineConstants>{string.Join(";", properties.Defines)}</DefineConstants>",
|
||||
$@" <ErrorReport>prompt</ErrorReport>",
|
||||
$@" <WarningLevel>4</WarningLevel>",
|
||||
$@" <NoWarn>0169</NoWarn>",
|
||||
$@" <AllowUnsafeBlocks>{properties.Unsafe}</AllowUnsafeBlocks>",
|
||||
$@" </PropertyGroup>",
|
||||
$@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "">",
|
||||
$@" <DebugType>pdbonly</DebugType>",
|
||||
$@" <Optimize>true</Optimize>",
|
||||
$@" <OutputPath>Temp\bin\Release\</OutputPath>",
|
||||
$@" <ErrorReport>prompt</ErrorReport>",
|
||||
$@" <WarningLevel>4</WarningLevel>",
|
||||
$@" <NoWarn>0169</NoWarn>",
|
||||
$@" <AllowUnsafeBlocks>{properties.Unsafe}</AllowUnsafeBlocks>",
|
||||
$@" </PropertyGroup>"
|
||||
};
|
||||
headerBuilder = new StringBuilder();
|
||||
|
||||
var forceExplicitReferences = new[]
|
||||
{
|
||||
$@" <PropertyGroup>",
|
||||
$@" <NoConfig>true</NoConfig>",
|
||||
$@" <NoStdLib>true</NoStdLib>",
|
||||
$@" <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>",
|
||||
$@" <ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>",
|
||||
$@" <ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>",
|
||||
$@" </PropertyGroup>"
|
||||
};
|
||||
//Header
|
||||
headerBuilder.Append(@"<?xml version=""1.0"" encoding=""utf-8""?>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@"<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <LangVersion>").Append(properties.LangVersion).Append(@"</LangVersion>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" </PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <Platform Condition="" '$(Platform)' == '' "">AnyCPU</Platform>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <ProductVersion>10.0.20506</ProductVersion>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <SchemaVersion>2.0</SchemaVersion>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <RootNamespace>").Append(properties.RootNamespace).Append(@"</RootNamespace>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <ProjectGuid>{").Append(properties.ProjectGuid).Append(@"}</ProjectGuid>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <OutputType>Library</OutputType>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <AppDesignerFolder>Properties</AppDesignerFolder>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <AssemblyName>").Append(properties.AssemblyName).Append(@"</AssemblyName>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <FileAlignment>512</FileAlignment>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <BaseDirectory>.</BaseDirectory>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" </PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "">").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <DebugSymbols>true</DebugSymbols>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <DebugType>full</DebugType>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <Optimize>false</Optimize>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <OutputPath>").Append(properties.OutputPath).Append(@"</OutputPath>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <DefineConstants>").Append(string.Join(";", properties.Defines)).Append(@"</DefineConstants>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <ErrorReport>prompt</ErrorReport>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <WarningLevel>4</WarningLevel>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <NoWarn>0169</NoWarn>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <AllowUnsafeBlocks>").Append(properties.Unsafe).Append(@"</AllowUnsafeBlocks>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" </PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "">").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <DebugType>pdbonly</DebugType>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <Optimize>true</Optimize>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <OutputPath>Temp\bin\Release\</OutputPath>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <ErrorReport>prompt</ErrorReport>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <WarningLevel>4</WarningLevel>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <NoWarn>0169</NoWarn>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <AllowUnsafeBlocks>").Append(properties.Unsafe).Append(@"</AllowUnsafeBlocks>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" </PropertyGroup>").Append(k_WindowsNewline);
|
||||
|
||||
var flavoring = new[]
|
||||
{
|
||||
$@" <PropertyGroup>",
|
||||
$@" <ProjectTypeGuids>{{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1}};{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}</ProjectTypeGuids>",
|
||||
$@" <UnityProjectGenerator>Package</UnityProjectGenerator>",
|
||||
$@" <UnityProjectGeneratorVersion>{properties.FlavoringPackageVersion}</UnityProjectGeneratorVersion>",
|
||||
$@" <UnityProjectType>{properties.FlavoringProjectType}</UnityProjectType>",
|
||||
$@" <UnityBuildTarget>{properties.FlavoringBuildTarget}</UnityBuildTarget>",
|
||||
$@" <UnityVersion>{properties.FlavoringUnityVersion}</UnityVersion>",
|
||||
$@" </PropertyGroup>"
|
||||
};
|
||||
// Explicit references
|
||||
headerBuilder.Append(@" <PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <NoConfig>true</NoConfig>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <NoStdLib>true</NoStdLib>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" </PropertyGroup>").Append(k_WindowsNewline);
|
||||
|
||||
var footer = new[]
|
||||
{
|
||||
@""
|
||||
};
|
||||
|
||||
var lines = header
|
||||
.Concat(forceExplicitReferences)
|
||||
.Concat(flavoring)
|
||||
.ToList();
|
||||
// Flavoring
|
||||
headerBuilder.Append(@" <PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <UnityProjectGenerator>Package</UnityProjectGenerator>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <UnityProjectGeneratorVersion>").Append(properties.FlavoringPackageVersion).Append(@"</UnityProjectGeneratorVersion>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <UnityProjectType>").Append(properties.FlavoringProjectType).Append(@"</UnityProjectType>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <UnityBuildTarget>").Append(properties.FlavoringBuildTarget).Append(@"</UnityBuildTarget>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <UnityVersion>").Append(properties.FlavoringUnityVersion).Append(@"</UnityVersion>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" </PropertyGroup>").Append(k_WindowsNewline);
|
||||
|
||||
if (!string.IsNullOrEmpty(properties.RulesetPath))
|
||||
{
|
||||
lines.Add(@" <PropertyGroup>");
|
||||
lines.Add($" <CodeAnalysisRuleSet>{properties.RulesetPath.MakeAbsolutePath().NormalizePathSeparators()}</CodeAnalysisRuleSet>");
|
||||
lines.Add(@" </PropertyGroup>");
|
||||
headerBuilder.Append(@" <PropertyGroup>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" <CodeAnalysisRuleSet>").Append(properties.RulesetPath).Append(@"</CodeAnalysisRuleSet>").Append(k_WindowsNewline);
|
||||
headerBuilder.Append(@" </PropertyGroup>").Append(k_WindowsNewline);
|
||||
}
|
||||
|
||||
if (properties.Analyzers.Any())
|
||||
{
|
||||
lines.Add(@" <ItemGroup>");
|
||||
foreach (var analyzer in properties.Analyzers.Distinct())
|
||||
headerBuilder.Append(@" <ItemGroup>").Append(k_WindowsNewline);
|
||||
foreach (var analyzer in properties.Analyzers)
|
||||
{
|
||||
lines.Add($@" <Analyzer Include=""{analyzer.MakeAbsolutePath().NormalizePathSeparators()}"" />");
|
||||
headerBuilder.Append(@" <Analyzer Include=""").Append(analyzer).Append(@""" />").Append(k_WindowsNewline);
|
||||
}
|
||||
lines.Add(@" </ItemGroup>");
|
||||
headerBuilder.Append(@" </ItemGroup>").Append(k_WindowsNewline);
|
||||
}
|
||||
|
||||
return string.Join(k_WindowsNewline, lines.Concat(footer));
|
||||
}
|
||||
|
||||
private static string GetProjectFooter()
|
||||
@@ -885,7 +923,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
if (array == null || array.Length == 0)
|
||||
{
|
||||
// HideSolution by default
|
||||
array = new [] {
|
||||
array = new[] {
|
||||
new SolutionProperties() {
|
||||
Name = "SolutionProperties",
|
||||
Type = "preSolution",
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
internal static class SolutionParser
|
||||
{
|
||||
// Compared to the bridge implementation, we are not returning "{" "}" from Guids
|
||||
private static readonly Regex ProjectDeclaration = new Regex(@"Project\(\""{(?<projectFactoryGuid>.*?)}\""\)\s+=\s+\""(?<name>.*?)\"",\s+\""(?<fileName>.*?)\"",\s+\""{(?<projectGuid>.*?)}\""(?<metadata>.*?)\bEndProject\b", RegexOptions.Singleline | RegexOptions.ExplicitCapture);
|
||||
private static readonly Regex PropertiesDeclaration = new Regex(@"GlobalSection\((?<name>([\w]+Properties|NestedProjects))\)\s+=\s+(?<type>(?:post|pre)Solution)(?<entries>.*?)EndGlobalSection", RegexOptions.Singleline | RegexOptions.ExplicitCapture);
|
||||
private static readonly Regex PropertiesEntryDeclaration = new Regex(@"^\s*(?<key>.*?)=(?<value>.*?)$", RegexOptions.Multiline | RegexOptions.ExplicitCapture);
|
||||
private static readonly Regex ProjectDeclaration = new Regex(@"Project\(\""{(?<projectFactoryGuid>.*?)}\""\)\s+=\s+\""(?<name>.*?)\"",\s+\""(?<fileName>.*?)\"",\s+\""{(?<projectGuid>.*?)}\""(?<metadata>.*?)\bEndProject\b", RegexOptions.Singleline | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
|
||||
private static readonly Regex PropertiesDeclaration = new Regex(@"GlobalSection\((?<name>([\w]+Properties|NestedProjects))\)\s+=\s+(?<type>(?:post|pre)Solution)(?<entries>.*?)EndGlobalSection", RegexOptions.Singleline | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
|
||||
private static readonly Regex PropertiesEntryDeclaration = new Regex(@"^\s*(?<key>.*?)=(?<value>.*?)$", RegexOptions.Multiline | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
|
||||
|
||||
public static Solution ParseSolutionFile(string filename, IFileIO fileIO)
|
||||
{
|
||||
|
||||
Binary file not shown.
@@ -4,7 +4,6 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -12,6 +11,8 @@ using System.Runtime.CompilerServices;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Unity.CodeEditor;
|
||||
using System.Threading;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.VisualStudio.EditorTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.VisualStudio.Standalone.EditorTests")]
|
||||
@@ -287,6 +288,14 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
return false;
|
||||
}
|
||||
|
||||
private enum COMIntegrationState
|
||||
{
|
||||
Running,
|
||||
DisplayProgressBar,
|
||||
ClearProgressBar,
|
||||
Exited
|
||||
}
|
||||
|
||||
private bool OpenWindowsApp(string path, int line)
|
||||
{
|
||||
var progpath = FileUtility.GetPackageAssetFullPath("Editor", "COMIntegration", "Release", "COMIntegration.exe");
|
||||
@@ -309,44 +318,67 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
solution = solution.Replace("^", "^^");
|
||||
}
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = progpath,
|
||||
Arguments = $"\"{CodeEditor.CurrentEditorInstallation}\" {solution} \"{absolutePath}\" {line}",
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
StandardOutputEncoding = System.Text.Encoding.Unicode,
|
||||
RedirectStandardError = true,
|
||||
StandardErrorEncoding = System.Text.Encoding.Unicode,
|
||||
}
|
||||
};
|
||||
var result = process.Start();
|
||||
|
||||
var psi = ProcessRunner.ProcessStartInfoFor(progpath, $"\"{CodeEditor.CurrentEditorInstallation}\" {solution} \"{absolutePath}\" {line}");
|
||||
psi.StandardOutputEncoding = System.Text.Encoding.Unicode;
|
||||
psi.StandardErrorEncoding = System.Text.Encoding.Unicode;
|
||||
|
||||
while (!process.StandardOutput.EndOfStream)
|
||||
{
|
||||
var outputLine = process.StandardOutput.ReadLine();
|
||||
if (outputLine == "displayProgressBar")
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Opening Visual Studio", "Starting up Visual Studio, this might take some time.", .5f);
|
||||
}
|
||||
// inter thread communication
|
||||
var messages = new BlockingCollection<COMIntegrationState>();
|
||||
|
||||
if (outputLine == "clearprogressbar")
|
||||
var asyncStart = AsyncOperation<ProcessRunnerResult>.Run(
|
||||
() => ProcessRunner.StartAndWaitForExit(psi, onOutputReceived: data => OnOutputReceived(data, messages)),
|
||||
e => new ProcessRunnerResult {Success = false, Error = e.Message, Output = string.Empty},
|
||||
() => messages.Add(COMIntegrationState.Exited)
|
||||
);
|
||||
|
||||
MonitorCOMIntegration(messages);
|
||||
|
||||
var result = asyncStart.Result;
|
||||
|
||||
if (!result.Success && !string.IsNullOrWhiteSpace(result.Error))
|
||||
Debug.LogError($"Error while starting Visual Studio: {result.Error}");
|
||||
|
||||
return result.Success;
|
||||
}
|
||||
|
||||
private static void MonitorCOMIntegration(BlockingCollection<COMIntegrationState> messages)
|
||||
{
|
||||
var displayingProgress = false;
|
||||
COMIntegrationState state;
|
||||
|
||||
do
|
||||
{
|
||||
state = messages.Take();
|
||||
switch (state)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
case COMIntegrationState.ClearProgressBar:
|
||||
EditorUtility.ClearProgressBar();
|
||||
displayingProgress = false;
|
||||
break;
|
||||
case COMIntegrationState.DisplayProgressBar:
|
||||
EditorUtility.DisplayProgressBar("Opening Visual Studio", "Starting up Visual Studio, this might take some time.", .5f);
|
||||
displayingProgress = true;
|
||||
break;
|
||||
}
|
||||
} while (state != COMIntegrationState.Exited);
|
||||
|
||||
// Make sure the progress bar is properly cleared in case of COMIntegration failure
|
||||
if (displayingProgress)
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
private static readonly COMIntegrationState[] ProgressBarCommands = {COMIntegrationState.DisplayProgressBar, COMIntegrationState.ClearProgressBar};
|
||||
private static void OnOutputReceived(string data, BlockingCollection<COMIntegrationState> messages)
|
||||
{
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
foreach (var cmd in ProgressBarCommands)
|
||||
{
|
||||
if (data.IndexOf(cmd.ToString(), StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
messages.Add(cmd);
|
||||
}
|
||||
|
||||
var errorOutput = process.StandardError.ReadToEnd();
|
||||
if (!string.IsNullOrEmpty(errorOutput))
|
||||
{
|
||||
Console.WriteLine("Error: \n" + errorOutput);
|
||||
}
|
||||
|
||||
process.WaitForExit();
|
||||
return result;
|
||||
}
|
||||
|
||||
[DllImport("AppleEventIntegration")]
|
||||
|
||||
@@ -43,6 +43,10 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
// C# language version support for Visual Studio
|
||||
private static VersionPair[] WindowsVersionTable =
|
||||
{
|
||||
// VisualStudio 2022
|
||||
new VersionPair(17,4, /* => */ 11,0),
|
||||
new VersionPair(17,0, /* => */ 10,0),
|
||||
|
||||
// VisualStudio 2019
|
||||
new VersionPair(16,8, /* => */ 9,0),
|
||||
new VersionPair(16,0, /* => */ 8,0),
|
||||
@@ -57,6 +61,10 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
||||
// C# language version support for Visual Studio for Mac
|
||||
private static VersionPair[] OSXVersionTable =
|
||||
{
|
||||
// VisualStudio for Mac 2022
|
||||
new VersionPair(17,4, /* => */ 11,0),
|
||||
new VersionPair(17,0, /* => */ 10,0),
|
||||
|
||||
// VisualStudio for Mac 8.x
|
||||
new VersionPair(8,8, /* => */ 9,0),
|
||||
new VersionPair(8,3, /* => */ 8,0),
|
||||
|
||||
12
package.json
12
package.json
@@ -2,24 +2,22 @@
|
||||
"name": "com.unity.ide.visualstudio",
|
||||
"displayName": "Visual Studio Editor",
|
||||
"description": "Code editor integration for supporting Visual Studio as code editor for unity. Adds support for generating csproj files for intellisense purposes, auto discovery of installations, etc.",
|
||||
"version": "2.0.16",
|
||||
"version": "2.0.17",
|
||||
"unity": "2019.4",
|
||||
"unityRelease": "25f1",
|
||||
"dependencies": {
|
||||
"com.unity.test-framework": "1.1.9"
|
||||
},
|
||||
"relatedPackages": {
|
||||
"com.unity.ide.visualstudio.tests": "2.0.16"
|
||||
},
|
||||
"_upm": {
|
||||
"changelog": "Integration:\n\n- Prevent ADB Refresh while being in safe-mode with a URP project\n- Fixed an issue keeping the progress bar visible even after opening a script with Visual Studio."
|
||||
"com.unity.ide.visualstudio.tests": "2.0.17"
|
||||
},
|
||||
"upmCi": {
|
||||
"footprint": "3d5e14bed71dd5b89e088160c170e814d0058248"
|
||||
"footprint": "95a297ed65f40d1df2fe8239f87deab3217a10b0"
|
||||
},
|
||||
"documentationUrl": "https://docs.unity3d.com/Packages/com.unity.ide.visualstudio@2.0/manual/index.html",
|
||||
"repository": {
|
||||
"url": "https://github.cds.internal.unity3d.com/unity/com.unity.ide.visualstudio.git",
|
||||
"type": "git",
|
||||
"revision": "c01855ef6461b821ab0226135e96a4ee86de96be"
|
||||
"revision": "1f126893bfb18ea9661fb15771613e841467073c"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user