Attach non-standard properties from instance

Also had to make a change to instance 2 to remove the errors because of a possible regression in the native query API. Issue #4 is tracking putting them back once the runtime bug is fixed
This commit is contained in:
Heath Stewart 2017-01-27 13:45:49 -08:00
Родитель 78a29e444e
Коммит 836b1309ff
16 изменённых файлов: 198 добавлений и 76 удалений

Просмотреть файл

@ -0,0 +1,33 @@
// <copyright file="Extensions.cs" company="Microsoft Corporation">
// Copyright (C) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt in the project root for license information.
// </copyright>
namespace Microsoft.VisualStudio.Setup
{
using System.Text;
/// <summary>
/// Extension methods.
/// </summary>
internal static class Extensions
{
/// <summary>
/// Converts a string to PascalCase.
/// </summary>
/// <param name="value">The string value to convert.</param>
/// <returns>If the string is not null or empty, a string converted to PascalCase; otherwise, the original string value.</returns>
public static string ToPascalCase(this string value)
{
if (!string.IsNullOrEmpty(value))
{
var sb = new StringBuilder(value);
sb[0] = char.ToUpperInvariant(sb[0]);
return sb.ToString();
}
return value;
}
}
}

Просмотреть файл

@ -11,6 +11,7 @@ namespace Microsoft.VisualStudio.Setup
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using Configuration;
@ -19,6 +20,8 @@ namespace Microsoft.VisualStudio.Setup
/// </summary>
public class Instance
{
private static readonly ISet<string> DeclaredProperties;
private readonly string installationName;
private readonly string installationPath;
private readonly Version installationVersion;
@ -30,6 +33,15 @@ namespace Microsoft.VisualStudio.Setup
private readonly PackageReference product;
private readonly IList<PackageReference> packages;
static Instance()
{
var properties = typeof(Instance)
.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
.Select(property => property.Name);
DeclaredProperties = new HashSet<string>(properties, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Initializes a new instance of the <see cref="Instance"/> class.
/// </summary>
@ -104,6 +116,12 @@ namespace Microsoft.VisualStudio.Setup
{
Packages = new ReadOnlyCollection<PackageReference>(packages);
}
// Get all properties of the instance not explicitly declared.
var store = (ISetupPropertyStore)instance;
AdditionalProperties = store.GetNames()
.Where(name => !DeclaredProperties.Contains(name))
.ToDictionary(name => name.ToPascalCase(), name => store.GetValue(name), StringComparer.OrdinalIgnoreCase);
}
/// <summary>
@ -161,6 +179,11 @@ namespace Microsoft.VisualStudio.Setup
/// </summary>
public ReadOnlyCollection<PackageReference> Packages { get; }
/// <summary>
/// Gets additional properties not explicitly defined on this class.
/// </summary>
internal IDictionary<string, object> AdditionalProperties { get; }
private static IEnumerable<PackageReference> GetPackages(ISetupInstance2 instance)
{
var references = instance.GetPackages();

Просмотреть файл

@ -17,8 +17,6 @@ namespace Microsoft.VisualStudio.Setup.PowerShell
/// </summary>
public class InstanceAdapter : PSPropertyAdapter
{
private static readonly string ObjectTypeName = typeof(object).FullName;
private static readonly string StringTypeName = typeof(string).FullName;
private static readonly string PSPathPropertyName = "PSPath";
private static readonly string FileSystemProviderPrefix = @"Microsoft.PowerShell.Core\FileSystem::";
@ -60,7 +58,10 @@ namespace Microsoft.VisualStudio.Setup.PowerShell
public override string GetPropertyTypeName(PSAdaptedProperty adaptedProperty)
{
var property = adaptedProperty.Tag as InstanceProperty;
return property.TypeName ?? ObjectTypeName;
var type = property?.Type ?? typeof(object);
// TODO: If upgrading to newer PowerShell version use LanguagePrimitives.ConvertTypeNameToPSTypeName.
return type.FullName;
}
/// <inheritdoc/>
@ -69,13 +70,23 @@ namespace Microsoft.VisualStudio.Setup.PowerShell
var instance = adaptedProperty.BaseObject as Instance;
if (instance != null)
{
if (string.Equals(adaptedProperty.Name, PSPathPropertyName, StringComparison.OrdinalIgnoreCase))
var name = adaptedProperty.Name;
if (string.Equals(name, PSPathPropertyName, StringComparison.OrdinalIgnoreCase))
{
return GetPSPath(instance);
}
object value = null;
var property = adaptedProperty.Tag as InstanceProperty;
return property?.Property?.GetValue(instance, null);
if (property?.Property != null)
{
return property.Property.GetValue(instance, null);
}
else if (instance.AdditionalProperties.TryGetValue(name, out value))
{
return value;
}
}
return null;
@ -115,14 +126,20 @@ namespace Microsoft.VisualStudio.Setup.PowerShell
private IEnumerable<PSAdaptedProperty> GetProperties(Instance instance)
{
yield return new PSAdaptedProperty("PSPath", new InstanceProperty { TypeName = StringTypeName });
yield return new PSAdaptedProperty("PSPath", new InstanceProperty { Type = typeof(string) });
var properties = instance.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
foreach (var property in properties)
{
var tag = new InstanceProperty { TypeName = property.PropertyType.FullName, Property = property };
var tag = new InstanceProperty { Type = property.PropertyType, Property = property };
yield return new PSAdaptedProperty(property.Name, tag);
}
foreach (var keyValue in instance.AdditionalProperties)
{
var tag = new InstanceProperty { Type = keyValue.Value?.GetType() ?? typeof(object) };
yield return new PSAdaptedProperty(keyValue.Key, tag);
}
}
private string GetPSPath(Instance instance)
@ -137,7 +154,7 @@ namespace Microsoft.VisualStudio.Setup.PowerShell
private class InstanceProperty
{
public string TypeName { get; set; }
public Type Type { get; set; }
public PropertyInfo Property { get; set; }
}

Просмотреть файл

@ -35,7 +35,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.Setup.Configuration.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Interop.1.3.269-rc\lib\net35\Microsoft.VisualStudio.Setup.Configuration.Interop.dll</HintPath>
<HintPath>..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Interop.1.4.174-rc\lib\net35\Microsoft.VisualStudio.Setup.Configuration.Interop.dll</HintPath>
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="System" />
@ -47,6 +47,7 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extensions.cs" />
<Compile Include="Instance.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="PackageReference.cs" />
@ -100,4 +101,4 @@
</Target>
<Import Project="..\..\packages\Nerdbank.GitVersioning.1.5.62\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\Nerdbank.GitVersioning.targets" Condition="Exists('..\..\packages\Nerdbank.GitVersioning.1.5.62\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\Nerdbank.GitVersioning.targets')" />
<Import Project="..\..\packages\NuProj.Common.0.11.14-beta\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\NuProj.Common.targets" Condition="Exists('..\..\packages\NuProj.Common.0.11.14-beta\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\NuProj.Common.targets')" />
</Project>
</Project>

Просмотреть файл

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.PowerShell.3.ReferenceAssemblies" version="1.0.0" targetFramework="net40-client" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Interop" version="1.3.269-rc" targetFramework="net40-client" developmentDependency="true" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Interop" version="1.4.174-rc" targetFramework="net40-client" developmentDependency="true" />
<package id="Nerdbank.GitVersioning" version="1.5.62" targetFramework="net40-client" developmentDependency="true" />
<package id="NuProj.Common" version="0.11.14-beta" targetFramework="net40-client" developmentDependency="true" />
<package id="StyleCop.Analyzers" version="1.0.0" targetFramework="net40-client" developmentDependency="true" />
</packages>
</packages>

Просмотреть файл

@ -0,0 +1,26 @@
// <copyright file="ExtensionsTests.cs" company="Microsoft Corporation">
// Copyright (C) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt in the project root for license information.
// </copyright>
namespace Microsoft.VisualStudio.Setup
{
using Xunit;
public class ExtensionsTests
{
[Theory]
[InlineData(null, null)]
[InlineData("", "")]
[InlineData("a", "A")]
[InlineData("A", "A")]
[InlineData("ab", "Ab")]
[InlineData("Ab", "Ab")]
[InlineData("AB", "AB")]
public void ToPascalCase(string value, string expected)
{
var actual = value.ToPascalCase();
Assert.Equal(expected, actual);
}
}
}

Просмотреть файл

@ -14,6 +14,15 @@ namespace Microsoft.VisualStudio.Setup
public class InstanceTests
{
private readonly Mock<ISetupInstance2> instance;
private readonly Mock<ISetupPropertyStore> store;
public InstanceTests()
{
instance = new Mock<ISetupInstance2>();
store = instance.As<ISetupPropertyStore>();
}
[Fact]
public void New_Instance_Null_Throws()
{
@ -23,7 +32,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_Missing_InstanceId_Throws()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Throws(new COMException("Not found", NativeMethods.E_NOTFOUND));
var ex = Assert.Throws<COMException>(() => new Instance(instance.Object));
@ -33,7 +41,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_Missing_InstallationName()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
instance.Setup(x => x.GetInstallationName()).Throws(new COMException("Not found", NativeMethods.E_NOTFOUND));
@ -44,7 +51,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_Null_InstallationVersion()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
instance.Setup(x => x.GetInstallationVersion()).Returns<string>(null);
@ -55,7 +61,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_Invalid_InstallationVersion()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
instance.Setup(x => x.GetInstallationVersion()).Returns("invalid");
@ -66,7 +71,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_InstallationVersion()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
instance.Setup(x => x.GetInstallationVersion()).Returns("1.2.3.4");
@ -77,7 +81,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_Product_Null()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
var sut = new Instance(instance.Object);
@ -89,7 +92,6 @@ namespace Microsoft.VisualStudio.Setup
{
var product = Mock.Of<ISetupPackageReference>(x => x.GetId() == "product");
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
instance.Setup(x => x.GetProduct()).Returns(product);
@ -101,7 +103,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_Packages_Null()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
var sut = new Instance(instance.Object);
@ -111,7 +112,6 @@ namespace Microsoft.VisualStudio.Setup
[Fact]
public void New_Packages_Empty()
{
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
instance.Setup(x => x.GetPackages()).Returns(Enumerable.Empty<ISetupPackageReference>().ToArray());
@ -128,7 +128,6 @@ namespace Microsoft.VisualStudio.Setup
Mock.Of<ISetupPackageReference>(x => x.GetId() == "b"),
};
var instance = new Mock<ISetupInstance2>();
instance.Setup(x => x.GetInstanceId()).Returns("test");
instance.Setup(x => x.GetPackages()).Returns(references);
@ -138,5 +137,20 @@ namespace Microsoft.VisualStudio.Setup
x => Assert.Equal("a", x.Id),
x => Assert.Equal("b", x.Id));
}
[Fact]
public void New_Copies_AdditionalProperties()
{
instance.Setup(x => x.GetInstanceId()).Returns("test");
store.Setup(x => x.GetNames()).Returns(new[] { "a", "b" });
store.Setup(x => x.GetValue("a")).Returns(1);
store.Setup(x => x.GetValue("b")).Returns(2);
var sut = new Instance(instance.Object);
Assert.Equal(1, sut.AdditionalProperties["A"]);
Assert.Equal(1, sut.AdditionalProperties["a"]);
Assert.Equal(2, sut.AdditionalProperties["B"]);
Assert.Equal(2, sut.AdditionalProperties["b"]);
}
}
}

Просмотреть файл

@ -46,7 +46,7 @@
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Setup.Configuration.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Interop.1.3.269-rc\lib\net35\Microsoft.VisualStudio.Setup.Configuration.Interop.dll</HintPath>
<HintPath>..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Interop.1.4.174-rc\lib\net35\Microsoft.VisualStudio.Setup.Configuration.Interop.dll</HintPath>
<EmbedInteropTypes>False</EmbedInteropTypes>
</Reference>
<Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
@ -78,6 +78,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ExtensionsTests.cs" />
<Compile Include="InstanceTests.cs" />
<Compile Include="PackageReferenceTests.cs" />
<Compile Include="PowerShell\ExtensionsTests.cs" />
@ -91,7 +92,9 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json">
@ -115,4 +118,4 @@
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props'))" />
</Target>
<Import Project="..\..\packages\Nerdbank.GitVersioning.1.5.62\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\Nerdbank.GitVersioning.targets" Condition="Exists('..\..\packages\Nerdbank.GitVersioning.1.5.62\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\Nerdbank.GitVersioning.targets')" />
</Project>
</Project>

Просмотреть файл

@ -2,7 +2,7 @@
<packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net45" />
<package id="Microsoft.PowerShell.3.ReferenceAssemblies" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Interop" version="1.3.269-rc" targetFramework="net45" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Interop" version="1.4.174-rc" targetFramework="net45" />
<package id="Moq" version="4.5.30" targetFramework="net45" />
<package id="Nerdbank.GitVersioning" version="1.5.62" targetFramework="net40-client" developmentDependency="true" requireReinstallation="true" />
<package id="StyleCop.Analyzers" version="1.0.0" targetFramework="net40-client" developmentDependency="true" />

Просмотреть файл

@ -4,7 +4,7 @@
# Require .NET Framework
FROM microsoft/windowsservercore
ENV API_VERSION="1.3.269-rc"
ENV API_VERSION="1.4.174-rc"
# Download and register current query APIs
SHELL ["powershell.exe", "-ExecutionPolicy", "Bypass", "-Command"]
@ -20,10 +20,10 @@ RUN $ErrorActionPreference = 'Stop' ; \
Install-PackageProvider -Name nuget -MinimumVersion 2.8.5.201 -Force ; \
Install-Module -Name Pester -Scope CurrentUser -SkipPublisherCheck -Force
# Copy test instance data and set up directories
ADD ["Instances/", "C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances/"]
# Set up test directories and instance data
RUN $ErrorActionPreference = 'Stop' ; \
New-Item -Path C:\VS\Community, C:\VS\Enterprise, C:\VS\Professional, C:\BuildTools -Type Directory | Out-Null
ADD ["Instances/", "C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances/"]
# Copy tests
ADD ["Tests", "C:/Tests"]

Просмотреть файл

@ -1,4 +1,5 @@
{
"channelId": "VisualStudio.15.Release/public.d15rel/15.0.26116.0",
"installationName": "VisualStudio/public.d15rel/15.0.26116.0",
"installationVersion": "15.0.26116.0",
"installationPath": "C:\\VS\\Community",
@ -34,19 +35,19 @@
],
"packages": [
{
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"version": "15.0.26116.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"version": "15.0.26116.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Workload.CoreEditor",
"version": "15.0.26116.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.CoreEditor",
"version": "15.0.26116.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Branding.Community",
"version": "15.0.26116.0",
"type": "Vsix"
"id": "Microsoft.VisualStudio.Branding.Community",
"version": "15.0.26116.0",
"type": "Vsix"
},
{
"id": "Microsoft.VisualStudio.Product.Community",

Просмотреть файл

@ -1,4 +1,5 @@
{
"channelId": "VisualStudio.15.Release/public.d15rel/15.0.26117.0",
"installationName": "VisualStudio/public.d15rel/15.0.26117.0",
"installationVersion": "15.0.26117.0",
"installationPath": "C:\\VS\\Enterprise",
@ -34,41 +35,29 @@
],
"packages": [
{
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"version": "15.0.26117.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"version": "15.0.26117.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Workload.NativeDesktop",
"version": "15.0.26117.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.NativeDesktop",
"version": "15.0.26117.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Workload.CoreEditor",
"version": "15.0.26117.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.CoreEditor",
"version": "15.0.26117.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Branding.Enterprise",
"version": "15.0.26117.0",
"type": "Vsix"
"id": "Microsoft.VisualStudio.Branding.Enterprise",
"version": "15.0.26117.0",
"type": "Vsix"
},
{
"id": "Microsoft.VisualStudio.Product.Enterprise",
"version": "15.0.26117.0",
"type": "Product"
}
],
"errors": {
"errorLogFilePath": "C:\\TEMP\\dd_setup_201601180315_errors.log",
"failedPackages": [
{
"id": "Microsoft.VisualStudio.Workload.Office",
"version": "15.0.26009.0",
"type": "Workload",
"logFilePath": "C:\\TEMP\\dd_setup_201601180315_003_Microsoft.VisualStudio.Workload.Office_errors.log",
"description": "Failed to install Microsoft.VisualStudio.Workload.Office"
}
]
}
]
}

Просмотреть файл

@ -1,4 +1,5 @@
{
"channelId": "VisualStudio.15.Release/public.d15rel/15.0.26117.0",
"installationName": "VisualStudio/public.d15rel/15.0.26117.0",
"installationVersion": "15.0.26117.0",
"installationPath": "C:\\VS\\Professional",
@ -34,19 +35,19 @@
],
"packages": [
{
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"version": "15.0.26117.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"version": "15.0.26117.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Workload.CoreEditor",
"version": "15.0.26117.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.CoreEditor",
"version": "15.0.26117.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Branding.Professional",
"version": "15.0.26117.0",
"type": "Vsix"
"id": "Microsoft.VisualStudio.Branding.Professional",
"version": "15.0.26117.0",
"type": "Vsix"
},
{
"id": "Microsoft.VisualStudio.Product.Professional",

Просмотреть файл

@ -1,4 +1,5 @@
{
"channelId": "VisualStudio.15.Release/public.d15rel/15.0.26117.0",
"installationName": "VisualStudio/public.d15rel/15.0.26117.0",
"installationVersion": "15.0.26117.0",
"installationPath": "C:\\BuildTools",
@ -31,9 +32,9 @@
],
"packages": [
{
"id": "Microsoft.VisualStudio.Workload.MSBuildTools",
"version": "15.0.26117.0",
"type": "Workload"
"id": "Microsoft.VisualStudio.Workload.MSBuildTools",
"version": "15.0.26117.0",
"type": "Workload"
},
{
"id": "Microsoft.VisualStudio.Product.BuildTools",

Просмотреть файл

@ -54,4 +54,17 @@ Describe 'Get-VSSetupInstance' {
$instance.Description | Should Match '^Kostenlose'
}
}
Context 'Contains additional properties' {
[System.Globalization.CultureInfo]::CurrentUICulture = $en
$instance = Get-VSSetupInstance C:\VS\Community
It 'Contains "ChannelId"' {
$instance.ChannelId | Should Be 'VisualStudio.15.Release/public.d15rel/15.0.26116.0'
}
It 'Contains "EnginePath"' {
$instance.EnginePath | Should Be 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service'
}
}
}

Просмотреть файл

@ -52,7 +52,7 @@ Describe 'Select-VSSetupInstance' {
Context 'Queries specified workloads' {
$instances = Get-VSSetupInstance | Select-VSSetupInstance -Require 'Microsoft.VisualStudio.Workload.ManagedDesktop'
It 'Returns 2 insances' {
It 'Returns 2 instances' {
$instances.Count | Should Be 2
}
}