Make Start-Job throw terminating exception when -RunAs32 is specified in 64-bit pwsh (#9143)

This commit is contained in:
Dongbo Wang
2019-03-18 10:23:29 -07:00
committed by Aditya Patwardhan
parent 66ab6e7e74
commit 24d3152f00
5 changed files with 29 additions and 42 deletions
@@ -48,28 +48,6 @@ namespace System.Management.Automation.Runspaces
/// <param name="useWow64"></param>
public PowerShellProcessInstance(Version powerShellVersion, PSCredential credential, ScriptBlock initializationScript, bool useWow64)
{
string psWow64Path = PwshExePath;
if (useWow64)
{
string procArch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
if (!string.IsNullOrEmpty(procArch) && (procArch.Equals("amd64", StringComparison.OrdinalIgnoreCase) ||
procArch.Equals("ia64", StringComparison.OrdinalIgnoreCase)))
{
psWow64Path = PwshExePath.ToLowerInvariant().Replace("\\system32\\", "\\syswow64\\");
if (!File.Exists(psWow64Path))
{
string message =
PSRemotingErrorInvariants.FormatResourceString(
RemotingErrorIdStrings.IPCWowComponentNotPresent,
psWow64Path);
throw new PSInvalidOperationException(message);
}
}
}
string processArguments = " -s -NoLogo -NoProfile";
if (initializationScript != null)
@@ -88,7 +66,7 @@ namespace System.Management.Automation.Runspaces
// to 'false' in our use, we can ignore the 'WindowStyle' setting in the initialization below.
_startInfo = new ProcessStartInfo
{
FileName = useWow64 ? psWow64Path : PwshExePath,
FileName = PwshExePath,
Arguments = processArguments,
UseShellExecute = false,
RedirectStandardInput = true,
@@ -481,20 +481,13 @@ namespace Microsoft.PowerShell.Commands
private ScriptBlock _initScript;
/// <summary>
/// Launces the background job as a 32-bit process. This can be used on
/// Launches the background job as a 32-bit process. This can be used on
/// 64-bit systems to launch a 32-bit wow process for the background job.
/// </summary>
[Parameter(ParameterSetName = StartJobCommand.FilePathComputerNameParameterSet)]
[Parameter(ParameterSetName = StartJobCommand.ComputerNameParameterSet)]
[Parameter(ParameterSetName = StartJobCommand.LiteralFilePathComputerNameParameterSet)]
public virtual SwitchParameter RunAs32
{
get { return _shouldRunAs32; }
set { _shouldRunAs32 = value; }
}
private bool _shouldRunAs32;
public virtual SwitchParameter RunAs32 { get; set; }
/// <summary>
/// Powershell Version to execute the background job.
@@ -574,12 +567,24 @@ namespace Microsoft.PowerShell.Commands
RemotingErrorIdStrings.IPCPwshExecutableNotFound,
PowerShellProcessInstance.PwshExePath);
var exception = new PSNotSupportedException(message);
var errorRecord = new ErrorRecord(
exception,
"IPCPwshExecutableNotFound",
ErrorCategory.NotInstalled,
PowerShellProcessInstance.PwshExePath);
new PSNotSupportedException(message),
"IPCPwshExecutableNotFound",
ErrorCategory.NotInstalled,
PowerShellProcessInstance.PwshExePath);
ThrowTerminatingError(errorRecord);
}
if (RunAs32.IsPresent && Environment.Is64BitProcess)
{
// We cannot start a 32-bit 'pwsh' process from a 64-bit 'pwsh' installation.
string message = RemotingErrorIdStrings.RunAs32NotSupported;
var errorRecord = new ErrorRecord(
new PSNotSupportedException(message),
"RunAs32NotSupported",
ErrorCategory.InvalidOperation,
targetObject: null);
ThrowTerminatingError(errorRecord);
}
@@ -620,7 +625,6 @@ namespace Microsoft.PowerShell.Commands
}
NewProcessConnectionInfo connectionInfo = new NewProcessConnectionInfo(this.Credential);
connectionInfo.RunAs32 = _shouldRunAs32;
connectionInfo.InitializationScript = _initScript;
connectionInfo.AuthenticationMechanism = this.Authentication;
connectionInfo.PSVersion = this.PSVersion;
@@ -791,8 +791,8 @@ Do you want to continue?</value>
<value>The pwsh executable cannot be found at "{0}".
Note that 'Start-Job' is not supported by design in scenarios where PowerShell is being hosted in other applications. Instead, usage of the 'ThreadJob' module is recommended in such scenarios.</value>
</data>
<data name="IPCWowComponentNotPresent" xml:space="preserve">
<value>The "{0}" executable file was not found. Verify that the WOW64 feature is installed.</value>
<data name="RunAs32NotSupported" xml:space="preserve">
<value>Cannot start a 32-bit 'pwsh' process from the 64-bit 'pwsh' installation. Install the 32-bit 'pwsh' if you need to run PowerShell in a 32-bit process.</value>
</data>
<data name="IPCServerProcessReportedError" xml:space="preserve">
<value>The background process reported an error with the following message: {0}.</value>
@@ -32,6 +32,13 @@ Describe "Job Cmdlet Tests" -Tag "CI" {
Wait-Job -Timeout 60 -id $j.id | Should -Not -BeNullOrEmpty
receive-job -id $j.id | Should -Be 2
}
It "-RunAs32 not supported from 64-bit pwsh" -Skip:(-not [System.Environment]::Is64BitProcess) {
{ Start-Job -ScriptBlock {} -RunAs32 } | Should -Throw -ErrorId "RunAs32NotSupported,Microsoft.PowerShell.Commands.StartJobCommand"
}
It "-RunAs32 supported in 32-bit pwsh" -Skip:([System.Environment]::Is64BitProcess) {
$job = Start-Job -ScriptBlock { 1+1 } -RunAs32
Receive-Job $job -Wait | Should -Be 2
}
}
Context "Jobs with arguments" {
It "Start-Job accepts arguments" {
-2
View File
@@ -7,10 +7,8 @@ using Xunit;
namespace PSTests.Sequential
{
// Not static because a test requires non-const variables
public static class PowerShellHostingScenario
{
// Test that it does not throw an exception
[Fact]
public static void TestStartJobThrowTerminatingException()
{