【问题标题】:Passing Unicode parameters to Windows .bat file when rerunning it重新运行时将 Unicode 参数传递给 Windows .bat 文件
【发布时间】:2015-06-26 09:42:25
【问题描述】:

我的 .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 窗口上时,我得到:

,这很好。

当我对 2 做同样的事情时,我得到:

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

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

【问题讨论】:

  • set user=%2% 在批处理代码的第 8 行应为 set user=%2,末尾没有百分号。

标签: windows batch-file unicode dos


【解决方案1】:

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

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

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

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

您可以通过将文件名作为参数传递给脚本来避免将任意 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

【讨论】:

  • @Scott griffiths:看起来 jpen 在这里变得安静了。你还有什么想在这个答案中看到的吗?
  • @PeterBrittain:我刚刚刺激了 jpen,他在接受之前正在查看这个新答案。我认为我们有可行的解决方案,因此赏金可能会是最简单的。
【解决方案2】:

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

@echo off

chcp 65001
.
.
.

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

编辑:必须还为您的命令窗口使用支持 unicode 的字体,例如 Lucida Console。如果没有这个,命令处理器会在 unicode 字符上阻塞,要么找不到文件,要么可能显示“系统无法写入指定设备”错误。

单击命令窗口左上角的窗口图标,在菜单上选择 Defaults,然后在 Fonts 选项卡上选择 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”拖到窗口中时,然后将“C:\temp\test\フォルダ\file2.txt”拖到窗口中。

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

【讨论】:

  • @beercohol-我已经尝试过了,但不幸的是这并不能解决问题。输出消息更改为“错误:找不到文件:C:\Test\フォルダ\File.txt”
  • 请查看我更新的答案 - 我最初认为字体是可选的是错误的 - 您必须使用 unicode 字体才能使用!我已经使用您的批处理文件的一个子集进行了测试,并创建了一个具有相同名称的测试文件和文件夹,并且该脚本当字体设置为 Lucida Console 时运行良好。
  • @beercohol-Hmm 奇怪...我一直在使用 Lucida Console,但问题仍然存在。
  • 这很奇怪。我已经用我的测试批处理文件及其输出进一步更新了我的答案。也许你可以检查一下你从中得到了什么结果。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 2012-12-08
    相关资源
    最近更新 更多