重新运行时将 Unicode 参数传递给 Windows .bat 文件

Passing Unicode parameters to Windows .bat file when rerunning it

我的 .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%\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

我有这两个测试文件:

  1. C:\Test\Folder\ファイル.txt
  2. C:\Test\フォルド\File.txt

当我 运行 上面的批处理文件并将 1 拖到 cmd window 我得到:

,不错

当我对 2 执行相同操作时,我得到:

当我调用 UAC.ShellExecute 时,%file% 没有正确传递。

我怎样才能解决这个问题?

尝试使用 UTF-8 代码页 65001 在批处理文件的开头添加 CHCP(更改代码页)命令,例如:

@echo off

chcp 65001
.
.
.

有关代码页标识符的更多信息,请参阅此处:https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx

编辑:必须还为您的命令window使用支持 unicode 的字体,例如 Lucida Console。没有这个,命令处理器会阻塞在 unicode 字符上,并且将找不到文件,或者可能会显示 "system cannot write to the specified device" 错误。

单击命令 window 左上角的 window 图标,在菜单上选择默认值,然后在字体选项卡上选择 Lucida Console。

更新 - 测试批处理文件和输出如下。

这是我用来测试的批处理文件:

@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" 拖入 window,然后再将 "C:\temp\test\フォルダ\file2.txt".

我的系统是 Win 7 Pro x64 SP1,英语 UK 设置。

您的问题是您创建临时 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

我使用管理员权限启动批处理文件的首选方法是创建一个快捷方式,然后将该快捷方式标记为需要管理员权限。

首先右击foo.bat,然后创建一个快捷方式。打开该快捷方式的属性,单击 高级... 按钮并以管理员身份启用 运行.

这有一个缺点:您不能将文件名拖到生成的命令提示符上 window。但是您可以将文件拖到快捷方式上。

但是如果我不想或不能使用快捷方式怎么办?

您可以通过将文件名作为参数传递给脚本来避免将任意 Unicode 字符写入文件的需要。即使 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