Elevated bat file with & or ^ in name dies

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Elevated bat file with & or ^ in name dies

#1 Post by aGerman » 28 Sep 2014 06:03

*** brief summary of this thread ***

Whenever you try to execute a batch file whose name contains an ampersand or caret via right click and "run as administrator" - it will fail to run.
The reason seems to be a bug in the elevation routine of Windows. The batch file cannot be found because the cmd is obviously called with the file path as an unquoted argument.
Even if jeb mentioned this behavior could be avoided by changing the command in the related registry key my experiences are that it doesn't help either ...
*******************************



I found that odd behavior when I tried to save the relative path of a file into a variable (%~pnx0) but it seems to be a general problem. For that reason I simplified my code for testing ...

The name of my test file has a space (to protect the %0 from being unquoted) and an ampersand (that triggers the behavior I mentioned).
"test (&).bat"

Code: Select all

@prompt $g
rem Hello from %0
pause>nul

When running it unelevated via double click it displays
>rem Hello from "G:\Documents\test (&).bat"

>pause1>nul


As soon as you right-click and run as administrator it dies with an error message I wasn't able to read (the window closes too fast).

Even more strange:
I created a 2nd batch file in the same directory.
"call_test.bat"

Code: Select all

@prompt $g
call "%~dp0test (&).bat"

If I run this batch code elevated I don't have any problems to access %0 (or modified parameters derived from it).
>call "G:\Documents\test (&).bat"

>rem Hello from "G:\Documents\test (&).bat"

>pause1>nul


It seems I have to process the CMDCMDLINE variable to extract the name. However I'm wondering if somebody out there can confirm that behavior or is it just me (Win7 x86)?

Regards
aGerman

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Elevated bat file with & in name dies when accessing %0

#2 Post by foxidrive » 28 Sep 2014 06:40

aGerman wrote:As soon as you right-click and run as administrator it dies with an error message I wasn't able to read (the window closes too fast).


I recorded the screen and here is the error (Win 8.1 32 bit)

Image

It looks like the term is not being quoted by Windows, similar to a drag and drop of a filename with & in it and no spaces etc.

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & in name dies when accessing %0

#3 Post by aGerman » 28 Sep 2014 06:48

Thanks foxi. That's what I feared.
It must be an internal problem though. As you can see I already included a space into the name to make sure the parameter is quoted and you could try with "%~0" or "%~f0" and the like - enclosing the term into quotes inside of the code doesn't help either.

Regards
aGerman

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & in name dies when accessing %0

#4 Post by aGerman » 28 Sep 2014 07:10

Addendum:
I don't even find a way to access CMDCMDLINE :roll: :lol:

Code: Select all

@prompt $g
rem %cmdcmdline%
pause>nul

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Elevated bat file with & in name dies when accessing %0

#5 Post by foxidrive » 28 Sep 2014 07:17

Yeah, it seems that the script itself is not running because of the characters in the filename.
The filename term isn't quoted by the elevation routine when passing it to a cmd prompt.

Call the batch file test & toast.bat and the same thing happens.

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & in name dies when accessing %0

#6 Post by aGerman » 28 Sep 2014 07:45

Another gorgeous little bug in a huge formicary :lol:

BTW I would really appreciate if we could find a way to work around it.

Regards
aGerman

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & in name dies

#7 Post by aGerman » 28 Sep 2014 08:58

foxidrive wrote:Yeah, it seems that the script itself is not running because of the characters in the filename.
The filename term isn't quoted by the elevation routine when passing it to a cmd prompt.

I shortened the topic from
"Elevated bat file with & in name dies when accessing %0"
to
"Elevated bat file with & in name dies"

Even a zero sized batch file would interrupt with the error message that foxi recorded before the OS realizes that the file is empty.

Thus, I'm virtually certain there is no work-around at all :(

Regards
aGerman

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Elevated bat file with & in name dies

#8 Post by foxidrive » 28 Sep 2014 09:02

How is this being used aGerman?

Do you need to run this by right-clicking or do you just want a script solution to get a UAC prompt and get it to run as admin?

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & in name dies

#9 Post by aGerman » 28 Sep 2014 09:27

Actually I don't expect file names with ampersands. It's just because I thought nobody would need to take care. Nothing in particular but a general issue...

The code I wrote can be placed to an external drive (pen drive or the like) to remount its volume to a certain drive letter. When you call it then it will write a temporary batch code in %temp%, call it and quit. The temporary code will do the remounting and call the origin batch file again. To be able to do the latter I have to save the relative path of the file.

Code: Select all

@echo off &setlocal DisableDelayedExpansion
:::::::::::::::::::::::::::::: New Drive Letter ::::::::::::::::::::::::::::::::
set "driveletter=x"

:::::::::::::::::::::::: Don't change anything here ... ::::::::::::::::::::::::
if defined __tmp__ (
  call :code
  exit /b
)
if defined driveletter (
  set "driveletter=%driveletter:~0,1%"
  call :toUpper driveletter
  if not defined driveletter set "driveletter=^!"
  setlocal EnableDelayedExpansion
  echo ABCDEFGHIJKLMNOPQRSTUVWXYZ|findstr /c:"!driveletter!" >nul ||(
    echo !driveletter! ist no letter.
    endlocal
    pause
    exit /b 1
  )
  if /i "%~d0"=="!driveletter!:" (
    endlocal
    call :code
    exit /b
  )
  endlocal
) else (
  echo The drive letter isn't defined.
  pause
  exit /b 1
)
if /i "%~d0"=="%SystemDrive%" (
  echo The system drive must not be changed.
  pause
  exit /b 1
)
mountvol %driveletter%:\ /l >nul &&(
  echo The drive letter %driveletter% is already in use.
  pause
  exit /b 1
)
fsutil fsinfo drives|findstr /c:":\\">nul &&(
  set "__tmp__=%random%_%random%"
  set "__relpath__=%~pnx0"
  call :mount
  exit /b 0
) || (
  echo Run as administrator!
  pause
  exit /b 1
)
:mount
for /f "tokens=*" %%i in ('mountvol %~d0 /l') do set "__volume__=%%i"
>"%temp%\mnt_%__tmp__%.bat" echo @echo off ^&setlocal
>>"%temp%\mnt_%__tmp__%.bat" echo ^>nul ping -n 2 localhost
>>"%temp%\mnt_%__tmp__%.bat" echo mountvol %~d0 /d
>>"%temp%\mnt_%__tmp__%.bat" echo mountvol %driveletter%: %__volume__% ^|^| (mountvol %~d0 %__volume__% ^&del "%%~f0" ^&exit^)
>>"%temp%\mnt_%__tmp__%.bat" echo cd /d %driveletter%:\
>>"%temp%\mnt_%__tmp__%.bat" echo for %%%%i in ("%driveletter%:%%__relpath__%%"^) do start /b /d "%%%%~dpsi" cmd /c "%%%%~fsi"
>>"%temp%\mnt_%__tmp__%.bat" echo del "%%~f0" ^&exit
start /b cmd /c "%temp%\mnt_%__tmp__%.bat"
exit /b 0
:toUpper
setlocal EnableDelayedExpansion
set ^"LF=^

^"  The above empty line is critical - DO NOT REMOVE
set "str=!%~1!"
if not defined str exit /b
set "str=!str:@=@A!"
set "str=!str:"=@Q!"
set "rtn="
setlocal DisableDelayedExpansion
for /f skip^=1^ delims^=^ eol^= %%i in (
  '2^>^&1 cmd /von /c fc "!LF!!str!!LF!" nul'
) do if not defined rtn set "rtn=%%i"
setlocal EnableDelayedExpansion
set "rtn=!rtn:@Q="!"
set "rtn=!rtn:@A=@!"
for /f "delims=" %%i in (""!rtn!"") do (
  endlocal&endlocal&endlocal
  set "%~1=%%~i"
)
exit /b
:code
cd /d "%~dp0"

:::::::::::::::::::: Code to be executed after remounting ::::::::::::::::::::::
echo Hello World from drive %~d0
pause

Development still in progress ... :wink:

Regards
aGerman

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & or ^ in name dies

#10 Post by aGerman » 28 Sep 2014 12:38

The bug in the elevation routine is more comprehensive than I was aware. The same behavior with a ^ in the name. (I changed the topic again.)

Regards
aGerman

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & or ^ in name dies

#11 Post by aGerman » 28 Sep 2014 16:42

Not the same behavior because it happens with or without running as administrator: A batch name with a predefined variable (e.g. "test %path%.bat") will not run. The variable will be expanded and causes various error messages depending on the variable content.

jeb
Expert
Posts: 1063
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Elevated bat file with & or ^ in name dies

#12 Post by jeb » 29 Sep 2014 00:15

Hi aGerman,

a while ago I tested this issue with the same results you discovered.

But there exists a solution for most of the charcacters.

You can change the cmdfile open entry in the registry from
cmd.exe %1 %*
to
cmd.exe "%~1" %*


At HK_ROOT\cmdfile\shell\open\command

But as said this solve not all problems, I never found a solution for filenames with percents inside.

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Elevated bat file with & or ^ in name dies

#13 Post by aGerman » 29 Sep 2014 13:20

I figured you would get into the act :wink: Thanks for the hint to the registry. I'll do some experiments and leave a summary in the first post later on. Unfortunately my first tests don't show any differences. "%1" was already quoted and changing to "%~1" didn't help at all. I also changed the value in HKEY_CLASSES_ROOT\cmdfile\shell\runas\command

Concerning variables in batch file names I should certainly open a new topic ... Of course you're welcome to post your experiences.

Regards
aGerman

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Elevated bat file with & or ^ in name dies

#14 Post by penpen » 30 Sep 2014 03:39

I'm just a little bit curious (and actually i have no access to win 7):
Is windows 7 just cutting the filename, or does it execute the rest of the filename as a command?
For example what happens when using a filename like this "test & cmd /K echo awful.bat"?

penpen

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Elevated bat file with & or ^ in name dies

#15 Post by foxidrive » 30 Sep 2014 03:59

penpen wrote:For example what happens when using a filename like this "test & cmd /K echo awful.bat"?


You can't have a / in a filename.

Post Reply