99using System . IO ;
1010using System . Linq ;
1111using System . Text . RegularExpressions ;
12+ using UnityEngine ;
1213using IOPath = System . IO . Path ;
1314
1415namespace Microsoft . Unity . VisualStudio . Editor
@@ -52,7 +53,7 @@ public override string[] GetAnalyzers()
5253 if ( string . IsNullOrEmpty ( vstuPath ) )
5354 return Array . Empty < string > ( ) ;
5455
55- return GetAnalyzers ( vstuPath ) ; }
56+ return GetAnalyzers ( vstuPath ) ; }
5657
5758 public override IGenerator ProjectGenerator
5859 {
@@ -73,6 +74,13 @@ private static bool IsCandidateForDiscovery(string path)
7374 return File . Exists ( path ) && path . EndsWith ( "code" , StringComparison . OrdinalIgnoreCase ) ;
7475 }
7576
77+ [ Serializable ]
78+ internal class VisualStudioCodeManifest
79+ {
80+ public string name ;
81+ public string version ;
82+ }
83+
7684 public static bool TryDiscoverInstallation ( string editorPath , out IVisualStudioInstallation installation )
7785 {
7886 installation = null ;
@@ -84,28 +92,29 @@ public static bool TryDiscoverInstallation(string editorPath, out IVisualStudioI
8492 return false ;
8593
8694 Version version = null ;
87- bool isPrerelease = false ;
88-
89- if ( VisualStudioEditor . IsWindows ) {
90- // On windows we use the executable directly, so we can query extra information
91- if ( ! File . Exists ( editorPath ) )
92- return false ;
93-
94- // VSCode preview are not using the isPrerelease flag so far
95- var vi = FileVersionInfo . GetVersionInfo ( editorPath ) ;
96- version = new Version ( vi . ProductMajorPart , vi . ProductMinorPart , vi . ProductBuildPart ) ;
97- isPrerelease = vi . IsPreRelease || vi . FileDescription . ToLower ( ) . Contains ( "insider" ) ;
98- } else if ( VisualStudioEditor . IsOSX ) {
99- var plist = IOPath . Combine ( editorPath , "Contents" , "Info.plist" ) ;
100- if ( ! File . Exists ( plist ) )
101- return false ;
102-
103- const string pattern = @"<key>CFBundleShortVersionString</key>\s*<string>(?<version>\d+\.\d+\.\d+).*</string>" ;
104- var match = Regex . Match ( File . ReadAllText ( plist ) , pattern ) ;
105- if ( ! match . Success )
106- return false ;
107-
108- version = new Version ( match . Groups [ nameof ( version ) ] . ToString ( ) ) ;
95+ var isPrerelease = false ;
96+
97+ try
98+ {
99+ var manifestBase = editorPath ;
100+ if ( VisualStudioEditor . IsWindows ) // on Windows, editorPath is a file, resources as subdirectory
101+ manifestBase = IOPath . GetDirectoryName ( editorPath ) ;
102+ else if ( VisualStudioEditor . IsOSX ) // on Mac, editorPath is a directory
103+ manifestBase = editorPath ;
104+ else // on Linux, editorPath is a file, in a bin sub-directory
105+ manifestBase = Directory . GetParent ( editorPath ) . Parent . FullName ;
106+
107+ var manifestFullPath = IOPath . Combine ( manifestBase , @"resources" , "app" , "package.json" ) ;
108+ if ( File . Exists ( manifestFullPath ) )
109+ {
110+ var manifest = JsonUtility . FromJson < VisualStudioCodeManifest > ( File . ReadAllText ( manifestFullPath ) ) ;
111+ Version . TryParse ( manifest . version . Split ( '-' ) . First ( ) , out version ) ;
112+ isPrerelease = manifest . version . ToLower ( ) . Contains ( "insider" ) ;
113+ }
114+ }
115+ catch ( IOException )
116+ {
117+ // do not fail if we are not able to retrieve the exact version number
109118 }
110119
111120 isPrerelease = isPrerelease || editorPath . ToLower ( ) . Contains ( "insider" ) ;
@@ -141,6 +150,7 @@ public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallation
141150 }
142151 else
143152 {
153+ candidates . Add ( "/usr/share/code/bin/code" ) ;
144154 candidates . Add ( "/usr/bin/code" ) ;
145155 candidates . Add ( "/bin/code" ) ;
146156 candidates . Add ( "/usr/local/bin/code" ) ;
0 commit comments