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
vscode to cursor, disable vs
This commit is contained in:
@@ -13,14 +13,6 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
{
|
{
|
||||||
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
|
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR_WIN
|
|
||||||
foreach (var installation in VisualStudioForWindowsInstallation.GetVisualStudioInstallations())
|
|
||||||
yield return installation;
|
|
||||||
#elif UNITY_EDITOR_OSX
|
|
||||||
foreach (var installation in VisualStudioForMacInstallation.GetVisualStudioInstallations())
|
|
||||||
yield return installation;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
foreach (var installation in VisualStudioCodeInstallation.GetVisualStudioInstallations())
|
foreach (var installation in VisualStudioCodeInstallation.GetVisualStudioInstallations())
|
||||||
yield return installation;
|
yield return installation;
|
||||||
}
|
}
|
||||||
@@ -29,13 +21,6 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR_WIN
|
|
||||||
if (VisualStudioForWindowsInstallation.TryDiscoverInstallation(editorPath, out installation))
|
|
||||||
return true;
|
|
||||||
#elif UNITY_EDITOR_OSX
|
|
||||||
if (VisualStudioForMacInstallation.TryDiscoverInstallation(editorPath, out installation))
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
if (VisualStudioCodeInstallation.TryDiscoverInstallation(editorPath, out installation))
|
if (VisualStudioCodeInstallation.TryDiscoverInstallation(editorPath, out installation))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -49,11 +34,6 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
|
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR_WIN
|
|
||||||
VisualStudioForWindowsInstallation.Initialize();
|
|
||||||
#elif UNITY_EDITOR_OSX
|
|
||||||
VisualStudioForMacInstallation.Initialize();
|
|
||||||
#endif
|
|
||||||
VisualStudioCodeInstallation.Initialize();
|
VisualStudioCodeInstallation.Initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
if (string.IsNullOrEmpty(vstuPath))
|
if (string.IsNullOrEmpty(vstuPath))
|
||||||
return Array.Empty<string>();
|
return Array.Empty<string>();
|
||||||
|
|
||||||
return GetAnalyzers(vstuPath); }
|
return GetAnalyzers(vstuPath);
|
||||||
|
}
|
||||||
|
|
||||||
public override IGenerator ProjectGenerator
|
public override IGenerator ProjectGenerator
|
||||||
{
|
{
|
||||||
@@ -132,7 +133,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
installation = new VisualStudioCodeInstallation()
|
installation = new VisualStudioCodeInstallation()
|
||||||
{
|
{
|
||||||
IsPrerelease = isPrerelease,
|
IsPrerelease = isPrerelease,
|
||||||
Name = "Visual Studio Code" + (isPrerelease ? " - Insider" : string.Empty) + (version != null ? $" [{version.ToString(3)}]" : string.Empty),
|
Name = "Cursor" + (isPrerelease ? " - Insider" : string.Empty) + (version != null ? $" [{version.ToString(3)}]" : string.Empty),
|
||||||
Path = editorPath,
|
Path = editorPath,
|
||||||
Version = version ?? new Version()
|
Version = version ?? new Version()
|
||||||
};
|
};
|
||||||
@@ -150,17 +151,16 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
|
|
||||||
foreach (var basePath in new[] {localAppPath, programFiles})
|
foreach (var basePath in new[] {localAppPath, programFiles})
|
||||||
{
|
{
|
||||||
candidates.Add(IOPath.Combine(basePath, "Microsoft VS Code", "Code.exe"));
|
|
||||||
candidates.Add(IOPath.Combine(basePath, "Microsoft VS Code Insiders", "Code - Insiders.exe"));
|
candidates.Add(IOPath.Combine(basePath, "Microsoft VS Code Insiders", "Code - Insiders.exe"));
|
||||||
}
|
}
|
||||||
#elif UNITY_EDITOR_OSX
|
#elif UNITY_EDITOR_OSX
|
||||||
var appPath = IOPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles));
|
var appPath = IOPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles));
|
||||||
candidates.AddRange(Directory.EnumerateDirectories(appPath, "Visual Studio Code*.app"));
|
candidates.AddRange(Directory.EnumerateDirectories(appPath, "Cursor*.app"));
|
||||||
#elif UNITY_EDITOR_LINUX
|
#elif UNITY_EDITOR_LINUX
|
||||||
// Well known locations
|
// Well known locations
|
||||||
candidates.Add("/usr/bin/code");
|
candidates.Add("/usr/bin/cursor");
|
||||||
candidates.Add("/bin/code");
|
candidates.Add("/bin/cursor");
|
||||||
candidates.Add("/usr/local/bin/code");
|
candidates.Add("/usr/local/bin/cursor");
|
||||||
|
|
||||||
// Preference ordered base directories relative to which desktop files should be searched
|
// Preference ordered base directories relative to which desktop files should be searched
|
||||||
candidates.AddRange(GetXdgCandidates());
|
candidates.AddRange(GetXdgCandidates());
|
||||||
@@ -243,7 +243,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
}
|
}
|
||||||
catch (IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string DefaultLaunchFileContent = @"{
|
private const string DefaultLaunchFileContent = @"{
|
||||||
@@ -440,7 +440,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
private const string MicrosoftUnityExtensionId = "visualstudiotoolsforunity.vstuc";
|
private const string MicrosoftUnityExtensionId = "visualstudiotoolsforunity.vstuc";
|
||||||
private const string DefaultRecommendedExtensionsContent = @"{
|
private const string DefaultRecommendedExtensionsContent = @"{
|
||||||
""recommendations"": [
|
""recommendations"": [
|
||||||
"""+ MicrosoftUnityExtensionId + @"""
|
""" + MicrosoftUnityExtensionId + @"""
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
@@ -506,7 +506,7 @@ namespace Microsoft.Unity.VisualStudio.Editor
|
|||||||
var directory = IOPath.GetDirectoryName(solution);
|
var directory = IOPath.GetDirectoryName(solution);
|
||||||
var application = Path;
|
var application = Path;
|
||||||
|
|
||||||
ProcessRunner.Start(string.IsNullOrEmpty(path) ?
|
ProcessRunner.Start(string.IsNullOrEmpty(path) ?
|
||||||
ProcessStartInfoFor(application, $"\"{directory}\"") :
|
ProcessStartInfoFor(application, $"\"{directory}\"") :
|
||||||
ProcessStartInfoFor(application, $"\"{directory}\" -g \"{path}\":{line}:{column}"));
|
ProcessStartInfoFor(application, $"\"{directory}\" -g \"{path}\":{line}:{column}"));
|
||||||
|
|
||||||
|
|||||||
@@ -1,181 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if UNITY_EDITOR_OSX
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Unity.CodeEditor;
|
|
||||||
using IOPath = System.IO.Path;
|
|
||||||
|
|
||||||
namespace Microsoft.Unity.VisualStudio.Editor
|
|
||||||
{
|
|
||||||
internal class VisualStudioForMacInstallation : VisualStudioInstallation
|
|
||||||
{
|
|
||||||
// C# language version support for Visual Studio for Mac
|
|
||||||
private static readonly 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),
|
|
||||||
new VersionPair(8,0, /* => */ 7,3),
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly IGenerator _generator = new LegacyStyleProjectGeneration();
|
|
||||||
|
|
||||||
public override bool SupportsAnalyzers
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Version >= new Version(8, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Version LatestLanguageVersionSupported
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return GetLatestLanguageVersionSupported(OSXVersionTable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetExtensionPath()
|
|
||||||
{
|
|
||||||
const string addinName = "MonoDevelop.Unity";
|
|
||||||
const string addinAssembly = addinName + ".dll";
|
|
||||||
|
|
||||||
// user addins repository
|
|
||||||
var localAddins = IOPath.Combine(
|
|
||||||
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
|
|
||||||
$"Library/Application Support/VisualStudio/${Version.Major}.0" + "/LocalInstall/Addins");
|
|
||||||
|
|
||||||
// In the user addins repository, the addins are suffixed by their versions, like `MonoDevelop.Unity.1.0`
|
|
||||||
// When installing another local user addin, MD will remove files inside the folder
|
|
||||||
// So we browse all VSTUM addins, and return the one with an addin assembly
|
|
||||||
if (Directory.Exists(localAddins))
|
|
||||||
{
|
|
||||||
foreach (var folder in Directory.GetDirectories(localAddins, addinName + "*", SearchOption.TopDirectoryOnly))
|
|
||||||
{
|
|
||||||
if (File.Exists(IOPath.Combine(folder, addinAssembly)))
|
|
||||||
return folder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check in Visual Studio.app/
|
|
||||||
// In that case the name of the addin is used
|
|
||||||
var addinPath = IOPath.Combine(Path, $"Contents/Resources/lib/monodevelop/AddIns/{addinName}");
|
|
||||||
if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
|
|
||||||
return addinPath;
|
|
||||||
|
|
||||||
addinPath = IOPath.Combine(Path, $"Contents/MonoBundle/Addins/{addinName}");
|
|
||||||
if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
|
|
||||||
return addinPath;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string[] GetAnalyzers()
|
|
||||||
{
|
|
||||||
var vstuPath = GetExtensionPath();
|
|
||||||
if (string.IsNullOrEmpty(vstuPath))
|
|
||||||
return Array.Empty<string>();
|
|
||||||
|
|
||||||
return GetAnalyzers(vstuPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IGenerator ProjectGenerator
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _generator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsCandidateForDiscovery(string path)
|
|
||||||
{
|
|
||||||
return Directory.Exists(path) && Regex.IsMatch(path, "Visual\\s?Studio(?!.*Code.*).*.app$", RegexOptions.IgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryDiscoverInstallation(string editorPath, out IVisualStudioInstallation installation)
|
|
||||||
{
|
|
||||||
installation = null;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(editorPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!IsCandidateForDiscovery(editorPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// On Mac we use the .app folder, so we need to access to main assembly
|
|
||||||
var fvi = IOPath.Combine(editorPath, "Contents/Resources/lib/monodevelop/bin/VisualStudio.exe");
|
|
||||||
|
|
||||||
if (!File.Exists(fvi))
|
|
||||||
fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.exe");
|
|
||||||
|
|
||||||
if (!File.Exists(fvi))
|
|
||||||
fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.dll");
|
|
||||||
|
|
||||||
if (!File.Exists(fvi))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// VS preview are not using the isPrerelease flag so far
|
|
||||||
// On Windows FileDescription contains "Preview", but not on Mac
|
|
||||||
var vi = FileVersionInfo.GetVersionInfo(fvi);
|
|
||||||
var version = new Version(vi.ProductVersion);
|
|
||||||
var isPrerelease = vi.IsPreRelease || string.Concat(editorPath, "/" + vi.FileDescription).ToLower().Contains("preview");
|
|
||||||
|
|
||||||
installation = new VisualStudioForMacInstallation()
|
|
||||||
{
|
|
||||||
IsPrerelease = isPrerelease,
|
|
||||||
Name = $"{vi.FileDescription}{(isPrerelease ? " Preview" : string.Empty)} [{version.ToString(3)}]",
|
|
||||||
Path = editorPath,
|
|
||||||
Version = version
|
|
||||||
};
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
|
|
||||||
{
|
|
||||||
var candidates = Directory.EnumerateDirectories("/Applications", "*.app");
|
|
||||||
foreach (var candidate in candidates)
|
|
||||||
{
|
|
||||||
if (TryDiscoverInstallation(candidate, out var installation))
|
|
||||||
yield return installation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("AppleEventIntegration")]
|
|
||||||
private static extern bool OpenVisualStudio(string appPath, string solutionPath, string filePath, int line);
|
|
||||||
|
|
||||||
public override void CreateExtraFiles(string projectDirectory)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Open(string path, int line, int column, string solution)
|
|
||||||
{
|
|
||||||
string absolutePath = "";
|
|
||||||
if (!string.IsNullOrWhiteSpace(path))
|
|
||||||
{
|
|
||||||
absolutePath = IOPath.GetFullPath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return OpenVisualStudio(CodeEditor.CurrentEditorInstallation, solution, absolutePath, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Initialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2c64241ee5e302b478d7f2522bbaa4e3
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,380 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if UNITY_EDITOR_WIN
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
using Unity.CodeEditor;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using Debug = UnityEngine.Debug;
|
|
||||||
using IOPath = System.IO.Path;
|
|
||||||
|
|
||||||
namespace Microsoft.Unity.VisualStudio.Editor
|
|
||||||
{
|
|
||||||
internal class VisualStudioForWindowsInstallation : VisualStudioInstallation
|
|
||||||
{
|
|
||||||
// C# language version support for Visual Studio
|
|
||||||
private static readonly 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),
|
|
||||||
|
|
||||||
// VisualStudio 2017
|
|
||||||
new VersionPair(15,7, /* => */ 7,3),
|
|
||||||
new VersionPair(15,5, /* => */ 7,2),
|
|
||||||
new VersionPair(15,3, /* => */ 7,1),
|
|
||||||
new VersionPair(15,0, /* => */ 7,0),
|
|
||||||
};
|
|
||||||
|
|
||||||
private static string _vsWherePath = null;
|
|
||||||
private static readonly IGenerator _generator = new LegacyStyleProjectGeneration();
|
|
||||||
|
|
||||||
public override bool SupportsAnalyzers
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Version >= new Version(16, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Version LatestLanguageVersionSupported
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return GetLatestLanguageVersionSupported(WindowsVersionTable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ReadRegistry(RegistryKey hive, string keyName, string valueName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var unitykey = hive.OpenSubKey(keyName);
|
|
||||||
|
|
||||||
var result = (string)unitykey?.GetValue(valueName);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetWindowsBridgeFromRegistry()
|
|
||||||
{
|
|
||||||
var keyName = $"Software\\Microsoft\\Microsoft Visual Studio {Version.Major}.0 Tools for Unity";
|
|
||||||
const string valueName = "UnityExtensionPath";
|
|
||||||
|
|
||||||
var bridge = ReadRegistry(Registry.CurrentUser, keyName, valueName);
|
|
||||||
if (string.IsNullOrEmpty(bridge))
|
|
||||||
bridge = ReadRegistry(Registry.LocalMachine, keyName, valueName);
|
|
||||||
|
|
||||||
return bridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetExtensionPath()
|
|
||||||
{
|
|
||||||
const string extensionName = "Visual Studio Tools for Unity";
|
|
||||||
const string extensionAssembly = "SyntaxTree.VisualStudio.Unity.dll";
|
|
||||||
|
|
||||||
var vsDirectory = IOPath.GetDirectoryName(Path);
|
|
||||||
var vstuDirectory = IOPath.Combine(vsDirectory, "Extensions", "Microsoft", extensionName);
|
|
||||||
|
|
||||||
if (File.Exists(IOPath.Combine(vstuDirectory, extensionAssembly)))
|
|
||||||
return vstuDirectory;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string[] GetAnalyzers()
|
|
||||||
{
|
|
||||||
var vstuPath = GetExtensionPath();
|
|
||||||
if (string.IsNullOrEmpty(vstuPath))
|
|
||||||
return Array.Empty<string>();
|
|
||||||
|
|
||||||
var analyzers = GetAnalyzers(vstuPath);
|
|
||||||
if (analyzers?.Length > 0)
|
|
||||||
return analyzers;
|
|
||||||
|
|
||||||
var bridge = GetWindowsBridgeFromRegistry();
|
|
||||||
if (File.Exists(bridge))
|
|
||||||
return GetAnalyzers(IOPath.Combine(IOPath.GetDirectoryName(bridge), ".."));
|
|
||||||
|
|
||||||
return Array.Empty<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IGenerator ProjectGenerator
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _generator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsCandidateForDiscovery(string path)
|
|
||||||
{
|
|
||||||
return File.Exists(path) && Regex.IsMatch(path, "devenv.exe$", RegexOptions.IgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryDiscoverInstallation(string editorPath, out IVisualStudioInstallation installation)
|
|
||||||
{
|
|
||||||
installation = null;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(editorPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!IsCandidateForDiscovery(editorPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// On windows we use the executable directly, so we can query extra information
|
|
||||||
if (!File.Exists(editorPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// VS preview are not using the isPrerelease flag so far
|
|
||||||
// On Windows FileDescription contains "Preview", but not on Mac
|
|
||||||
var vi = FileVersionInfo.GetVersionInfo(editorPath);
|
|
||||||
var version = new Version(vi.ProductVersion);
|
|
||||||
var isPrerelease = vi.IsPreRelease || string.Concat(editorPath, "/" + vi.FileDescription).ToLower().Contains("preview");
|
|
||||||
|
|
||||||
installation = new VisualStudioForWindowsInstallation()
|
|
||||||
{
|
|
||||||
IsPrerelease = isPrerelease,
|
|
||||||
Name = $"{FormatProductName(vi.FileDescription)} [{version.ToString(3)}]",
|
|
||||||
Path = editorPath,
|
|
||||||
Version = version
|
|
||||||
};
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string FormatProductName(string productName)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(productName))
|
|
||||||
return string.Empty;
|
|
||||||
|
|
||||||
return productName.Replace("Microsoft ", string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
|
|
||||||
{
|
|
||||||
foreach (var installation in QueryVsWhere())
|
|
||||||
yield return installation;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region VsWhere Json Schema
|
|
||||||
#pragma warning disable CS0649
|
|
||||||
[Serializable]
|
|
||||||
internal class VsWhereResult
|
|
||||||
{
|
|
||||||
public VsWhereEntry[] entries;
|
|
||||||
|
|
||||||
public static VsWhereResult FromJson(string json)
|
|
||||||
{
|
|
||||||
return JsonUtility.FromJson<VsWhereResult>("{ \"" + nameof(VsWhereResult.entries) + "\": " + json + " }");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<VisualStudioInstallation> ToVisualStudioInstallations()
|
|
||||||
{
|
|
||||||
foreach (var entry in entries)
|
|
||||||
{
|
|
||||||
yield return new VisualStudioForWindowsInstallation
|
|
||||||
{
|
|
||||||
Name = $"{FormatProductName(entry.displayName)} [{entry.catalog.productDisplayVersion}]",
|
|
||||||
Path = entry.productPath,
|
|
||||||
IsPrerelease = entry.isPrerelease,
|
|
||||||
Version = Version.Parse(entry.catalog.buildVersion)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
internal class VsWhereEntry
|
|
||||||
{
|
|
||||||
public string displayName;
|
|
||||||
public bool isPrerelease;
|
|
||||||
public string productPath;
|
|
||||||
public VsWhereCatalog catalog;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
internal class VsWhereCatalog
|
|
||||||
{
|
|
||||||
public string productDisplayVersion; // non parseable like "16.3.0 Preview 3.0"
|
|
||||||
public string buildVersion;
|
|
||||||
}
|
|
||||||
#pragma warning restore CS3021
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private static IEnumerable<VisualStudioInstallation> QueryVsWhere()
|
|
||||||
{
|
|
||||||
var progpath = _vsWherePath;
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(progpath))
|
|
||||||
return Enumerable.Empty<VisualStudioInstallation>();
|
|
||||||
|
|
||||||
const string arguments = "-prerelease -format json";
|
|
||||||
|
|
||||||
// We've seen issues with json parsing in utf8 mode and with specific non-UTF code pages like 949 (Korea)
|
|
||||||
// So try with utf8 first, then fallback to non utf8 in case of an issue
|
|
||||||
// See https://github.com/microsoft/vswhere/issues/264
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return QueryVsWhere(progpath, $"{arguments} -utf8");
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return QueryVsWhere(progpath, $"{arguments}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<VisualStudioInstallation> QueryVsWhere(string progpath, string arguments)
|
|
||||||
{
|
|
||||||
var result = ProcessRunner.StartAndWaitForExit(progpath, arguments);
|
|
||||||
|
|
||||||
if (!result.Success)
|
|
||||||
throw new Exception($"Failure while running vswhere: {result.Error}");
|
|
||||||
|
|
||||||
// Do not catch any JsonException here, this will be handled by the caller
|
|
||||||
return VsWhereResult
|
|
||||||
.FromJson(result.Output)
|
|
||||||
.ToVisualStudioInstallations();
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum COMIntegrationState
|
|
||||||
{
|
|
||||||
Running,
|
|
||||||
DisplayProgressBar,
|
|
||||||
ClearProgressBar,
|
|
||||||
Exited
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CreateExtraFiles(string projectDirectory)
|
|
||||||
{
|
|
||||||
// See https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/
|
|
||||||
// We create a .vsconfig file to make sure our ManagedGame workload is installed
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var vsConfigFile = IOPath.Combine(projectDirectory.NormalizePathSeparators(), ".vsconfig");
|
|
||||||
if (File.Exists(vsConfigFile))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const string content = @"{
|
|
||||||
""version"": ""1.0"",
|
|
||||||
""components"": [
|
|
||||||
""Microsoft.VisualStudio.Workload.ManagedGame""
|
|
||||||
]
|
|
||||||
}
|
|
||||||
";
|
|
||||||
File.WriteAllText(vsConfigFile, content);
|
|
||||||
}
|
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Open(string path, int line, int column, string solution)
|
|
||||||
{
|
|
||||||
var progpath = FileUtility.GetPackageAssetFullPath("Editor", "COMIntegration", "Release", "COMIntegration.exe");
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(progpath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string absolutePath = "";
|
|
||||||
if (!string.IsNullOrWhiteSpace(path))
|
|
||||||
{
|
|
||||||
absolutePath = IOPath.GetFullPath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We remove all invalid chars from the solution filename, but we cannot prevent the user from using a specific path for the Unity project
|
|
||||||
// So process the fullpath to make it compatible with VS
|
|
||||||
if (!string.IsNullOrWhiteSpace(solution))
|
|
||||||
{
|
|
||||||
solution = $"\"{solution}\"";
|
|
||||||
solution = solution.Replace("^", "^^");
|
|
||||||
}
|
|
||||||
|
|
||||||
var psi = ProcessRunner.ProcessStartInfoFor(progpath, $"\"{CodeEditor.CurrentEditorInstallation}\" {solution} \"{absolutePath}\" {line}");
|
|
||||||
psi.StandardOutputEncoding = System.Text.Encoding.Unicode;
|
|
||||||
psi.StandardErrorEncoding = System.Text.Encoding.Unicode;
|
|
||||||
|
|
||||||
// inter thread communication
|
|
||||||
var messages = new BlockingCollection<COMIntegrationState>();
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Initialize()
|
|
||||||
{
|
|
||||||
_vsWherePath = FileUtility.GetPackageAssetFullPath("Editor", "VSWhere", "vswhere.exe");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: be7ef402265a7a549b2e43c11d1a22c5
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "com.unity.ide.visualstudio",
|
"name": "com.unity.ide.cursor",
|
||||||
"displayName": "Visual Studio Editor",
|
"displayName": "Cursor 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.",
|
"description": "Code editor integration for supporting Cursor as code editor for unity. Adds support for generating csproj files for intellisense purposes, auto discovery of installations, etc.",
|
||||||
"version": "2.0.22",
|
"version": "2.0.22",
|
||||||
"unity": "2019.4",
|
"unity": "2019.4",
|
||||||
"unityRelease": "25f1",
|
"unityRelease": "25f1",
|
||||||
@@ -23,4 +23,4 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"revision": "700b44077345e97d37d464ff25507638983aed64"
|
"revision": "700b44077345e97d37d464ff25507638983aed64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user