A game about forced loneliness, made by TACStudios
at master 5.5 kB view raw
1/*--------------------------------------------------------------------------------------------- 2 * Copyright (c) Microsoft Corporation. All rights reserved. 3 * Licensed under the MIT License. See License.txt in the project root for license information. 4 *--------------------------------------------------------------------------------------------*/ 5 6#if UNITY_EDITOR_OSX 7 8using System; 9using System.Collections.Generic; 10using System.Diagnostics; 11using System.IO; 12using System.Runtime.InteropServices; 13using System.Text.RegularExpressions; 14using Unity.CodeEditor; 15using IOPath = System.IO.Path; 16 17namespace Microsoft.Unity.VisualStudio.Editor 18{ 19 internal class VisualStudioForMacInstallation : VisualStudioInstallation 20 { 21 // C# language version support for Visual Studio for Mac 22 private static readonly VersionPair[] OSXVersionTable = 23 { 24 // VisualStudio for Mac 2022 25 new VersionPair(17,4, /* => */ 11,0), 26 new VersionPair(17,0, /* => */ 10,0), 27 28 // VisualStudio for Mac 8.x 29 new VersionPair(8,8, /* => */ 9,0), 30 new VersionPair(8,3, /* => */ 8,0), 31 new VersionPair(8,0, /* => */ 7,3), 32 }; 33 34 private static readonly IGenerator _generator = new LegacyStyleProjectGeneration(); 35 36 public override bool SupportsAnalyzers 37 { 38 get 39 { 40 return Version >= new Version(8, 3); 41 } 42 } 43 44 public override Version LatestLanguageVersionSupported 45 { 46 get 47 { 48 return GetLatestLanguageVersionSupported(OSXVersionTable); 49 } 50 } 51 52 private string GetExtensionPath() 53 { 54 const string addinName = "MonoDevelop.Unity"; 55 const string addinAssembly = addinName + ".dll"; 56 57 // user addins repository 58 var localAddins = IOPath.Combine( 59 Environment.GetFolderPath(Environment.SpecialFolder.Personal), 60 $"Library/Application Support/VisualStudio/${Version.Major}.0" + "/LocalInstall/Addins"); 61 62 // In the user addins repository, the addins are suffixed by their versions, like `MonoDevelop.Unity.1.0` 63 // When installing another local user addin, MD will remove files inside the folder 64 // So we browse all VSTUM addins, and return the one with an addin assembly 65 if (Directory.Exists(localAddins)) 66 { 67 foreach (var folder in Directory.GetDirectories(localAddins, addinName + "*", SearchOption.TopDirectoryOnly)) 68 { 69 if (File.Exists(IOPath.Combine(folder, addinAssembly))) 70 return folder; 71 } 72 } 73 74 // Check in Visual Studio.app/ 75 // In that case the name of the addin is used 76 var addinPath = IOPath.Combine(Path, $"Contents/Resources/lib/monodevelop/AddIns/{addinName}"); 77 if (File.Exists(IOPath.Combine(addinPath, addinAssembly))) 78 return addinPath; 79 80 addinPath = IOPath.Combine(Path, $"Contents/MonoBundle/Addins/{addinName}"); 81 if (File.Exists(IOPath.Combine(addinPath, addinAssembly))) 82 return addinPath; 83 84 return null; 85 } 86 87 public override string[] GetAnalyzers() 88 { 89 var vstuPath = GetExtensionPath(); 90 if (string.IsNullOrEmpty(vstuPath)) 91 return Array.Empty<string>(); 92 93 return GetAnalyzers(vstuPath); 94 } 95 96 public override IGenerator ProjectGenerator 97 { 98 get 99 { 100 return _generator; 101 } 102 } 103 104 private static bool IsCandidateForDiscovery(string path) 105 { 106 return Directory.Exists(path) && Regex.IsMatch(path, "Visual\\s?Studio(?!.*Code.*).*.app$", RegexOptions.IgnoreCase); 107 } 108 109 public static bool TryDiscoverInstallation(string editorPath, out IVisualStudioInstallation installation) 110 { 111 installation = null; 112 113 if (string.IsNullOrEmpty(editorPath)) 114 return false; 115 116 if (!IsCandidateForDiscovery(editorPath)) 117 return false; 118 119 // On Mac we use the .app folder, so we need to access to main assembly 120 var fvi = IOPath.Combine(editorPath, "Contents/Resources/lib/monodevelop/bin/VisualStudio.exe"); 121 122 if (!File.Exists(fvi)) 123 fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.exe"); 124 125 if (!File.Exists(fvi)) 126 fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.dll"); 127 128 if (!File.Exists(fvi)) 129 return false; 130 131 // VS preview are not using the isPrerelease flag so far 132 // On Windows FileDescription contains "Preview", but not on Mac 133 var vi = FileVersionInfo.GetVersionInfo(fvi); 134 var version = new Version(vi.ProductVersion); 135 var isPrerelease = vi.IsPreRelease || string.Concat(editorPath, "/" + vi.FileDescription).ToLower().Contains("preview"); 136 137 installation = new VisualStudioForMacInstallation() 138 { 139 IsPrerelease = isPrerelease, 140 Name = $"{vi.FileDescription}{(isPrerelease ? " Preview" : string.Empty)} [{version.ToString(3)}]", 141 Path = editorPath, 142 Version = version 143 }; 144 return true; 145 } 146 147 public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations() 148 { 149 var candidates = Directory.EnumerateDirectories("/Applications", "*.app"); 150 foreach (var candidate in candidates) 151 { 152 if (TryDiscoverInstallation(candidate, out var installation)) 153 yield return installation; 154 } 155 } 156 157 [DllImport("AppleEventIntegration")] 158 private static extern bool OpenVisualStudio(string appPath, string solutionPath, string filePath, int line); 159 160 public override void CreateExtraFiles(string projectDirectory) 161 { 162 } 163 164 public override bool Open(string path, int line, int column, string solution) 165 { 166 string absolutePath = ""; 167 if (!string.IsNullOrWhiteSpace(path)) 168 { 169 absolutePath = IOPath.GetFullPath(path); 170 } 171 172 return OpenVisualStudio(CodeEditor.CurrentEditorInstallation, solution, absolutePath, line); 173 } 174 175 public static void Initialize() 176 { 177 } 178 } 179} 180 181#endif