我有一个批处理脚本,它使用拖放并根据放置的文件/文件夹的文件名创建一些html代码。跟
chcp 65001
我得到这个来编写 unicode。一切都很好,很好。至少在记事本编辑器中,而浏览器只显示垃圾。当我在记事本中重新保存文件时,该文件也可以在浏览器中正常工作。不幸的是,创建的 unicode 文件似乎缺少两个"unicode 标头"字符(0xFF 和 0xFE),就在文件之前,结果与十六进制转储 (http://www.fileformat.info/tool/hexdump.htm) 进行比较。
在这个主题上,我发现:http://www.robvanderwoude.com/type.php#Unicode
那里的链接文件不起作用(参数格式错误)这个网站关于非原生回声等的例子是不可能的。复制一个空的 unicodeHeader-Helper 文件并附加我的文件工作正常,但非常欠佳,因为这意味着,从中拖放文件的任何文件夹都需要包含此辅助文件。这不是假设的情况,因为它是不切实际的,所以这是不好的。
使用类型也是不可能的,因为它在字符之间创建了大量的空格。
所以我正在考虑将缺少标头的文件写入临时文件,将两个十六进制值添加到一个文件中并将临时文件附加到其中。所以基本上是直接编写十六进制字符,而不是从空的 unicode 帮助程序文件中复制它们。
我发现这个:http://www.dostips.com/forum/viewtopic.php?f=3&t=3857此外,还有:根据 Windows 批处理文件中的代码页 1252 将 7F (127)>字符写入十六进制字符串
我想我可以将示例十六进制值替换为0xFF和0xFE,并使其回显到文件:
@echo off
call :hex2Char 0xFF char_FF
call :hex2Char 0xFE char_FE
echo %char_FF% %char_800%
exit /b
:hex2Char hexString rtnVar
for /f delims^=^ eol^= %%A in (
'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(%~1"'
) do set "%~2=%%A" >> temp.txt
exit /b
但似乎事情并没有那么简单。由此产生的两个问题:1.它在其中写入了一些Unicode字符,但它与Unicode帮助程序文件不同,如hexdump所示。
file name: UniHeader.txt
mime type:
0000-0003: ef bb bf
file name: temp.txt
mime type:
0000-0000:
事实上,我可以更改 FF 或 FE,但它仍然只在十六进制转储输出中打印 0000-0000......
- 我可以在该文件之后添加任何我想要的内容(例如编写我的无头文件并将其附加到创建的文件中的代码,代码在第二个出口/b 处停止并且不再写入任何内容。(但是删除它会使整个事情根本不起作用,将其移动到文件的末尾会使它无法找到正在放在蝙蝠上的文件)老实说,我目前没有通过这几行代码行。exit/b 标记命令的结束,如果我正确理解,那么,为什么它在第一个退出/b 后继续工作,但在第二个出口/b 处停止?我也尝试使用标签和goto,没有用。
我现在不知所措。有什么优雅的方法可以解决这个问题吗?
您可以在批处理脚本中嵌入 base64 编码的部分,该脚本将创建一个 2 字节文件,然后使用 copy /b "my_header_file.bin" + "myfile.html" newfile.htm"
将目标文件添加到其中。
它使用 certutil
进行解码(并使用 -encode 进行 certutil 来创建文本部分),因此需要 Vista 及更高版本。
以下是创建包含十六进制的头文件的脚本:FF FE
@echo off
(
echo -----BEGIN CERTIFICATE-----
echo //4=
echo -----END CERTIFICATE-----
)>header.tmp
certutil -decode -f header.tmp "my_header_file.bin" >nul
del header.tmp
copy /b "my_header_file.bin" + "myfile.html" "newfile.html"
move /y "newfile.htm" "myfile.html" >nul
del "my_header_file.bin"
将它们包含在批处理文件中。
@echo off
for /f "tokens=2 delims=:" %%f in ('findstr /b /c:"BOFM:" "%~dpnx0"') do echo %%f
exit /b
rem Here starts the special characters part
BOFM:ÿþ:
以 BOFM: 开头的行被键入为 ALT+charchode 以获得所需的字符。
编辑-
我放弃了。我无法使其在批处理文件、数据文件和编辑器中与多个页面代码一致地工作。没有办法保证会生成什么。所以,我接受了@foxidrive答案(太棒了!)来生成文件前缀并尝试了。
我发现,如果我们使用 FF FE
作为从不是 unicode 模式(/u
参数)但使用 unicode 页面码 (65001) cmd
生成的文件的前缀,我们正在生成一个标记为 unicode(前缀)的文件,但内容不是,我们每个字符只生成一个字节。所以我们得到了"中国人"?字符,只是将单字节字符流向两个字节字符的错误转换。
如果我们使用相同的前缀,但来自 unicode cmd(带有 /u
参数)和 unicode 页面码 (65001),则会生成一个真正的 unicode 文件,并且内容从命令行、记事本和浏览器正确显示(在 ie 和 Firefox 中测试)。但这是一个真正的 unicode 文件,因此每个字符生成两个字节。
代替FF FE
,我们可以发送一个utf8 BOM EF BB BF
,从一个非Unicode cmd,但使用Unicode页面代码。这将生成一个带有 BOM 前缀的 utf8,一个或多字节的字符(取决于每个字符的 utf 编码),该字符在编辑器和浏览器中正确显示,但在命令行中无法正确显示。
我一直在尝试的代码(改编自 OP 附加文件)是(从非 unicode cmd 运行):
@echo off
if ["%~1"]==[""] goto :EOF
setlocal enableextensions enabledelayedexpansion
rem File to generate
set "myFile=aText.txt"
rem save current pagecode
for /f "tokens=2 delims=:" %%f in ('chcp') do set "cp=%%f"
rem Generate BOM
call :generateBOM "%myFile%"
rem change to unicode
chcp 65001 > nul
:loop
echo %1 >> "%myFile%"
for %%a in ("%1") do (
echo %%~nxa
echo ^<br^>^<img src='%%~nxa'^>^<br^>
) >> "%myFile%"
shift
if ["%~1"]==[""] goto showData
goto loop
:showData
"%myFile%"
:endProcess
rem Cleanup and restore pagecode
endlocal & chcp %cp% > nul
exit /b
:generateBOM file
rem [ EF BB BF ] utf8 bom encoded value = 77u/
rem [ FF FE ] unicode bom encoded value = //4=
echo 77u/>"%~1"
rem Yes, certutil allows decode inplace, so no temporary file needed
certutil -f -decode "%~1" "%~1" >nul
endlocal
goto :EOF
你可以通过以下方式创建 Unicode 标头 ( CertUtil -decodehex
0xFF 0xFE
):
rem // Create hexadecimal-encoded file:
> "header.tmp" (echo FF FE)
rem // Decode file to binary header file:
> nul CertUtil -f -decodehex "header.tmp" "header.tmp"
rem // Combine binary header file and Unicode text file:
copy /B "header.tmp" + "U-file.txt" "header.tmp"
rem // Move combined file over original Unicode text file:
move /Y "header.tmp" "U-file.txt"
使用 forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo(0xFF0xFE"
的方法有问题,因为echo
会产生尾随换行符。echo(0xFF0xFE
的替代方法是 < nul set /P ="0xFF0xFE"
,但这也不起作用,因为set /P
从消息文本中删除前导空格,并且0xFF
被认为是这样(不幸的是,它是一个不间断的空格)。