Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Here you can propose new features, make suggestions etc.

Moderators: petermad, Stefan2, white, Hacker

User avatar
white
Power Member
Power Member
Posts: 6885
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *white »

Commands that are run on Total Commander's command line are generally executed "directly", but sometimes via "%comspec% /c <command>".

Since the earliest Windows Commander versions, "%comspec% /c " is added for these commands:
dir
ren
del
copy
type
date
time

And also when the redirection symbols are used on the command line:
|
<
>

So because "dir" is in the list above, running this command works:

Code: Select all

dir & pause
Although Total Commander is picky and you need to use a space behind "dir" here and no other standard delimiters (comma, semicolon, equal sign) are allowed.

Because "echo" is not in the list above, running this command results in a file not found message:

Code: Select all

echo ==Bare directory list== & dir /b & pause
The user can add "cmd /c" to make it work:

Code: Select all

cmd /c echo ==Bare directory list== & dir /b & pause
Or by using a redirection symbol in the command:

Code: Select all

echo ==Bare directory list== & dir /b & pause & rem|
So Total Commander has a smart implementation that adds "cmd.exe /c " when a redirection symbol is used.
However, the implementation is not smart enough to omit adding "cmd.exe /c " when the user already added "cmd.exe /c" himself. So when you run this command:

Code: Select all

cmd.exe /c echo Writing bare directory list to file.. & (echo ==Bare directory list== & dir /b/s) > dirlist.txt & echo. & pause
this is the command that actually ends up being executed:

Code: Select all

c:\WINDOWS\system32\cmd.exe /C cmd.exe /c echo Writing bare directory list to file.. & (echo ==Bare directory list== & dir /b/s) > dirlist.txt & echo. & pause
My suggestion is to make the implementation a little smarter so that "%comspec% /c " is not added when the command being executed is %comspec%.
Fla$her
Power Member
Power Member
Posts: 3973
Joined: 2020-01-18, 04:03 UTC

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *Fla$her »

All of this can be done independently using aliases.
Overquoting is evil! 👎
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 52920
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *ghisler(Author) »

I think it's a good idea to check whether there already is cmd or cmd.exe at the start of the command line when a pipe symbol is detected, and if yes, to not add another cmd to the front.

noclose.exe does something similar: If you press Shift+Enter on a command like cmd /C dir, then noclose.exe will add its own cmd /K in front of it. I have now modified noclose.exe/noclose64.exe to remove the cmd /C which is passed in from the caller, in the following cases:
1. The command must be cmd or cmd.exe
2. The parameters must be just /C or /K or no parameter. If other parameters are passed, the command will not be removed
3. If the passed command line behind /C is already in double quotes, no extra double quotes will be added.
Examples:
cmd /c echo ==Bare directory list== & dir /b & pause
-> c:\windows\system32\cmd.exe /S/K "echo ==Bare directory list== & dir /b & pause"
cmd.exe /c "echo ==Bare directory list== & dir /b & pause"
-> c:\windows\system32\cmd.exe /S/K "echo ==Bare directory list== & dir /b & pause"

You can download it here:
https://plugins.ghisler.com/addons/noclose_b3.zip
Author of Total Commander
https://www.ghisler.com
User avatar
white
Power Member
Power Member
Posts: 6885
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *white »

ghisler(Author) wrote: 2026-06-01, 09:50 UTC I think it's a good idea to check whether there already is cmd or cmd.exe at the start of the command line when a pipe symbol is detected, and if yes, to not add another cmd to the front.
That makes sense because the purpose here is to add cmd when necessary, and when cmd is already included, it isn't necessary.

ghisler(Author) wrote: 2026-06-01, 09:50 UTC noclose.exe does something similar: If you press Shift+Enter on a command like cmd /C dir, then noclose.exe will add its own cmd /K in front of it. I have now modified noclose.exe/noclose64.exe to remove the cmd /C which is passed in from the caller, in the following cases:
This is different. The purpose here is not to add cmd when necessary for the command to work, but to always add cmd /K in order to start a console window that doesn't close after the command has been executed. If the command already included a cmd command, it is expected that another cmd command is added. The reason for you to prevent two cmd processes being started here seems to be efficiency rather than expectation of behavior. The reasoning here seems to be: It isn't necessary to add another cmd command to get the same result. However, the result is not the same:
  • cmd /K cmd /C <command> : the environment in the open console window is not changed by the command
  • cmd /K <command>: the environment in the open console window is changed by the command

ghisler(Author) wrote: 2026-06-01, 09:50 UTC 1. The command must be cmd or cmd.exe
2. The parameters must be just /C or /K or no parameter. If other parameters are passed, the command will not be removed
3. If the passed command line behind /C is already in double quotes, no extra double quotes will be added.
Examples:
cmd /c echo ==Bare directory list== & dir /b & pause
-> c:\windows\system32\cmd.exe /S/K "echo ==Bare directory list== & dir /b & pause"
cmd.exe /c "echo ==Bare directory list== & dir /b & pause"
-> c:\windows\system32\cmd.exe /S/K "echo ==Bare directory list== & dir /b & pause"
This would fix broken commands entered by the user and break valid commands entered by the user. I think you shouldn't change the command entered by the user. If you want to prevent another cmd process being used, you should simply replace /C with /K, without adding /S and without adding quotes.

Example of a command that breaks:

Code: Select all

cmd /c "c:\Program Files\Notepad++\notepad++.exe"
Run the command using Shift+Enter (using the noclose files from noclose_b3.zip) and what will be executed is:

Code: Select all

cmd /S/K "c:\Program Files\Notepad++\notepad++.exe"
Which results in the error:
'c:\Program' is not recognized as an internal or external command,
operable program or batch file.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 52920
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *ghisler(Author) »

You are right, I didn't consider this. Here is a new noclose beta:
https://plugins.ghisler.com/addons/noclose_b4.zip

Here I look whether the command starts with cmd or cmd.exe. If yes, and if there is a /C parameter, I replace cmd with "c:\windows\system32\cmd" and cmd.exe with "c:\windows\system32\cmd.exe", and /C with /K. If not, then I just put the cmd /S/K command in front and surround the whole command with double quotes as before.
Author of Total Commander
https://www.ghisler.com
User avatar
white
Power Member
Power Member
Posts: 6885
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *white »

ghisler(Author) wrote: 2026-06-02, 09:49 UTC Here I look whether the command starts with cmd or cmd.exe. If yes, and if there is a /C parameter, I replace cmd with "c:\windows\system32\cmd" and cmd.exe with "c:\windows\system32\cmd.exe", and /C with /K. If not, then I just put the cmd /S/K command in front and surround the whole command with double quotes as before.
Doesn't work if more parameters are used and there is no space before /C, for example:

Code: Select all

cmd /s/c "dir"
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 52920
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *ghisler(Author) »

You are right, it doesn't handle switches which aren't separated by spaces. Here is a new noclose beta:
https://plugins.ghisler.com/addons/noclose_b5.zip
Author of Total Commander
https://www.ghisler.com
User avatar
white
Power Member
Power Member
Posts: 6885
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *white »

ghisler(Author) wrote: 2026-06-03, 07:54 UTC You are right, it doesn't handle switches which aren't separated by spaces. Here is a new noclose beta:
https://plugins.ghisler.com/addons/noclose_b5.zip
Tested OK, but I did find an edge case. It can happen that the user enters a faulty command and the console window doesn't stay open after pressing Shift+Enter. But it might actually be a side effect that is useful.

I am talking about when the user makes the mistake of starting his command with "cmd /c" and doesn't specify a command, but does use input/output redirection. Or when he inserted a redirection character by mistake.

Example ahk script:

Code: Select all

Run, %comspec% /c 2>test.123
This causes a console window to be opened and closed, even when using the /K switch:

Code: Select all

Run, %comspec% /k 2>test.123
The file test.123 is not created.

The same thing happens when using Windows Run to execute the command.

In the current TC version, executing the command below on TC's command line causes the file test.123 to be created (or worse, overwritten if it already exists).

Code: Select all

cmd /c 2>test.123
This is because currently an extra "cmd /c" is added. If this is no longer done in TC 11.58, this won't be the case.

When executing above command using Shift+Enter and using noclose_b5.zip, no extra "cmd /K" is added, but /C is replaced by /K. In this case the console window doesn't stay open, but the good thing is that the file test.123 is not created.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 52920
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *ghisler(Author) »

The file test.123 is not created.
Can you give me more details? While the cmd window doesn't stay open even with the /K switch, it does stay open with Shift+Enter. Also the file test.123 is created here both with and without the /K switch.
In the current TC version, executing the command below on TC's command line causes the file test.123 to be created (or worse, overwritten if it already exists).
Indeed this creates test.123 in TC 11.57 but not in TC 11.58 RC2, so it's a good thing?
When executing above command using Shift+Enter and using noclose_b5.zip, no extra "cmd /K" is added, but /C is replaced by /K. In this case the console window doesn't stay open, but the good thing is that the file test.123 is not created.
Indeed it doesn't stay open, but I think that this is because the user didn't specify a command after /C (or /K), so cmd closes immediately.

So would you change anything in the current implementation of TC 11.58 RC2?
Author of Total Commander
https://www.ghisler.com
User avatar
white
Power Member
Power Member
Posts: 6885
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *white »

ghisler(Author) wrote: 2026-06-04, 13:23 UTC Indeed this creates test.123 in TC 11.57 but not in TC 11.58 RC2, so it's a good thing?
I think so, yes. The command contains a syntax error and normally would not create or overwrite a file. Try this in a command prompt window:

Code: Select all

D:\> >test.123
The syntax of the command is incorrect.

D:\>dir test.123
 Volume in drive D is Data
 Volume Serial Number is 3C01-C21F

 Directory of D:\

File Not Found
But if you execute the command via "cmd /C" or "cmd /K" and add an extra "cmd /C" or "cmd /K" in front of it, ">test.123" is parsed by the outer cmd process. That results in the file "test.123" being created or overwritten (and not the same command being executed). I think it is better to not have an open command prompt window, than this happening.

To produce another syntax error, use for example ">test.123 & pause" instead of ">test.123". Then, the syntax error is:

Code: Select all

& was unexpected at this time.

ghisler(Author) wrote: 2026-06-04, 13:23 UTC Indeed it doesn't stay open, but I think that this is because the user didn't specify a command after /C (or /K), so cmd closes immediately.
Not exactly. Not specifying a command is allowed: "cmd /k". But /K doesn't work if the command has a syntax error. Then the console window opens, a syntax error is displayed, and then the console window closes. To clearly see what happens, use powershell:

Code: Select all

PS D:\> cmd /s/c ">test.123"
The syntax of the command is incorrect.

PS D:\> cmd /s/k ">test.123"
The syntax of the command is incorrect.

PS D:\> dir test.123
dir : Cannot find path 'D:\test.123' because it does not exist.
As you can see, the PS prompt returns after executing cmd /s/k.
I added the quotes here because otherwise >test.123 would be parsed by powershell.

The same applies when using cmd:

Code: Select all

D:\>cmd /s/c ">test.123"
The syntax of the command is incorrect.

D:\>cmd /s/k ">test.123"
The syntax of the command is incorrect.

D:\>dir test.123
 Volume in drive D is Data
 Volume Serial Number is 3C01-C21F

 Directory of D:\

File Not Found

ghisler(Author) wrote: 2026-06-04, 13:23 UTC So would you change anything in the current implementation of TC 11.58 RC2?
For the case when the user uses Shift+Enter and the command already starts with cmd with parameter /K, you may want to consider not adding or changing anything, and launch the command as is. So that also in this case the command cannot be parsed differently and cannot cause a file being created when it shouldn't.

And you may want to prevent another cmd process being added also when the user uses full path for cmd (c:\windows\system32\cmd or c:\windows\system32\cmd.exe). And for both methods of execution (using Enter and using Shift+Enter).
User avatar
AntonyD
Power Member
Power Member
Posts: 2142
Joined: 2006-11-04, 15:30 UTC
Location: Russian Federation

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *AntonyD »

So can i have a clue?
New NOCLOSE willbe a part of 11.58 release?
#146217 personal license
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 52920
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *ghisler(Author) »

AntonyD wrote: New NOCLOSE willbe a part of 11.58 release?
Yes, beta 5 is already part of Total Commander 11.58 RC2.
white wrote:For the case when the user uses Shift+Enter and the command already starts with cmd with parameter /K, you may want to consider not adding or changing anything, and launch the command as is. So that also in this case the command cannot be parsed differently and cannot cause a file being created when it shouldn't.

And you may want to prevent another cmd process being added also when the user uses full path for cmd (c:\windows\system32\cmd or c:\windows\system32\cmd.exe). And for both methods of execution (using Enter and using Shift+Enter).
OK, I have added both. noclose will handle the following commands:

1. In the following group, it will prefix the command with c:\windows\system32\ and put it in double quotes, and replace /C with /K if needed:
cmd /s/c "dir"
cmd.exe /s/c "dir"
cmd /s/k "dir"
cmd.exe /s/k "dir"

2. In the following group, it leave the command unchanged, and replace /C with /K if needed:
c:\windows\system32\cmd /s/c "dir"
c:\windows\system32\cmd.exe /s/c "dir"
c:\windows\system32\cmd /s/k "dir"
c:\windows\system32\cmd.exe /s/k "dir"
"c:\windows\system32\cmd" /s/c "dir"
"c:\windows\system32\cmd.exe" /s/c "dir"
"c:\windows\system32\cmd" /s/k "dir"
"c:\windows\system32\cmd.exe" /s/k "dir"

3. Otherwise it will prepend "c:\windows\system32\cmd.exe" /s/k and put the original command in double quotes as before.

To make it easier to test, you can now call noclose with parameter /T (test):
noclose /T cmd /s/c "dir"
or typing
/T cmd /s/c "dir"
on the Total Commander command line and pressing Shift+Enter. This will show the resulting command line as a message box instead of executing the command.

Please try this test version:
https://plugins.ghisler.com/addons/noclose_b6.zip
Author of Total Commander
https://www.ghisler.com
User avatar
white
Power Member
Power Member
Posts: 6885
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *white »

ghisler(Author) wrote: 2026-06-05, 08:44 UTC Please try this test version:
https://plugins.ghisler.com/addons/noclose_b6.zip
Seems to work as described.



Edge case: quotes around cmd or cmd.exe

Code: Select all

"cmd" /c pause & rem >nul
Pressing Enter: Adding an extra cmd /C is prevented.
Pressing Shift+Enter: Adding an extra cmd /K is not prevented.



Suggestion for the help text

Current help:
Press Shift+Enter to open a command in a command line window which stays open after the command ends.
Start the command with an asterisk * to run as administrator, or two asterisks ** to run as a different user. *cmd will be replaced with cmd.exe in the System32 directory.
Suggestion: Split unrelated info into clearly separated paragraphs, use "command prompt window" instead of "command line window", add a note that the window doesn't always stay open.
Press Shift+Enter to open a command in a command prompt window which stays open after the command ends. Note: The window doesn't stay open if the command contains a syntax error when run in the command prompt window.

Start the command with an asterisk * to run as administrator, or two asterisks ** to run as a different user. *cmd will be replaced with cmd.exe in the System32 directory.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 52920
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *ghisler(Author) »

Edge case: quotes around cmd or cmd.exe
Please try this test version:
https://plugins.ghisler.com/addons/noclose_b7.zip

This one introduces a new test mode: It takes a UTF-16 LE text file as input, and tests all the cases inside.

Code: Select all

noclose.exe /Ttestcases.txt
Please check whether I missed any test cases! The tests are case insensitive, and assume that the Windows System32 directory is in
c:\Windows\System32 on the test system.
Author of Total Commander
https://www.ghisler.com
User avatar
white
Power Member
Power Member
Posts: 6885
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: Command line: Don't automatically add "cmd /c" if the command being executed is cmd

Post by *white »

ghisler(Author) wrote: 2026-06-07, 09:39 UTC This one introduces a new test mode: It takes a UTF-16 LE text file as input, and tests all the cases inside.

Code: Select all

noclose.exe /Ttestcases.txt
When doing this, noclose.exe often crashes. noclose64.exe sometimes.
Maybe it needs a small delay after displaying the message box?

noclose.exe
Exception Code: 0xc0000005
Exception Offset: 0x000015d0

noclose64.exe
Exception Code: 0xc0000005
Exception Offset: 0x00000000000016a0
Post Reply