diff --git a/src/VsixTesting.Installer/Program.cs b/src/VsixTesting.Installer/Program.cs index 7ba11ff..a093d2e 100644 --- a/src/VsixTesting.Installer/Program.cs +++ b/src/VsixTesting.Installer/Program.cs @@ -25,13 +25,36 @@ internal class Program : MarshalByRefObject [STAThread] public static int Main(string[] args) { - var applicationPath = CommandLineParser.One(args, "ApplicationPath"); + var applicationPath = CommandLineParser.One(args, "ApplicationPath", string.Empty); var rootSuffix = CommandLineParser.One(args, "RootSuffix", string.Empty); + + if (string.IsNullOrEmpty(applicationPath)) + { + var version = CommandLineParser.One(args, "Version"); + var sku = CommandLineParser.One(args, "SKU", string.Empty); + var preview = CommandLineParser.Contains(args, "Preview"); + var installations = VisualStudioUtil.FindInstallations(); + applicationPath = GetInstallation(installations, version, sku, preview).ApplicationPath; + } + var appDomain = CreateAppDomain(applicationPath); var program = appDomain.CreateInstanceFromAndUnwrap(); return program.Run(applicationPath, rootSuffix, args); } + internal static VsInstallation GetInstallation(IEnumerable installations, string versionRange, string sku, bool preview) + { + var version = VersionRange.Parse(versionRange).Minimum; + var year = VersionUtil.GetYear(version); + + return installations. + Where(i => i.Version.Major == version.Major) + .OrderByDescending(i => i.ProductId.Split('.').Last().Equals(sku, StringComparison.OrdinalIgnoreCase)) + .ThenByDescending(i => i.Preview == preview) + .FirstOrDefault() + ?? throw new Exception($"Please install Visual Studio {year}."); + } + private int Run(string applicationPath, string rootSuffix, string[] args) { try diff --git a/src/VsixTesting.Installer/Properties/launchSettings.json b/src/VsixTesting.Installer/Properties/launchSettings.json index 37580ef..0998bf5 100644 --- a/src/VsixTesting.Installer/Properties/launchSettings.json +++ b/src/VsixTesting.Installer/Properties/launchSettings.json @@ -18,19 +18,19 @@ }, "VsixTesting.Installer.2012.Install": { "commandName": "Project", - "commandLineArgs": "/ApplicationPath \"C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\Common7\\IDE\\devenv.exe\" /RootSuffix Exp /Install \"$(SolutionDir)bin\\VsixTesting.Invoker\\$(Configuration)\\net452\\VsixTesting.Invoker.vsix\"" + "commandLineArgs": "/Version 2012 /RootSuffix Exp /Install \"$(SolutionDir)bin\\VsixTesting.Invoker\\$(Configuration)\\net452\\VsixTesting.Invoker.vsix\"" }, "VsixTesting.Installer.2012.InstallAndStart": { "commandName": "Project", - "commandLineArgs": "/ApplicationPath \"C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\Common7\\IDE\\devenv.exe\" /RootSuffix Exp /InstallAndStart \"$(SolutionDir)bin\\VsixTesting.Invoker\\$(Configuration)\\net452\\VsixTesting.Invoker.vsix\"" + "commandLineArgs": "/Version 2012 /RootSuffix Exp /InstallAndStart \"$(SolutionDir)bin\\VsixTesting.Invoker\\$(Configuration)\\net452\\VsixTesting.Invoker.vsix\"" }, "VsixTesting.Installer.2012.Uninstall": { "commandName": "Project", - "commandLineArgs": "/ApplicationPath \"C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\Common7\\IDE\\devenv.exe\" /RootSuffix Exp /Uninstall 9eef3d53-333f-4be2-900e-a1f104fc325a" + "commandLineArgs": "/Version 2012 /RootSuffix Exp /Uninstall 9eef3d53-333f-4be2-900e-a1f104fc325a" }, "VsixTesting.Installer.2012.IsProfileInitialized": { "commandName": "Project", - "commandLineArgs": "/ApplicationPath \"C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\Common7\\IDE\\devenv.exe\" /RootSuffix Exp /IsProfileInitialized" - } + "commandLineArgs": "/Version 2012 /RootSuffix Exp /IsProfileInitialized" + }, } } \ No newline at end of file diff --git a/src/VsixTesting.Xunit/Internal/VsTestCaseFactory.cs b/src/VsixTesting.Xunit/Internal/VsTestCaseFactory.cs index 1722b80..2e4edd2 100644 --- a/src/VsixTesting.Xunit/Internal/VsTestCaseFactory.cs +++ b/src/VsixTesting.Xunit/Internal/VsTestCaseFactory.cs @@ -91,7 +91,7 @@ internal static IEnumerable FilterInstallations(IEnumerable !i.ApplicationPath.Equals(preferedAppPath, StringComparison.OrdinalIgnoreCase)) - .ThenBy(i => i.Name.Contains("-pre"))) + .ThenBy(i => i.Preview)) { if (!settings.SupportedVersionRanges.Any(range => installation.Version >= range.Minimum && installation.Version <= range.Maximum)) { diff --git a/src/VsixTesting/Vs/VersionUtil.cs b/src/VsixTesting/Vs/VersionUtil.cs index 5b34858..b236a7d 100644 --- a/src/VsixTesting/Vs/VersionUtil.cs +++ b/src/VsixTesting/Vs/VersionUtil.cs @@ -16,7 +16,7 @@ public static int GetYear(Version version) case 15: return 2017; } - throw new ArgumentOutOfRangeException(nameof(version)); + throw new ArgumentOutOfRangeException(nameof(version), $"Visual Studio {version.Major} is not supported."); } public static Version FromYear(int year) @@ -27,8 +27,9 @@ public static Version FromYear(int year) case 2013: return new Version(12, 0); case 2015: return new Version(14, 0); case 2017: return new Version(15, 0); - default: throw new ArgumentOutOfRangeException(nameof(year), $"VS{year} is not supported."); } + + throw new ArgumentOutOfRangeException(nameof(year), $"Visual Studio {year} is not supported."); } } } diff --git a/src/VsixTesting/Vs/VisualStudioUtil.cs b/src/VsixTesting/Vs/VisualStudioUtil.cs index cf61c0d..3f44af9 100644 --- a/src/VsixTesting/Vs/VisualStudioUtil.cs +++ b/src/VsixTesting/Vs/VisualStudioUtil.cs @@ -7,14 +7,12 @@ namespace Vs using System.Diagnostics; using System.IO; using System.Linq; - using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using Common; using EnvDTE80; using Microsoft.VisualStudio.Setup.Configuration; using Microsoft.Win32; - using VsixTesting.Utilities; using DTE = EnvDTE.DTE; internal static partial class VisualStudioUtil @@ -129,6 +127,7 @@ public static IEnumerable FindInstallations() path: instance.GetInstallationPath()) { PackageIds = instance.GetPackages().Select(p => p.GetId()), + ProductId = instance.GetProduct().GetId(), }; } } diff --git a/src/VsixTesting/Vs/VsInstallation.cs b/src/VsixTesting/Vs/VsInstallation.cs index 7cfcdf8..ad8a6c1 100644 --- a/src/VsixTesting/Vs/VsInstallation.cs +++ b/src/VsixTesting/Vs/VsInstallation.cs @@ -16,8 +16,10 @@ public VsInstallation(Version version, string path, string name) } public Version Version { get; } + public bool Preview => Name.Contains("-pre"); public string Path { get; } public string Name { get; } + public string ProductId { get; set; } = string.Empty; public string ApplicationPath => VisualStudioUtil.GetApplicationPath(Path); public IEnumerable PackageIds { get; set; } = Enumerable.Empty(); } diff --git a/test/VsixTesting.Installer.Tests/ProgramTests.cs b/test/VsixTesting.Installer.Tests/ProgramTests.cs new file mode 100644 index 0000000..4342656 --- /dev/null +++ b/test/VsixTesting.Installer.Tests/ProgramTests.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2018 Jose Torres. All rights reserved. Licensed under the Apache License, Version 2.0. See LICENSE.md file in the project root for full license information. + +namespace VsixTesting.Installer.Tests +{ + using System; + using Vs; + using Xunit; + + public class ProgramTests + { + private const string CommunityId = "Microsoft.VisualStudio.Product.Community"; + private const string ProfessionalId = "Microsoft.VisualStudio.Product.Professional"; + private const string EnterpriseId = "Microsoft.VisualStudio.Product.Enterprise"; + + [Theory] + [InlineData("2017", null, false, CommunityId)] + [InlineData("15.0", null, false, CommunityId)] + [InlineData("15", null, false, CommunityId)] + [InlineData("2017", null, true, ProfessionalId)] + [InlineData("2017", "Community", false, CommunityId)] + [InlineData("2017", "Community", true, CommunityId)] + [InlineData("2017", "Professional", false, ProfessionalId)] + [InlineData("2017", "Professional", true, ProfessionalId)] + void GetInstallation(string version, string sku, bool preview, string expected) + { + var installations = new[] + { + new VsInstallation(new Version(15, 0), string.Empty, "VisualStudio/15.0.0") { ProductId = CommunityId }, + new VsInstallation(new Version(15, 0), string.Empty, "VisualStudio/15.0.0-pre.1.0+27729.1") { ProductId = ProfessionalId }, + new VsInstallation(new Version(15, 1), string.Empty, "VisualStudio/15.0.1") { ProductId = EnterpriseId }, + }; + + Assert.Equal(expected, Program.GetInstallation(installations, version, sku, preview).ProductId); + } + } +}