mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
This commit is contained in:
+1
-1
@@ -173,7 +173,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
ci.alignment = colHeader.alignment;
|
||||
if (colHeader.label != null)
|
||||
{
|
||||
ci.HeaderMatchesProperty = so.Properties[colHeader.label.text] is not null || !ExperimentalFeature.IsEnabled(ExperimentalFeature.PSCustomTableHeaderLabelDecoration);
|
||||
ci.HeaderMatchesProperty = so.Properties[colHeader.label.text] is not null;
|
||||
|
||||
ci.label = this.dataBaseInfo.db.displayResourceManagerCache.GetTextTokenString(colHeader.label);
|
||||
}
|
||||
|
||||
@@ -104,9 +104,7 @@ internal sealed class FileBytePipe : BytePipe
|
||||
throw new RuntimeException(null, e, errorRecord);
|
||||
}
|
||||
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData(
|
||||
ExperimentalFeature.PSNativeCommandPreserveBytePipe,
|
||||
"f");
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData("PSNativeCommandPreserveBytePipe", "f");
|
||||
|
||||
return new FileBytePipe(fileStream);
|
||||
}
|
||||
|
||||
@@ -21,14 +21,9 @@ namespace System.Management.Automation
|
||||
#region Const Members
|
||||
|
||||
internal const string EngineSource = "PSEngine";
|
||||
internal const string PSNativeCommandErrorActionPreferenceFeatureName = "PSNativeCommandErrorActionPreference";
|
||||
internal const string PSNativeCommandPreserveBytePipe = "PSNativeCommandPreserveBytePipe";
|
||||
internal const string PSModuleAutoLoadSkipOfflineFilesFeatureName = "PSModuleAutoLoadSkipOfflineFiles";
|
||||
internal const string PSCustomTableHeaderLabelDecoration = "PSCustomTableHeaderLabelDecoration";
|
||||
internal const string PSFeedbackProvider = "PSFeedbackProvider";
|
||||
internal const string PSCommandWithArgs = "PSCommandWithArgs";
|
||||
internal const string PSConstrainedAuditLogging = "PSConstrainedAuditLogging";
|
||||
internal const string PSWindowsNativeCommandArgPassing = "PSWindowsNativeCommandArgPassing";
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -120,30 +115,15 @@ namespace System.Management.Automation
|
||||
new ExperimentalFeature(
|
||||
name: "PSLoadAssemblyFromNativeCode",
|
||||
description: "Expose an API to allow assembly loading from native code"),
|
||||
new ExperimentalFeature(
|
||||
name: PSNativeCommandErrorActionPreferenceFeatureName,
|
||||
description: "Native commands with non-zero exit codes issue errors according to $ErrorActionPreference when $PSNativeCommandUseErrorActionPreference is $true"),
|
||||
new ExperimentalFeature(
|
||||
name: PSModuleAutoLoadSkipOfflineFilesFeatureName,
|
||||
description: "Module discovery will skip over files that are marked by cloud providers as not fully on disk."),
|
||||
new ExperimentalFeature(
|
||||
name: PSCustomTableHeaderLabelDecoration,
|
||||
description: "Formatting differentiation for table header labels that aren't property members"),
|
||||
new ExperimentalFeature(
|
||||
name: PSNativeCommandPreserveBytePipe,
|
||||
description: "Byte output is retained when piping between two or more native commands"),
|
||||
new ExperimentalFeature(
|
||||
name: PSFeedbackProvider,
|
||||
description: "Replace the hard-coded suggestion framework with the extensible feedback provider"),
|
||||
new ExperimentalFeature(
|
||||
name: PSCommandWithArgs,
|
||||
description: "Enable `-CommandWithArgs` parameter for pwsh"),
|
||||
new ExperimentalFeature(
|
||||
name: PSConstrainedAuditLogging,
|
||||
description: "PowerShell restriction logging when WDAC (Windows Defender Application Control) Code Integrity policy is set to Audit mode."),
|
||||
new ExperimentalFeature(
|
||||
name: "PSWindowsNativeCommandArgPassing",
|
||||
description: "Enable 'Windows' as the native command argument passing mode"),
|
||||
};
|
||||
|
||||
EngineExperimentalFeatures = new ReadOnlyCollection<ExperimentalFeature>(engineFeatures);
|
||||
|
||||
@@ -4652,16 +4652,13 @@ end {
|
||||
#endregion
|
||||
};
|
||||
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandErrorActionPreferenceFeatureName))
|
||||
{
|
||||
builtinVariables.Add(
|
||||
new SessionStateVariableEntry(
|
||||
SpecialVariables.PSNativeCommandUseErrorActionPreference,
|
||||
value: true, // when this feature is changed to stable, this should default to `false`
|
||||
RunspaceInit.PSNativeCommandUseErrorActionPreferenceDescription,
|
||||
ScopedItemOptions.None,
|
||||
new ArgumentTypeConverterAttribute(typeof(bool))));
|
||||
}
|
||||
builtinVariables.Add(
|
||||
new SessionStateVariableEntry(
|
||||
SpecialVariables.PSNativeCommandUseErrorActionPreference,
|
||||
value: false,
|
||||
RunspaceInit.PSNativeCommandUseErrorActionPreferenceDescription,
|
||||
ScopedItemOptions.None,
|
||||
new ArgumentTypeConverterAttribute(typeof(bool))));
|
||||
|
||||
builtinVariables.Add(
|
||||
new SessionStateVariableEntry(
|
||||
@@ -4677,20 +4674,14 @@ end {
|
||||
/// <summary>
|
||||
/// Assigns the default behavior for native argument passing.
|
||||
/// If the system is non-Windows, we will return Standard.
|
||||
/// If the experimental feature is enabled, we will return Windows.
|
||||
/// Otherwise, we will return Legacy.
|
||||
/// Otherwise, we will return Windows.
|
||||
/// </summary>
|
||||
private static NativeArgumentPassingStyle GetPassingStyle()
|
||||
{
|
||||
#if UNIX
|
||||
return NativeArgumentPassingStyle.Standard;
|
||||
#else
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSWindowsNativeCommandArgPassing))
|
||||
{
|
||||
return NativeArgumentPassingStyle.Windows;
|
||||
}
|
||||
|
||||
return NativeArgumentPassingStyle.Legacy;
|
||||
return NativeArgumentPassingStyle.Windows;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -397,8 +397,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
// If upstream is a native command it'll be writing directly to our stdin stream
|
||||
// so we can skip reading here.
|
||||
if (!ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
|| !UpstreamIsNativeCommand)
|
||||
if (!UpstreamIsNativeCommand)
|
||||
{
|
||||
while (Read())
|
||||
{
|
||||
@@ -547,7 +546,7 @@ namespace System.Management.Automation
|
||||
|
||||
// Send Telemetry indicating what argument passing mode we are in.
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData(
|
||||
ExperimentalFeature.PSWindowsNativeCommandArgPassing,
|
||||
"PSWindowsNativeCommandArgPassing",
|
||||
NativeParameterBinderController.ArgumentPassingStyle.ToString());
|
||||
|
||||
#if !UNIX
|
||||
@@ -720,9 +719,7 @@ namespace System.Management.Automation
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
if (!_stopped
|
||||
&& (!ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
|| !UpstreamIsNativeCommand))
|
||||
if (!_stopped && !UpstreamIsNativeCommand)
|
||||
{
|
||||
_inputWriter.Start(_nativeProcess, inputFormat);
|
||||
}
|
||||
@@ -785,21 +782,16 @@ namespace System.Management.Automation
|
||||
if (CommandRuntime.ErrorMergeTo is MshCommandRuntime.MergeDataStream.Output)
|
||||
{
|
||||
StdOutDestination = null;
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe))
|
||||
if (DownStreamNativeCommand is not null)
|
||||
{
|
||||
if (DownStreamNativeCommand is not null)
|
||||
{
|
||||
DownStreamNativeCommand.UpstreamIsNativeCommand = false;
|
||||
DownStreamNativeCommand = null;
|
||||
}
|
||||
DownStreamNativeCommand.UpstreamIsNativeCommand = false;
|
||||
DownStreamNativeCommand = null;
|
||||
}
|
||||
}
|
||||
|
||||
_nativeProcessOutputQueue = new BlockingCollection<ProcessOutputObject>();
|
||||
// we don't assign the handler to anything, because it's used only for objects marshaling
|
||||
BytePipe stdOutDestination = ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
? StdOutDestination ?? DownStreamNativeCommand?.CreateBytePipe(stdout: false)
|
||||
: null;
|
||||
BytePipe stdOutDestination = StdOutDestination ?? DownStreamNativeCommand?.CreateBytePipe(stdout: false);
|
||||
|
||||
BytePipe stdOutSource = null;
|
||||
if (stdOutDestination is not null)
|
||||
@@ -823,8 +815,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (blocking)
|
||||
{
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
&& _stdOutByteTransfer is not null)
|
||||
if (_stdOutByteTransfer is not null)
|
||||
{
|
||||
_stdOutByteTransfer.EOF.GetAwaiter().GetResult();
|
||||
return null;
|
||||
@@ -853,8 +844,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
&& _stdOutByteTransfer is not null)
|
||||
if (_stdOutByteTransfer is not null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -897,8 +887,7 @@ namespace System.Management.Automation
|
||||
if (!_isRunningInBackground)
|
||||
{
|
||||
// Wait for input writer to finish.
|
||||
if (!ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
|| !UpstreamIsNativeCommand)
|
||||
if (!UpstreamIsNativeCommand)
|
||||
{
|
||||
_inputWriter.Done();
|
||||
}
|
||||
@@ -952,12 +941,6 @@ namespace System.Management.Automation
|
||||
|
||||
this.commandRuntime.PipelineProcessor.ExecutionFailed = true;
|
||||
|
||||
// Feature is not enabled, so return
|
||||
if (!ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandErrorActionPreferenceFeatureName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We send telemetry information only if the feature is enabled.
|
||||
// This shouldn't be done once, because it's a run-time check we should send telemetry every time.
|
||||
// Report on the following conditions:
|
||||
@@ -973,12 +956,12 @@ namespace System.Management.Automation
|
||||
// The variable is unset
|
||||
if (useDefaultSetting)
|
||||
{
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData(ExperimentalFeature.PSNativeCommandErrorActionPreferenceFeatureName, "unset");
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData("PSNativeCommandErrorActionPreference", "unset");
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the value that was set.
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData(ExperimentalFeature.PSNativeCommandErrorActionPreferenceFeatureName, nativeErrorActionPreferenceSetting.ToString());
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData("PSNativeCommandErrorActionPreference", nativeErrorActionPreferenceSetting.ToString());
|
||||
|
||||
// if it was explicitly set to false, return
|
||||
if (!nativeErrorActionPreferenceSetting)
|
||||
@@ -1267,8 +1250,7 @@ namespace System.Management.Automation
|
||||
if (!_runStandAlone)
|
||||
{
|
||||
// Stop input writer
|
||||
if (!ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
|| !UpstreamIsNativeCommand)
|
||||
if (!UpstreamIsNativeCommand)
|
||||
{
|
||||
_inputWriter.Stop();
|
||||
}
|
||||
@@ -1816,8 +1798,7 @@ namespace System.Management.Automation
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
|| stdOutDestination is null)
|
||||
if (stdOutDestination is null)
|
||||
{
|
||||
_isFirstOutput = true;
|
||||
_isXmlCliOutput = false;
|
||||
@@ -2074,19 +2055,16 @@ namespace System.Management.Automation
|
||||
|
||||
object baseObjInput = PSObject.Base(input);
|
||||
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe))
|
||||
if (baseObjInput is byte[] bytes)
|
||||
{
|
||||
if (baseObjInput is byte[] bytes)
|
||||
{
|
||||
_streamWriter.BaseStream.Write(bytes, 0, bytes.Length);
|
||||
return;
|
||||
}
|
||||
_streamWriter.BaseStream.Write(bytes, 0, bytes.Length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (baseObjInput is byte b)
|
||||
{
|
||||
_streamWriter.BaseStream.WriteByte(b);
|
||||
return;
|
||||
}
|
||||
if (baseObjInput is byte b)
|
||||
{
|
||||
_streamWriter.BaseStream.WriteByte(b);
|
||||
return;
|
||||
}
|
||||
|
||||
AddTextInput(input);
|
||||
|
||||
@@ -261,31 +261,26 @@ namespace System.Management.Automation.Internal
|
||||
/// <exception cref="ObjectDisposedException"></exception>
|
||||
internal int Add(CommandProcessorBase commandProcessor)
|
||||
{
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe))
|
||||
if (commandProcessor is NativeCommandProcessor nativeCommand)
|
||||
{
|
||||
if (commandProcessor is NativeCommandProcessor nativeCommand)
|
||||
if (_lastNativeCommand is not null)
|
||||
{
|
||||
if (_lastNativeCommand is not null)
|
||||
// Only report experimental feature usage once per pipeline.
|
||||
if (!_haveReportedNativePipeUsage)
|
||||
{
|
||||
// Only report experimental feature usage once per pipeline.
|
||||
if (!_haveReportedNativePipeUsage)
|
||||
{
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData(
|
||||
ExperimentalFeature.PSNativeCommandPreserveBytePipe,
|
||||
"p");
|
||||
_haveReportedNativePipeUsage = true;
|
||||
}
|
||||
|
||||
_lastNativeCommand.DownStreamNativeCommand = nativeCommand;
|
||||
nativeCommand.UpstreamIsNativeCommand = true;
|
||||
ApplicationInsightsTelemetry.SendExperimentalUseData("PSNativeCommandPreserveBytePipe", "p");
|
||||
_haveReportedNativePipeUsage = true;
|
||||
}
|
||||
|
||||
_lastNativeCommand = nativeCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastNativeCommand = null;
|
||||
_lastNativeCommand.DownStreamNativeCommand = nativeCommand;
|
||||
nativeCommand.UpstreamIsNativeCommand = true;
|
||||
}
|
||||
|
||||
_lastNativeCommand = nativeCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastNativeCommand = null;
|
||||
}
|
||||
|
||||
commandProcessor.CommandRuntime.PipelineProcessor = this;
|
||||
|
||||
@@ -221,10 +221,7 @@ namespace System.Management.Automation
|
||||
bool redirectedInformation = false;
|
||||
if (redirections != null)
|
||||
{
|
||||
bool shouldProcessMergesFirst = ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe)
|
||||
&& isNativeCommand;
|
||||
|
||||
if (shouldProcessMergesFirst)
|
||||
if (isNativeCommand)
|
||||
{
|
||||
foreach (CommandRedirection redirection in redirections)
|
||||
{
|
||||
@@ -237,7 +234,7 @@ namespace System.Management.Automation
|
||||
|
||||
foreach (CommandRedirection redirection in redirections)
|
||||
{
|
||||
if (!shouldProcessMergesFirst || redirection is not MergingRedirection)
|
||||
if (!isNativeCommand || redirection is not MergingRedirection)
|
||||
{
|
||||
redirection.Bind(pipe, commandProcessor, context);
|
||||
}
|
||||
@@ -1081,16 +1078,13 @@ namespace System.Management.Automation
|
||||
// dir > out
|
||||
internal override void Bind(PipelineProcessor pipelineProcessor, CommandProcessorBase commandProcessor, ExecutionContext context)
|
||||
{
|
||||
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeCommandPreserveBytePipe))
|
||||
if (commandProcessor is NativeCommandProcessor nativeCommand
|
||||
&& nativeCommand.CommandRuntime.ErrorMergeTo is not MshCommandRuntime.MergeDataStream.Output
|
||||
&& FromStream is RedirectionStream.Output
|
||||
&& !string.IsNullOrWhiteSpace(File))
|
||||
{
|
||||
if (commandProcessor is NativeCommandProcessor nativeCommand
|
||||
&& nativeCommand.CommandRuntime.ErrorMergeTo is not MshCommandRuntime.MergeDataStream.Output
|
||||
&& FromStream is RedirectionStream.Output
|
||||
&& !string.IsNullOrWhiteSpace(File))
|
||||
{
|
||||
nativeCommand.StdOutDestination = FileBytePipe.Create(File, Appending);
|
||||
return;
|
||||
}
|
||||
nativeCommand.StdOutDestination = FileBytePipe.Create(File, Appending);
|
||||
return;
|
||||
}
|
||||
|
||||
Pipe pipe = GetRedirectionPipe(context, pipelineProcessor);
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
Describe 'Native command byte piping tests' -Tags 'CI' {
|
||||
BeforeAll {
|
||||
$originalDefaultParameterValues = $PSDefaultParameterValues.Clone()
|
||||
if (-not [ExperimentalFeature]::IsEnabled('PSNativeCommandPreserveBytePipe'))
|
||||
{
|
||||
$PSDefaultParameterValues['It:Skip'] = $true
|
||||
return
|
||||
}
|
||||
|
||||
# Without this the test would otherwise be hard coded to a specific set
|
||||
# of [Console]::OutputEncoding/$OutputEncoding settings.
|
||||
|
||||
@@ -7,12 +7,6 @@
|
||||
Describe 'Native command error handling tests' -Tags 'CI' {
|
||||
BeforeAll {
|
||||
$originalDefaultParameterValues = $PSDefaultParameterValues.Clone()
|
||||
if (-not [ExperimentalFeature]::IsEnabled('PSNativeCommandErrorActionPreference'))
|
||||
{
|
||||
$PSDefaultParameterValues['It:Skip'] = $true
|
||||
return
|
||||
}
|
||||
|
||||
$exeName = $IsWindows ? 'testexe.exe' : 'testexe'
|
||||
$exePath = @(Get-Command $exeName -Type Application)[0].Path
|
||||
|
||||
|
||||
Reference in New Issue
Block a user