Передача параметров Unicode в Windows.файл bat при повторном запуске

мой .bat файл выглядит так:

@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%system32cacls.exe" "%SYSTEMROOT%system32configsystem"

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

У меня есть эти два тестовых файла:

  1. C:TestFolderファイル.txt
  2. C:TestフォルダFile.txt

когда я запускаю пакетный файл выше и перетаскиваю 1 в окно cmd, я получаю:

enter image description here

, это хорошо.

когда я делаю то же самое для 2, я получаю:

enter image description here

когда я вызываю UAC.ShellExecute, %файл% не передается правильно.

Как я могу обойти эту проблему?

3 ответов


мой предпочтительный способ запуска пакетного файла с правами администратора-создать ярлык, а затем пометить этот ярлык как требующий прав администратора.

сначала щелкните правой кнопкой мыши foo.bat, затем создайте ярлык. Откройте свойства для этого ярлыка, нажмите кнопку дополнительно... и включения Запуск от имени администратора.

У этого есть недостаток: вы не можете перетащить имена файлов в результирующее окно командной строки. Но вы можете перетащить файл на ярлыке.

но что, если я не хочу или не могу использовать ярлык?

вы можете избежать необходимости записывать произвольные символы Юникода в файл, передавая имя файла в качестве аргумента скрипту. Даже если файл VBS находится в кодировке ANSI, узел сценария всегда использует Unicode внутри.

Итак, вот как вы пишете файл VBS и запускаете его:

:: 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

попробуйте добавить команду CHCP (изменить кодовую страницу) для запуска пакетного файла, используя кодовую страницу UTF-8 65001, e.g:

@echo off

chcp 65001
.
.
.

см. здесь немного больше информации об идентификаторах кодовой страницы: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs. 85).aspx

EDIT: вы должны также используйте шрифт с поддержкой unicode, например консоль Lucida, для командного окна. Без этого командный процессор подавится символы unicode и либо не найдут файлы, либо могут отображать ошибку "система не может записать на указанное устройство".

щелкните значок окна в левом верхнем углу окна команд, выберите в меню пункт по умолчанию, затем на вкладке шрифты выберите консоль Lucida.

UPDATE-тестовый пакетный файл и вывод ниже.

вот пакетный файл, который я использую для проверки этого:

@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%"
)

вот результат моего теста, когда я сначала перетаскиваю "C:\temp\test\ファイル.txt " в окно, затем во-вторых "C:\temp\test\フォルダ\file2 - ... формат txt."

моя система Win 7 Pro x64 SP1, с английскими настройками Великобритании.

Sample output


ваша проблема в том, что способ создания временного файла VBS означает, что он не является допустимым файлом unicode, и поэтому Windows не знает, как интерпретировать имя unicode, которое вы передали.

следуя совету beercohol использовать кодовую страницу 65001, я все еще обнаружил, что не могу получить доступ к файлу в каталоге unicode. Однако, если я попытался создать файл вручную с помощью редактора unicode (например, с помощью блокнота и сохранения в качестве кодировки unicode) и вызвать этот ручной скрипт вместо автогенерированный файл VBS, все это просто сработало.

я переработал ваш скрипт для использования iconv вместо этого создать файл utf-16. Обратите внимание, что этот сценарий должен быть запущен с кодовой страницей 65001 для работы.

@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