Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement WinGetUserSettings cmdlets #2776

Merged
merged 15 commits into from
Jan 6, 2023
4 changes: 4 additions & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,16 @@ ISQ
ISVs
itr
IWin
JArray
jdk
jfearn
JObject
jpalardy
JREs
jrsoftware
jsoncpp
JToken
JValue
KNOWNFOLDERID
ktf
ldcase
Expand Down Expand Up @@ -288,6 +291,7 @@ rosoft
rowids
RRF
rrr
runspace
runtimeclass
ryfu
rzkzqaqjwj
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Microsoft.Msix.Utils" Version="2.1.1" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
Expand Down
43 changes: 0 additions & 43 deletions src/AppInstallerCLIE2ETests/BaseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,48 +44,5 @@ public void ResetTestSource(bool useGroupPolicyForTestSource = false)
// to enable testing it by default. Until then, leaving this here...
TestCommon.SetupTestSource(useGroupPolicyForTestSource);
}

/// <summary>
/// Configure experimental features.
/// </summary>
/// <param name="featureName">Feature name.</param>
/// <param name="status">Status.</param>
public void ConfigureFeature(string featureName, bool status)
{
string localAppDataPath = Environment.GetEnvironmentVariable(Constants.LocalAppData);
JObject settingsJson = JObject.Parse(File.ReadAllText(Path.Combine(localAppDataPath, TestCommon.SettingsJsonFilePath)));
JObject experimentalFeatures = (JObject)settingsJson["experimentalFeatures"];
experimentalFeatures[featureName] = status;

File.WriteAllText(Path.Combine(localAppDataPath, TestCommon.SettingsJsonFilePath), settingsJson.ToString());
}

/// <summary>
/// Configure the install behavior.
/// </summary>
/// <param name="settingName">Setting name.</param>
/// <param name="value">Setting value.</param>
public void ConfigureInstallBehavior(string settingName, string value)
{
string localAppDataPath = Environment.GetEnvironmentVariable(Constants.LocalAppData);
JObject settingsJson = JObject.Parse(File.ReadAllText(Path.Combine(localAppDataPath, TestCommon.SettingsJsonFilePath)));
JObject installBehavior = (JObject)settingsJson["installBehavior"];
installBehavior[settingName] = value;

File.WriteAllText(Path.Combine(localAppDataPath, TestCommon.SettingsJsonFilePath), settingsJson.ToString());
}

/// <summary>
/// Initialize all features.
/// </summary>
/// <param name="status">Initialized feature value.</param>
public void InitializeAllFeatures(bool status)
{
this.ConfigureFeature("experimentalArg", status);
this.ConfigureFeature("experimentalCmd", status);
this.ConfigureFeature("dependencies", status);
this.ConfigureFeature("directMSI", status);
this.ConfigureFeature("openLogsArgument", status);
}
}
}
12 changes: 6 additions & 6 deletions src/AppInstallerCLIE2ETests/FeaturesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class FeaturesCommand : BaseCommand
[SetUp]
public void Setup()
{
this.InitializeAllFeatures(false);
WinGetSettingsHelper.InitializeAllFeatures(false);
}

/// <summary>
Expand All @@ -28,7 +28,7 @@ public void Setup()
[TearDown]
public void TearDown()
{
this.InitializeAllFeatures(false);
WinGetSettingsHelper.InitializeAllFeatures(false);
}

/// <summary>
Expand All @@ -49,10 +49,10 @@ public void DisplayFeatures()
[Test]
public void EnableExperimentalFeatures()
{
this.ConfigureFeature("experimentalArg", true);
this.ConfigureFeature("experimentalCmd", true);
this.ConfigureFeature("directMSI", true);
this.ConfigureFeature("openLogsArgument", true);
WinGetSettingsHelper.ConfigureFeature("experimentalArg", true);
WinGetSettingsHelper.ConfigureFeature("experimentalCmd", true);
WinGetSettingsHelper.ConfigureFeature("directMSI", true);
WinGetSettingsHelper.ConfigureFeature("openLogsArgument", true);
var result = TestCommon.RunAICLICommand("features", string.Empty);
Assert.True(result.StdOut.Contains("Enabled"));
}
Expand Down
6 changes: 3 additions & 3 deletions src/AppInstallerCLIE2ETests/GroupPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class GroupPolicy : BaseCommand
[SetUp]
public void Setup()
{
this.InitializeAllFeatures(false);
WinGetSettingsHelper.InitializeAllFeatures(false);
GroupPolicyHelper.DeleteExistingPolicies();
}

Expand All @@ -30,7 +30,7 @@ public void Setup()
[TearDown]
public void TearDown()
{
this.InitializeAllFeatures(false);
WinGetSettingsHelper.InitializeAllFeatures(false);
GroupPolicyHelper.DeleteExistingPolicies();
}

Expand Down Expand Up @@ -62,7 +62,7 @@ public void EnableSettings()
[Test]
public void EnableExperimentalFeatures()
{
this.ConfigureFeature("experimentalCmd", true);
WinGetSettingsHelper.ConfigureFeature("experimentalCmd", true);
var result = TestCommon.RunAICLICommand("experimental", string.Empty);
Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);

Expand Down
8 changes: 4 additions & 4 deletions src/AppInstallerCLIE2ETests/InstallCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -403,15 +403,15 @@ public void ReinstallPortable()
public void InstallPortable_UserScope()
{
string installDir = TestCommon.GetRandomTestDir();
this.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir);
WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir);

string packageId, commandAlias, fileName, packageDirName, productCode;
packageId = "AppInstallerTest.TestPortableExe";
packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier;
commandAlias = fileName = "AppInstallerTestExeInstaller.exe";

var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope user");
this.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty);
WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty);
Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);
Assert.True(result.StdOut.Contains("Successfully installed"));
TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);
Expand All @@ -424,15 +424,15 @@ public void InstallPortable_UserScope()
public void InstallPortable_MachineScope()
{
string installDir = TestCommon.GetRandomTestDir();
this.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir);
WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir);

string packageId, commandAlias, fileName, packageDirName, productCode;
packageId = "AppInstallerTest.TestPortableExe";
packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier;
commandAlias = fileName = "AppInstallerTestExeInstaller.exe";

var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope machine");
this.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty);
WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty);
Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);
Assert.True(result.StdOut.Contains("Successfully installed"));
TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine);
Expand Down
101 changes: 101 additions & 0 deletions src/AppInstallerCLIE2ETests/PowerShell/PowerShellHost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// -----------------------------------------------------------------------------
// <copyright file="PowerShellHost.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
// </copyright>
// -----------------------------------------------------------------------------

namespace AppInstallerCLIE2ETests.PowerShell
{
using System;
using System.Collections;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using Microsoft.PowerShell;
using NUnit.Framework;

/// <summary>
/// Helper class to run powershell commands.
/// </summary>
internal class PowerShellHost : IDisposable
{
private readonly Runspace runspace = null;

private bool disposed = false;

/// <summary>
/// Initializes a new instance of the <see cref="PowerShellHost"/> class.
/// </summary>
public PowerShellHost()
{
InitialSessionState initialSessionState = InitialSessionState.CreateDefault();
initialSessionState.ExecutionPolicy = ExecutionPolicy.Unrestricted;
initialSessionState.ImportPSModule(new string[]
{
TestCommon.PowerShellModulePath,
});

this.runspace = RunspaceFactory.CreateRunspace(initialSessionState);
this.runspace.Open();
this.VerifyErrorState();

this.PowerShell = PowerShell.Create(this.runspace);
}

/// <summary>
/// Finalizes an instance of the <see cref="PowerShellHost"/> class.
/// </summary>
~PowerShellHost() => this.Dispose(false);

/// <summary>
/// Gets PowerShell.
/// </summary>
public PowerShell PowerShell { get; private set; } = null;

/// <summary>
/// Dispose.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Protected implementation of dispose pattern.
/// </summary>
/// <param name="disposing">Dispose.</param>
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.PowerShell.Dispose();
this.runspace.Dispose();
}

this.disposed = true;
}
}

/// <summary>
/// The most common error is that the module was not found.
/// </summary>
private void VerifyErrorState()
{
var errors = (ArrayList)this.runspace.SessionStateProxy.PSVariable.GetValue("Error");

if (errors.Count > 0)
{
string errorMessage = "PSVariable Error:";
foreach (var error in errors)
{
errorMessage += Environment.NewLine + ((ErrorRecord)error).Exception.Message;
}

TestContext.Error.WriteLine(errorMessage);
throw new Exception(errorMessage);
}
}
}
}
Loading