2

I have a file a.cmd. Path to the file is C:\Program Files\a\a.cmd and C:\Program Files\a is in PATH environment variable. When I invoke a.cmd from PowerShell (v. 7.2) I see that a process with the following command line is created:

C:\WINDOWS\system32\cmd.exe /c ""C:\Program Files\a\a.cmd""

I wonder what the quotes add (OS, PowerShell or something else) and how cmd.exe handles the arguments list. When I replace cmd.exe with a custom .NET program (eg. by changing COMSPEC env variable) I see following command line args (from the cmd.exe replacement perspective):

arg 0: /c
arg 1: C:\Program
arg 2: Files\a\a.cmd

and whole command line is (System.Environment.CommandLine):

replaced.exe /c C:\Program Files\a\a.cmd

and it make sense to me.

As I know an OS parses a command line and passes it to a process. How does cmd.exe handle these arguments and how can cmd.exe open proper file?

1 Answer 1

1

what the quotes add: double-quotes in CMD can sometimes be escaped by doubling them to "". In this case, CMD just treats them as one double-quote. The second one is there in case the path was not quoted by the launching program.

how cmd.exe handles the arguments list: There's a lot of legacy answers to that, but in this case:

  • Powershell launches the default program for .cmd files: cmd.exe
  • And windows registry entries determine which/how arguments are passed to default programs:
Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Classes\cmdfile\shell\runas\command

(default)    : C:\WINDOWS\System32\cmd.exe /C "%1" %*

Which spells out:

  1. launch cmd.exe with the /C parameter,
  2. then the first argument %1 in quotes (also why you see double-double-quotes in the process cmdline)
  3. then the remaining args %* (space-delimited)

So powershell (or any program) can also pass more args to a .cmd script like a.cmd arg1 arg2

4
  • Not sure are you right. I changed COMSPEC variable to e.g. replaced.exe and I see PowerShell runs "replaced.exe" /c ""C:\Program Files\a\a.cmd"" (spotted in Process Monitor) not the command from registry.
    – kkj
    Commented Sep 27, 2023 at 21:21
  • @kkj yeah the registry stuff might not apply in win 10 since default program registrations aren't handled there anymore. There might be some old OS hook to add /C or redirect cmd based on comspec when running cmd-related commands (remember NT cmd.exe is 30 years old now), but the idea is the same.
    – Cpt.Whale
    Commented Sep 28, 2023 at 19:31
  • @kkj the command you used in the question, replaced.exe /c C:\Program Files\a\a.cmd, did not have quotes around the path, so it was treated as two arguments because of the space. The OS handles parsing a.cmd to "C:\Program Files\a\a.cmd" with quotes
    – Cpt.Whale
    Commented Sep 28, 2023 at 19:33
  • @io-oi No, it is simple program just for debug arguments and whole command line. You can use pwsh.exe or other and the result will be the same.
    – kkj
    Commented Sep 29, 2023 at 13:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .