My .bat file looks like this:
@echo off
CD /D "%~dp0"
if [%2]==[] (
set user=%USERNAME%
) else (
set user=%2%
)
:getFile
if [%1]==[] (
set /p file=Enter file name :
) else (
set file=%~f1
echo File name: %~f1
)
:checkFile
for /f "useback tokens=*" %%a in ('%file%') do set file=%%~a
if not exist "%file%" (
echo Error: Could not find file: %file%
echo.
)
:: Check for admin permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' == '0' (
goto gotAdmin
)
:: Rerun this batch with admin rights
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "cmd", "/c """"%~f0"" ""%file%"" ""%user%""""", "%CD%", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
exit /B
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
pushd "%CD%"
CD /D "%~dp0"
echo.
:eof
pause
exit /B
I have these two test files:
When I run the batch file above and drag 1 onto the cmd window I get:
, which is good.
When I do the same for 2, I get:
When I call UAC.ShellExecute, %file% isn't passed correctly.
How can I get around this problem?
%%a refers to the name of the variable your for loop will write to. Quoted from for /? : FOR %variable IN (set) DO command [command-parameters] %variable Specifies a single letter replaceable parameter. (set) Specifies a set of one or more files.
You are able to prompt a user for input using a Batch script function.
Command line internal encoding (that changed with chcp) . bat Text Encoding.
My preferred way of starting a batch file with administrator permissions is to create a shortcut, and then mark that shortcut as requiring administrator permissions.
First right-click foo.bat, then create a shortcut. Open the properties for that shortcut, click the Advanced… button and enable Run as administrator.
This has a downside: you can't drag file names onto the resulting command prompt window. But you can drag a file onto the shortcut.
But what if I don't want or can't use a shortcut?
You can avoid the need to write arbitrary Unicode characters to the file by passing your file name as an argument to your script. Even if the VBS file is in ANSI encoding, the script host always uses Unicode internally.
So here is how you write the VBS file and run it:
:: Rerun this batch with admin rights
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "cmd", "/c """"%~f0"" """ + Wscript.Arguments.Item(0) + """ ""%user%""""", "%CD%", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs" "%file%"
exit /B
Try adding a CHCP (CHange Code Page) command to start of you batch file, using the UTF-8 code page 65001, e.g:
@echo off
chcp 65001
.
.
.
See here for a bit more info on code page identifiers: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
EDIT: You MUST also use a unicode capable font such as Lucida Console for your command window. Without this the command processor chokes on the unicode characters, and will either not find the files, or may display a "system cannot write to the specified device" error.
Click the window icon at the top-left of the command window, choose Defaults on the menu, then on the Fonts tab choose Lucida Console.
UPDATE - Test batch file and output below.
Here's the batch file I'm using to test this:
@echo off
chcp 65001
CD /D "%~dp0"
:getFile
if [%1]==[] (
set /p file=Enter file name :
) else (
set file=%~f1
echo File name: %~f1
)
:checkFile
for /f "useback tokens=*" %%a in ('%file%') do set file=%%~a
if not exist "%file%" (
echo Error: Could not find file: %file%
echo.
) else (
echo Found file "%file%"
)
Here is the output from my test, when I drag firstly "C:\temp\test\ファイル.txt" into the window, then secondly "C:\temp\test\フォルダ\file2.txt".
My system is Win 7 Pro x64 SP1, with English UK settings.
Your problem is that the way you create your temporary VBS file means it is not a valid unicode file and so Windows doesn't know how to interpret the unicode name you have passed in.
Following beercohol's advice to use code page 65001, I still found that I could not access a file in a unicode directory. However, if I tried to create the file by hand with a unicode editor (e.g. using notepad and saving as a unicode encoding) and invoke that manual script instead of the autogenerated VBS file, it all just worked.
I've re-worked your script to use iconv to create a utf-16 file instead. Note that this script needs to be run with code page 65001 in order to work.
@echo off
CD /D "%~dp0"
if [%2]==[] (
set user=%USERNAME%
) else (
set user=%2
)
:getFile
if [%1]==[] (
set /p file=Enter file name :
) else (
set file=%~f1
echo File name: %~f1
)
:checkFile
for /f "useback tokens=*" %%a in ('%file%') do set file=%%~a
if not exist "%file%" (
echo Error: Could not find file: %file%
echo.
)
:: Check for admin permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' == '0' (
goto gotAdmin
)
:: Rerun this batch with admin rights
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "cmd", "/c """"%~f0"" ""%file%"" ""%user%""""", "%CD%", "runas", 1 >> "%temp%\getadmin.vbs"
iconv.exe -f utf-8 -t utf-16le "%temp%\getadmin.vbs" > "%temp%\getadmin2.vbs"
"%temp%\getadmin2.vbs"
exit /B
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
if exist "%temp%\getadmin2.vbs" ( del "%temp%\getadmin2.vbs" )
pushd "%CD%"
CD /D "%~dp0"
echo.
:eof
pause
exit /B
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With