PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
44.22k stars 7.15k forks source link

The path in the environment variable %Path% with double quotes is not recognized. (PowerShell 7.4.3) #24002

Open miywm opened 4 weeks ago

miywm commented 4 weeks ago

Prerequisites

Steps to reproduce

  1. Set Environment Variables PATH=C:\Users\WDAGUtilityAccount\Desktop\New folder The folder contains a program named "ConsoleApplication1.exe", when you run it, the output is "Program is run".
  2. Open powershell
  3. Type in ConsoleApplication1 and enter
  4. "Program is run"
  5. Close powershell
  6. Set Environment Variables PATH=C:\Users\WDAGUtilityAccount\Desktop\New;folder Change the folder name to New;folder
  7. Open powershell
  8. Type in ConsoleApplication1 and enter
  9. Error
  10. Open CMD
  11. Type in ConsoleApplication1 and enter
  12. "Program is run" CMD can do it. I found that powershell does not recognize paths in %Path% that are wrapped in double quotes. (Paths are wrapped in double quotes when they contain ";"). I'm sure powershell isn't set up that way on purpose?

Expected behavior

PowerShell 7.4.3
PS C:\Users\WDAGUtilityAccount> ConsoleApplication1
Program is run

Actual behavior

PowerShell 7.4.3
PS C:\Users\WDAGUtilityAccount> ConsoleApplication1
ConsoleApplication1: The term 'ConsoleApplication1' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Error details

PS C:\Users\WDAGUtilityAccount> Get-Error

Exception             :
    Type        : System.Management.Automation.CommandNotFoundException
    ErrorRecord :
        Exception             :
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : The term 'ConsoleApplication1' is not recognized as a name of a cmdlet, function, script file,
or executable program.
                      Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.
            HResult : -2146233087
        TargetObject          : ConsoleApplication1
        CategoryInfo          : ObjectNotFound: (ConsoleApplication1:String) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : CommandNotFoundException
        InvocationInfo        :
            ScriptLineNumber : 1
            OffsetInLine     : 1
            HistoryId        : 1
            Line             : ConsoleApplication1
            Statement        : ConsoleApplication1
            PositionMessage  : At line:1 char:1
                               + ConsoleApplication1
                               + ~~~~~~~~~~~~~~~~~~~
            InvocationName   : ConsoleApplication1
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    CommandName : ConsoleApplication1
    TargetSite  :
        Name          : LookupCommandInfo
        DeclaringType : [System.Management.Automation.CommandDiscovery]
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Message     : The term 'ConsoleApplication1' is not recognized as a name of a cmdlet, function, script file, or
executable program.
                  Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
    Data        : System.Collections.ListDictionaryInternal
    Source      : System.Management.Automation
    HResult     : -2146233087
    StackTrace  :
   at System.Management.Automation.CommandDiscovery.LookupCommandInfo(String commandName, CommandTypes commandTypes,
SearchResolutionOptions searchResolutionOptions, CommandOrigin commandOrigin, ExecutionContext context)
   at System.Management.Automation.CommandDiscovery.LookupCommandProcessor(String commandName, CommandOrigin
commandOrigin, Nullable`1 useLocalScope)
   at System.Management.Automation.ExecutionContext.CreateCommand(String command, Boolean dotSource)
   at System.Management.Automation.PipelineOps.AddCommand(PipelineProcessor pipe, CommandParameterInternal[]
commandElements, CommandBaseAst commandBaseAst, CommandRedirection[] redirections, ExecutionContext context)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput,
CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][]
commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          : ConsoleApplication1
CategoryInfo          : ObjectNotFound: (ConsoleApplication1:String) [], CommandNotFoundException
FullyQualifiedErrorId : CommandNotFoundException
InvocationInfo        :
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 1
    Line             : ConsoleApplication1
    Statement        : ConsoleApplication1
    PositionMessage  : At line:1 char:1
                       + ConsoleApplication1
                       + ~~~~~~~~~~~~~~~~~~~
    InvocationName   : ConsoleApplication1
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1

Environment data

PS C:\Users\WDAGUtilityAccount> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.4.3
PSEdition                      Core
GitCommitId                    7.4.3
OS                             Microsoft Windows 10.0.22621
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

mklement0 commented 4 weeks ago

Indeed, PowerShell doesn't support "..."-enclosed entries in $env:PATH in direct invocation (see below), whereas cmd.exe does.

Note that POSIX-compatible shells such as bash, like PowerShell, also do not support "..."-enclosed entries.

Arguably, PowerShell and POSIX-compatible shells either should support "..."-enclosed entries or support a way to escape the entry-separator character (which is ; on Windows, and : on Unix-like platforms), but they do not.


By contrast, when you use Start-Process, as well as the [System.Diagnostics.Process] API with UseShellExecute = $true, which is equivalent, "..."-enclosed entries ARE recognized.

This may come down to differences between two WinAPI functions:

Given that direct invocation in cmd.exe (as opposed to use of the internal start command) presumably also uses CreateProcess(), there may be custom logic in cmd.exe for interpreting %PATH%.