Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,30 @@ public override void WriteWarningLine(string message)

internal class CommandLineParameterParser
{
internal static string[] validParameters = {
"psconsoleFile",
"version",
"nologo",
"noexit",
#if !CORECLR
"sta",
"mta",
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#if !CORECLR is no longer relevant. Should we remove the parameters at all?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fixing that as part of enabling ApartmentState PR and not part of this PR

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closed.

"noprofile",
"noninteractive",
"inputformat",
"outputformat",
#if !UNIX
"windowstyle",
#endif
"encodedcommand",
"configurationname",
"file",
"executionpolicy",
"command",
"help"
};

internal CommandLineParameterParser(PSHostUserInterface hostUI, string bannerText, string helpText)
{
if (hostUI == null) { throw new PSArgumentNullException("hostUI"); }
Expand Down Expand Up @@ -593,7 +617,7 @@ private void ParseHelper(string[] args)
break;
}
}
#if !CORECLR // windowstyle parameter not supported on NanoServer because ProcessWindowStyle does Not exist on CoreCLR
#if !UNIX
else if (MatchSwitch(switchKey, "windowstyle", "w"))
{
++i;
Expand Down Expand Up @@ -657,7 +681,7 @@ private void ParseHelper(string[] args)
WriteCommandLineError(
"The -module option can only be specified with the -iss option.",
showHelp: true,
showBanner: true);
showBanner: false);
break;
}

Expand Down Expand Up @@ -880,7 +904,7 @@ bool TryGetBoolValue(string arg, out bool boolValue)
WriteCommandLineError(
CommandLineParameterParserStrings.MissingFileArgument,
showHelp: true,
showBanner: true);
showBanner: false);
return false;
}

Expand Down Expand Up @@ -924,15 +948,36 @@ bool TryGetBoolValue(string arg, out bool boolValue)
{
WriteCommandLineError(
string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgument, args[i], exceptionMessage),
showBanner: true);
showBanner: false);
return false;
}

if (!System.IO.File.Exists(_file))
{
if (args[i].StartsWith("-") && args[i].Length > 1)
{
string param = args[i].Substring(1, args[i].Length - 1).ToLower();
StringBuilder possibleParameters = new StringBuilder();
foreach (string validParameter in validParameters)
{
if (validParameter.Contains(param))
{
possibleParameters.Append("\n -");
possibleParameters.Append(validParameter);
}
}
if (possibleParameters.Length > 0)
{
WriteCommandLineError(
string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidArgument, args[i]),
showBanner: false);
WriteCommandLineError(possibleParameters.ToString(), showBanner: false);
return false;
}
}
WriteCommandLineError(
string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.ArgumentFileDoesNotExist, args[i]),
showBanner: true);
showBanner: false);
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,7 @@ internal enum KeyboardFlag : uint
internal const int SW_FORCEMINIMIZE = 11;
internal const int SW_MAX = 11;


#if !CORECLR // ProcessWindowStyle does Not exist on CoreCLR
#if !UNIX
/// <summary>
/// Code to control the display properties of the a window...
/// </summary>
Expand Down
13 changes: 5 additions & 8 deletions src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ internal sealed partial class ConsoleHost
{
#region static methods

internal const uint ExitCodeSuccess = 0x00000000;
internal const uint ExitCodeCtrlBreak = 0xFFFE0000;
internal const uint ExitCodeInitFailure = 0xFFFF0000;
internal const uint ExitCodeBadCommandLineParameter = 0xFFFD0000;
internal const int ExitCodeSuccess = 0;
internal const int ExitCodeCtrlBreak = 128+21; // SIGBREAK
internal const int ExitCodeInitFailure = 70; // Internal Software Error
internal const int ExitCodeBadCommandLineParameter = 64; // Command Line Usage Error

// NTRAID#Windows Out Of Band Releases-915506-2005/09/09
// Removed HandleUnexpectedExceptions infrastructure
Expand Down Expand Up @@ -212,10 +212,7 @@ internal static int Start(
{
s_theConsoleHost.ui.WriteErrorLine(ConsoleHostStrings.ConflictingServerModeParameters);
}
unchecked
{
return (int)ExitCodeBadCommandLineParameter;
}
return ExitCodeBadCommandLineParameter;
}

// First check for and handle PowerShell running in a server mode.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ EXAMPLES
<value>Processing -File '{0}' failed because the file does not have a '.ps1' extension. Specify a valid Windows PowerShell script file name, and then try again.</value>
</data>
<data name="ArgumentFileDoesNotExist" xml:space="preserve">
<value>The argument '{0}' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.</value>
<value>The argument '{0}' is not recognized as the name of a script file. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.</value>
</data>
<data name="BadArgsValue" xml:space="preserve">
<value>Cannot process the command because the value specified with -EncodedArguments is not properly encoded. The value must be Base64 encoded.</value>
Expand All @@ -269,4 +269,7 @@ EXAMPLES
<data name="MissingConfigurationNameArgument" xml:space="preserve">
<value>Cannot process the command because -Configuration requires an argument that is a remote endpoint configuration name. Specify this argument and try again.</value>
</data>
<data name="InvalidArgument" xml:space="preserve">
<value>Invalid argument '{0}', did you mean:</value>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"did you mean:" - Do you want add something else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The possible matches show up after this. See example above in the PR description.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closed.

</data>
</root>
90 changes: 90 additions & 0 deletions test/powershell/Host/ConsoleHost.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Describe "ConsoleHost unit tests" -tags "Feature" {

BeforeAll {
$powershell = Join-Path -Path $PsHome -ChildPath "powershell"
$ExitCodeBadCommandLineParameter = 64

function NewProcessStartInfo([string]$CommandLine, [switch]$RedirectStdIn)
{
Expand Down Expand Up @@ -492,6 +493,95 @@ foo
powershell -v | Should Match $psversiontable.GitCommitId
}
}

Context "Ambiguous arguments" {
It "Ambiguous argument '<testArg>' should return possible matches" -TestCases @(
@{testArg="-no";expectedMatches=@("-nologo","-noexit","-noprofile","-noninteractive")},
@{testArg="-format";expectedMatches=@("-inputformat","-outputformat")}
) {
param($testArg, $expectedMatches)
$output = & $powershell $testArg -File foo 2>&1
$LASTEXITCODE | Should Be $ExitCodeBadCommandLineParameter
$outString = [String]::Join(",", $output)
foreach ($expectedMatch in $expectedMatches)
{
$outString | Should Match $expectedMatch
}
}
}
}

Describe "WindowStyle argument" -Tag Feature {
BeforeAll {
$defaultParamValues = $PSDefaultParameterValues.Clone()
$PSDefaultParameterValues["it:skip"] = !$IsWindows

if ($IsWindows)
{
$ExitCodeBadCommandLineParameter = 64
Add-Type -Name User32 -Namespace Test -MemberDefinition @"
public static WINDOWPLACEMENT GetPlacement(IntPtr hwnd)
{
WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
placement.length = Marshal.SizeOf(placement);
GetWindowPlacement(hwnd, ref placement);
return placement;
}

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowPlacement(
IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPLACEMENT
{
public int length;
public int flags;
public ShowWindowCommands showCmd;
public System.Drawing.Point ptMinPosition;
public System.Drawing.Point ptMaxPosition;
public System.Drawing.Rectangle rcNormalPosition;
}

public enum ShowWindowCommands : int
{
Hidden = 0,
Normal = 1,
Minimized = 2,
Maximized = 3,
}
"@
}
}

AfterAll {
$global:PSDefaultParameterValues = $defaultParamValues
}

It "-WindowStyle <WindowStyle> should work on Windows" -TestCases @(
@{WindowStyle="Normal"},
@{WindowStyle="Minimized"},
@{WindowStyle="Maximized"} # hidden doesn't work in CI/Server Core
) {
param ($WindowStyle)
$ps = Start-Process powershell -ArgumentList "-WindowStyle $WindowStyle -noexit -interactive" -PassThru
$startTime = Get-Date
$showCmd = "Unknown"
while (((Get-Date) - $startTime).TotalSeconds -lt 10 -and $showCmd -ne $WindowStyle)
{
Start-Sleep -Milliseconds 100
$showCmd = ([Test.User32]::GetPlacement($ps.MainWindowHandle)).showCmd
}
$showCmd | Should BeExactly $WindowStyle
$ps | Stop-Process -Force
}

It "Invalid -WindowStyle returns error" {
powershell -WindowStyle invalid
$LASTEXITCODE | Should Be $ExitCodeBadCommandLineParameter
}
}

Describe "Console host api tests" -Tag CI {
Expand Down