SOLVED

Batch file: filename with ampersand (&)

Copper Contributor

Hello,

 

I have a simple bat file named "test&.bat" with this content:

@echo off

echo This is test.bat
pause

When I use "Run as administrator" on the file, the pause command is not handled.

When I double-click on the file, it works.

When I rename the file as "test.bat", it works even with "Run as administrator".

 

Do you have any idea why the ampersand character causes troubles with "Run as administrator"?

4 Replies

@TaggAurel 

 

Yes, the ampersand has a very long history as a special character in the command prompt shell.

 

From the bottom of the command prompt shell help itself, it states:

 

The special characters that require quotes are:
<space>
&()[]{}^=;!'+,`~

 

So, put simply, your example needs to use double quotes to look like this:

 

@echo off

REM This following line will NOT work!
test&.bat

REM This will work.
"test&.bat"
pause

 

Cheers,

Lain

Thank you@LainRobertson for your answer!

But I still don't understand why the "right-click->Run as administrator" doesn't have the same behavior as double-click on file test&.bat.

Anyway, I have a workaround.

best response confirmed by TaggAurel (Copper Contributor)
Solution

@TaggAurel 

 

Taking a look behind the scenes with Process Monitor, the commands passed to the shell are formatted differently.

 

The TL;DR reason it that it's got to do with the Windows Explorer shell and a difference in how the filename is parsed and provided in the call to cmd.exe.

 

Initial observations from Process Monitor

When the filename contains the ampersand, the following occurs:

 

Normal user double-clickingExecutes
Run as administratorDoes not execute

 

So, the issue isn't the "pause" statement. The issue is the batch file doesn't actually run at all. cmd.exe is certainly called but the batch file within the new cmd.exe process fails to execute as it is interpreted as two separate commands.

 

This is because there's a difference in parsing in the Windows Shell between "normal" and "as administrator" launch experience.

 

The commands strings produced for each scenario were:

Normal user double-clicking
C:\Windows\system32\cmd.exe /c ""D:\Data\Temp\test&.bat" "
Run as administrator
"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test&.bat"

 

The character escaping and quoting issue

As I already mentioned, the ampersand is a reserved character that denotes the separation of commands. This is better discussed in the following article which also outlines how it can be a dangerous practice to leave unchecked.

 

Blaming the operating system for allowing people to create files with unusual characters in their na...

 

Even so, the issue isn't strictly the filename but rather that the parsing in the "run as administrator" version - through not properly escaping or quoting the arguments - is effectively producing two commands - not one - either side of the ampersand.

 

Reproduction

There are two easily-accessed methods for reproducing successful or erroneous outcomes:

 

  1. Via the Start | Run box;
  2. Via PowerShell's Start-Process commandlet.

For example, you can reproduce the baseline "run as administrator" failure using Start-Process as follows:

 

Start-Process -FilePath '"C:\Windows\System32\cmd.exe"' -ArgumentList @('/c', '"D:\Data\Temp\test&.bat"') -RedirectStandardError D:\Data\Temp\sp-out.txt

 

 

The redirected standard error file contains the two errors (one per line) associated with interpreting the filename as two separate commands:

'D:\Data\Temp\test' is not recognized as an internal or external command, operable program or batch file.
'.bat' is not recognized as an internal or external command, operable program or batch file.

 

Approaches to launching successfully

Rename the file to not include the ampersand

This doesn't need explaining as you're already aware of this.

 

"Double" double quotes

This is common in many programming an scripting languages but inaccessible from simple clicking on files in the shell (natively, at least - you could elect to create a properly-formatted shortcut.)

 

For example, doubling the quotes for the file path argument would take this:

"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test&.bat"

To this:

"C:\Windows\System32\cmd.exe" /C ""D:\Data\Temp\test&.bat""

 

Using Start-Process to demonstrate a successful launch using this method:

 

Start-Process -FilePath '"C:\Windows\System32\cmd.exe"' -ArgumentList @('/c', '""D:\Data\Temp\test&.bat""') -RedirectStandardError D:\Data\Temp\sp-out.txt

 

 

Properly escaping the ampersand

For the command shell, the caret is the nominated escaping character and should be used where special characters are used within the filename.

 

For example, escaping would take this:

"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test&.bat"

To this:

"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test^&.bat"

 

Using Start-Process to demonstrate a successful launch using this method:

 

Start-Process -FilePath '"C:\Windows\System32\cmd.exe"' -ArgumentList @('/c', '"D:\Data\Temp\test^&.bat"') -RedirectStandardError D:\Data\Temp\sp-out.txt

 

 

Summary

Using the ampersand in a filename isn't a good idea. That said, the underlying cause of the issue you noted is that two different command lines are produced depending on whether your simply double-click on the batch file or run it "as an administrator".

 

The former command line is properly quoted, allowing the command to run even with the ampersand, while the latter command line is neither properly formatted nor escaped, causing the associated cmd.exe process to be created but the command within that new process to fail execution.

 

The best solution is not to use reserved characters for any given shell within filenames but if that can't be avoided, to ensure the batch file(s) are launched using the proper escaping or quoting so the file name/path is not treated as separate commands (which is the by-design and expected outcome.)

 

Cheers,

Lain

Thank you very much @LainRobertsonn for your in-depth analysis.
It's clear for me now.
1 best response

Accepted Solutions
best response confirmed by TaggAurel (Copper Contributor)
Solution

@TaggAurel 

 

Taking a look behind the scenes with Process Monitor, the commands passed to the shell are formatted differently.

 

The TL;DR reason it that it's got to do with the Windows Explorer shell and a difference in how the filename is parsed and provided in the call to cmd.exe.

 

Initial observations from Process Monitor

When the filename contains the ampersand, the following occurs:

 

Normal user double-clickingExecutes
Run as administratorDoes not execute

 

So, the issue isn't the "pause" statement. The issue is the batch file doesn't actually run at all. cmd.exe is certainly called but the batch file within the new cmd.exe process fails to execute as it is interpreted as two separate commands.

 

This is because there's a difference in parsing in the Windows Shell between "normal" and "as administrator" launch experience.

 

The commands strings produced for each scenario were:

Normal user double-clicking
C:\Windows\system32\cmd.exe /c ""D:\Data\Temp\test&.bat" "
Run as administrator
"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test&.bat"

 

The character escaping and quoting issue

As I already mentioned, the ampersand is a reserved character that denotes the separation of commands. This is better discussed in the following article which also outlines how it can be a dangerous practice to leave unchecked.

 

Blaming the operating system for allowing people to create files with unusual characters in their na...

 

Even so, the issue isn't strictly the filename but rather that the parsing in the "run as administrator" version - through not properly escaping or quoting the arguments - is effectively producing two commands - not one - either side of the ampersand.

 

Reproduction

There are two easily-accessed methods for reproducing successful or erroneous outcomes:

 

  1. Via the Start | Run box;
  2. Via PowerShell's Start-Process commandlet.

For example, you can reproduce the baseline "run as administrator" failure using Start-Process as follows:

 

Start-Process -FilePath '"C:\Windows\System32\cmd.exe"' -ArgumentList @('/c', '"D:\Data\Temp\test&.bat"') -RedirectStandardError D:\Data\Temp\sp-out.txt

 

 

The redirected standard error file contains the two errors (one per line) associated with interpreting the filename as two separate commands:

'D:\Data\Temp\test' is not recognized as an internal or external command, operable program or batch file.
'.bat' is not recognized as an internal or external command, operable program or batch file.

 

Approaches to launching successfully

Rename the file to not include the ampersand

This doesn't need explaining as you're already aware of this.

 

"Double" double quotes

This is common in many programming an scripting languages but inaccessible from simple clicking on files in the shell (natively, at least - you could elect to create a properly-formatted shortcut.)

 

For example, doubling the quotes for the file path argument would take this:

"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test&.bat"

To this:

"C:\Windows\System32\cmd.exe" /C ""D:\Data\Temp\test&.bat""

 

Using Start-Process to demonstrate a successful launch using this method:

 

Start-Process -FilePath '"C:\Windows\System32\cmd.exe"' -ArgumentList @('/c', '""D:\Data\Temp\test&.bat""') -RedirectStandardError D:\Data\Temp\sp-out.txt

 

 

Properly escaping the ampersand

For the command shell, the caret is the nominated escaping character and should be used where special characters are used within the filename.

 

For example, escaping would take this:

"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test&.bat"

To this:

"C:\Windows\System32\cmd.exe" /C "D:\Data\Temp\test^&.bat"

 

Using Start-Process to demonstrate a successful launch using this method:

 

Start-Process -FilePath '"C:\Windows\System32\cmd.exe"' -ArgumentList @('/c', '"D:\Data\Temp\test^&.bat"') -RedirectStandardError D:\Data\Temp\sp-out.txt

 

 

Summary

Using the ampersand in a filename isn't a good idea. That said, the underlying cause of the issue you noted is that two different command lines are produced depending on whether your simply double-click on the batch file or run it "as an administrator".

 

The former command line is properly quoted, allowing the command to run even with the ampersand, while the latter command line is neither properly formatted nor escaped, causing the associated cmd.exe process to be created but the command within that new process to fail execution.

 

The best solution is not to use reserved characters for any given shell within filenames but if that can't be avoided, to ensure the batch file(s) are launched using the proper escaping or quoting so the file name/path is not treated as separate commands (which is the by-design and expected outcome.)

 

Cheers,

Lain

View solution in original post