From 37e7bc9539804703192860e8768ecfb4f55ff670 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 12 Sep 2016 10:32:35 -0700 Subject: [PATCH] Add Typescript Version Check **Bug** With NTVS 1.3, we will depend on TypeScript being installed. With VS15, this is enforced during instalation, but this dependency is not enforced in VS2015. However, we see the majority of users do have TypeScript installed. **Fix** Add runtime check to alert users if TypeScript is not installed. Closes #1259 --- Nodejs/Product/Nodejs/NodejsPackage.cs | 57 +++++++++++++++++++ .../Options/NodejsIntellisenseOptionsPage.cs | 38 ------------- .../Nodejs/Project/ProjectResources.cs | 1 + Nodejs/Product/Nodejs/Resources.resx | 3 + 4 files changed, 61 insertions(+), 38 deletions(-) diff --git a/Nodejs/Product/Nodejs/NodejsPackage.cs b/Nodejs/Product/Nodejs/NodejsPackage.cs index df3f0db19..fef6781b3 100644 --- a/Nodejs/Product/Nodejs/NodejsPackage.cs +++ b/Nodejs/Product/Nodejs/NodejsPackage.cs @@ -22,6 +22,7 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using System.Threading; using System.Web.Script.Serialization; using System.Windows.Forms; @@ -109,6 +110,16 @@ internal sealed partial class NodejsPackage : CommonPackage { // after the initialization private List _subscribedCommandEvents = new List(); + private static readonly Version _minRequiredTypescriptVersion = new Version("1.8"); + + private readonly Lazy _hasRequiredTypescriptVersion = new Lazy(() => { + Version version; + var versionString = GetTypeScriptToolsVersion(); + return !string.IsNullOrEmpty(versionString) + && Version.TryParse(versionString, out version) + && version.CompareTo(_minRequiredTypescriptVersion) > -1; + }); + /// /// Default constructor of the package. /// Inside this method you can place any initialization code that does not require @@ -188,6 +199,14 @@ protected override void Initialize() { Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString())); base.Initialize(); + if (!_hasRequiredTypescriptVersion.Value) { + MessageBox.Show( + Project.SR.GetString(Project.SR.TypeScriptMinVersionNotInstalled, _minRequiredTypescriptVersion.ToString()), + Project.SR.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + SubscribeToVsCommandEvents( (int)VSConstants.VSStd97CmdID.AddNewProject, delegate { NewProjectFromExistingWizard.IsAddNewProjectCmd = true; }, @@ -616,5 +635,43 @@ private void LogLooseFileAnalysisLevel() { _logger.LogEvent(NodejsToolsLogEvent.AnalysisLevel, (int)val); } } + + private static string GetTypeScriptToolsVersion() { + var toolsVersion = string.Empty; + try { + object installDirAsObject = null; + var shell = NodejsPackage.Instance.GetService(typeof(SVsShell)) as IVsShell; + if (shell != null) { + shell.GetProperty((int)__VSSPROPID.VSSPROPID_InstallDirectory, out installDirAsObject); + } + + var idePath = CommonUtils.NormalizeDirectoryPath((string)installDirAsObject) ?? string.Empty; + if (string.IsNullOrEmpty(idePath)) { + return toolsVersion; + } + + var typeScriptServicesPath = Path.Combine(idePath, @"CommonExtensions\Microsoft\TypeScript\typescriptServices.js"); + if (!File.Exists(typeScriptServicesPath)) { + return toolsVersion; + } + + var regex = new Regex(@"toolsVersion = ""(?\d.\d?)"";"); + var fileText = File.ReadAllText(typeScriptServicesPath); + var match = regex.Match(fileText); + + var version = match.Groups["version"].Value; + if (!string.IsNullOrWhiteSpace(version)) { + toolsVersion = version; + } + } catch (Exception ex) { + if (ex.IsCriticalException()) { + throw; + } + + Debug.WriteLine(string.Format("Failed to obtain TypeScript tools version: {0}", ex.ToString())); + } + + return toolsVersion; + } } } diff --git a/Nodejs/Product/Nodejs/Options/NodejsIntellisenseOptionsPage.cs b/Nodejs/Product/Nodejs/Options/NodejsIntellisenseOptionsPage.cs index b375379b4..086c93f64 100644 --- a/Nodejs/Product/Nodejs/Options/NodejsIntellisenseOptionsPage.cs +++ b/Nodejs/Product/Nodejs/Options/NodejsIntellisenseOptionsPage.cs @@ -88,43 +88,5 @@ public override void SaveSettingsToStorage() { SaveBool(ShowTypingsInfoBarSetting, ShowTypingsInfoBar); SaveBool(SaveChangesToConfigFileSetting, SaveChangesToConfigFile); } - - private static string GetTypeScriptToolsVersion() { - var toolsVersion = string.Empty; - try { - object installDirAsObject = null; - var shell = NodejsPackage.Instance.GetService(typeof(SVsShell)) as IVsShell; - if (shell != null) { - shell.GetProperty((int)__VSSPROPID.VSSPROPID_InstallDirectory, out installDirAsObject); - } - - var idePath = CommonUtils.NormalizeDirectoryPath((string)installDirAsObject) ?? string.Empty; - if (string.IsNullOrEmpty(idePath)) { - return toolsVersion; - } - - var typeScriptServicesPath = Path.Combine(idePath, @"CommonExtensions\Microsoft\TypeScript\typescriptServices.js"); - if (!File.Exists(typeScriptServicesPath)) { - return toolsVersion; - } - - var regex = new Regex(@"toolsVersion = ""(?\d.\d?)"";"); - var fileText = File.ReadAllText(typeScriptServicesPath); - var match = regex.Match(fileText); - - var version = match.Groups["version"].Value; - if (!string.IsNullOrWhiteSpace(version)) { - toolsVersion = version; - } - } catch (Exception ex) { - if (ex.IsCriticalException()) { - throw; - } - - Debug.WriteLine(string.Format("Failed to obtain TypeScript tools version: {0}", ex.ToString())); - } - - return toolsVersion; - } } } diff --git a/Nodejs/Product/Nodejs/Project/ProjectResources.cs b/Nodejs/Product/Nodejs/Project/ProjectResources.cs index 7baa5a599..aabd4af77 100644 --- a/Nodejs/Product/Nodejs/Project/ProjectResources.cs +++ b/Nodejs/Product/Nodejs/Project/ProjectResources.cs @@ -182,6 +182,7 @@ internal class SR : CommonSR { internal const string TypingsInfoBarSpan2 = "TypingsInfoBarSpan2"; internal const string TypingsInfoBarSpan3 = "TypingsInfoBarSpan3"; internal const string TypingsOpenOptionsText = "TypingsOpenOptionsText"; + internal const string TypeScriptMinVersionNotInstalled = "TypeScriptMinVersionNotInstalled"; internal const string TypingsToolCouldNotStart = "TypingsToolCouldNotStart"; internal const string TypingsToolInstallFailed = "TypingsToolInstallFailed"; internal const string TypingsToolNotInstalledError = "TypingsToolNotInstalledError"; diff --git a/Nodejs/Product/Nodejs/Resources.resx b/Nodejs/Product/Nodejs/Resources.resx index de03c6f9e..03b26ab9e 100644 --- a/Nodejs/Product/Nodejs/Resources.resx +++ b/Nodejs/Product/Nodejs/Resources.resx @@ -630,4 +630,7 @@ You will need to restart Visual Studio after installation. Could not retrieve Typescript language preferences. NTVS is not able to load. Please ensure Typescript is properly installed. + + Node.js Tools requires TypeScript for Visual Studio {0} or higher. Please ensure TypeScript is installed + \ No newline at end of file