diff --git a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs index f35e9998e..a43f5a7d3 100644 --- a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs +++ b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs @@ -302,16 +302,7 @@ protected async Task HandleLaunchRequest( string arguments = null; if ((launchParams.Args != null) && (launchParams.Args.Length > 0)) { - var sb = new StringBuilder(); - for (int i = 0; i < launchParams.Args.Length; i++) - { - sb.Append(PowerShellContext.QuoteEscapeString(launchParams.Args[i])); - if (i < launchParams.Args.Length - 1) - { - sb.Append(' '); - } - } - arguments = sb.ToString(); + arguments = string.Join(" ", launchParams.Args); Logger.Write(LogLevel.Verbose, "Script arguments are: " + arguments); } diff --git a/src/PowerShellEditorServices/Session/PowerShellContext.cs b/src/PowerShellEditorServices/Session/PowerShellContext.cs index 772892bb5..cf1206b0f 100644 --- a/src/PowerShellEditorServices/Session/PowerShellContext.cs +++ b/src/PowerShellEditorServices/Session/PowerShellContext.cs @@ -769,7 +769,6 @@ await this.ExecuteCommand( /// A Task that can be awaited for completion. public async Task ExecuteScriptWithArgs(string script, string arguments = null, bool writeInputToHost = false) { - var escapedScriptPath = new StringBuilder(PowerShellContext.WildcardEscapePath(script)); PSCommand command = new PSCommand(); if (arguments != null) @@ -791,24 +790,38 @@ public async Task ExecuteScriptWithArgs(string script, string arguments = null, "Could not determine current filesystem location:\r\n\r\n" + e.ToString()); } - // If we don't escape wildcard characters in a path to a script file, the script can - // fail to execute if say the script filename was foo][.ps1. + var strBld = new StringBuilder(); + + // The script parameter can refer to either a "script path" or a "command name". If it is a + // script path, we can determine that by seeing if the path exists. If so, we always single + // quote that path in case it includes special PowerShell characters like ', &, (, ), [, ] and + // . Any embedded single quotes are escaped. + // If the provided path is already quoted, then File.Exists will not find it. + // This keeps us from quoting an already quoted path. // Related to issue #123. if (File.Exists(script) || File.Exists(scriptAbsPath)) { - // Dot-source the launched script path - string escapedFilePath = escapedScriptPath.ToString(); - escapedScriptPath = new StringBuilder(". ").Append(QuoteEscapeString(escapedFilePath)); + // Dot-source the launched script path and single quote the path in case it includes + strBld.Append(". ").Append(QuoteEscapeString(script)); + } + else + { + strBld.Append(script); } // Add arguments - escapedScriptPath.Append(' ').Append(arguments); + strBld.Append(' ').Append(arguments); + + var launchedScript = strBld.ToString(); + this.logger.Write(LogLevel.Verbose, $"Launch script is: {launchedScript}"); - command.AddScript(escapedScriptPath.ToString(), false); + command.AddScript(launchedScript, false); } else { - command.AddCommand(escapedScriptPath.ToString(), false); + // AddCommand can handle script paths including those with special chars e.g.: + // ".\foo & [bar]\foo.ps1" and it can handle arbitrary commands, like "Invoke-Pester" + command.AddCommand(script, false); } if (writeInputToHost)