我的安装需要检查来自cmd.exe
的命令的结果。因此,我将命令的结果重定向到文本文件,然后尝试读取文件以获得如下结果:
// send command to cmd to execute and redirect the result to a text file
// try to read the file
szDir = "D:\\";
szFileName = "MyFile.txt";
if Is(FILEEXISTS, szDir ^ szFileName) then
listID = ListCreate(STRINGLIST);
if listID != LIST_NULL then
if OpenFIleMode(FILE_MODE_NORMAL) = 0 then
if OpenFile(nFileHandle, szDir, szFileName) = 0 then
// I run into problem here
while (GetLine(nFileHandle, szCurLine) = 0 )
ListAddString(listID, szCurLine, AFTER);
endwhile;
CloseFile(nFileHandle);
endif;
endif;
endif;
endif;
问题是,在执行命令提示符并将结果重定向到MyFile.txt
之后,我可以设置打开文件模式,打开文件但我无法读取任何文本到我的列表中。 ListReadFromFile()
没有帮助。如果我打开文件,手动编辑并保存,我的脚本就可以了。
调试后,我发现GetLine()
返回错误代码(-1),这意味着文件指针必须位于文件末尾或其他错误。但是,FILE_MODE_NORMAL
将文件设置为只读,并在文件开始时设置文件指针。
我可能做错了什么?这与文件的读/写访问有关吗?我尝试了这个没有结果的命令:
icacls D:\MyFile.txt /grant Administrator:(R,W)
我正在使用IstallShield 2018和Windows 10 64位顺便说一句。非常感谢您的帮助。
编辑1:我怀疑编码并试了几件事:
运行“wslconfig / l”后,在Notepad ++中打开的MyFile.txt内容没有编码,但仍显示正常且可读。我试图将内容转换为UTF-8,但它没有用。
如果我向文件添加内容(回显此行附加>>> MyFile.txt),则编码更改为UTF-8,但步骤1中的内容也会更改。在每个字符之间添加NULL(\ 0),甚至重新排列新行字符。也许这就是GetLine()无法读取文件的原因。
解决方法:在步骤1之后,我运行“find”my_desired_content“MyFile.txt”> TempFile.txt并读取TempFile.txt(以UTF-8编码)。
我的最终目标是检查“wslconfig / l”的结果中是否有“my_desired_content”,所以这很好。但是,我不明白的是,MyFile.txt和TempFile.txt都是从cmd命令创建的,但它们的编码方式不同?
答案 0 :(得分:1)
问题是由于文件的内容。假设这是您链接的问题生成的文件,您可以在十六进制编辑器中检查其内容,以找出以下事实:
我认为新行比文本编码更重要,但事实证明我已经倒退了。如果我单独更改这些内容,GetLine似乎可以正常运行CR,CR CR或CR LF,但只在BOM存在时才处理UTF-16。 (也就是说,在十六进制编辑器中,对于以字符W开头的文件,文件以FF FE 57 00而不是57 00开头。)
我有点不知所措,以解决这个问题。如果您正在接受挑战,则可以使用FILE_MODE_BINARYREADONLY读取该文件,并可以使用您对文件中应包含的内容的额外知识,以确保正确解释其编码。请注意,对于大多数UTF-16,您可以通过以下方式组合两个字节来创建单个代码单元:
szResult[i] = (nHigh << 8) + nLow;
其中nHigh
和nLow
可能是szBuffer[2*i + 1]
和szBuffer[2*i]
之类的值,假设您通过调用ReadBytes填充了STRING szBuffer。
其他未经证实的想法包括以二进制编辑它以确保BOM(FF FE)存在,找出确保文件最初使用BOM创建的方法,找出以备用编码创建文件的方法,找到另一个命令你可以调用&#34;修复&#34;该文件,或向供应商(我的雇主)提出请求,并希望开发团队更改某些内容以更好地处理此案例。
这是一个更简单的解决方法。如果您可以安全地假设该命令将附加没有签名的UTF-16字符,则可以将此输出附加到仅具有签名的文件。你怎么得到这样的文件?
您可以使用代码创建它。只需调用以下内容(为清晰起见,省略错误检查)
OpenFileMode(FILE_MODE_APPEND_UNICODE);
CreateFile(nFileHandle, szDir, szFileName);
CloseFile(nFileHandle);
如果szDir ^ szFileName不存在,它现在将是一个只有UTF-16签名的文件。
假设此文件名为sig.txt
,则可以调用该命令
wslconfig /l >> sig.txt
写入该文件。请注意追加加倍>>
。生成的文件将包含您提前创建的Unicode签名,以及wslconfig输出的Unicode数据,GetLine应正确解释。
这里最大的问题是这个硬编码围绕着wslconfig的行为,而且这种行为可能随时都会发生变化。这就是克里斯托弗暗示推荐API的原因,我完全同意。与此同时,您可以尝试通过在cmd /U
中调用它来使其更加健壮(但我理解这样做或保证最多是模糊的),或者尝试原始方式然后使用BOM
答案 1 :(得分:0)
这整个WSL的事情都很新鲜。我没有看到任何API,而是屏幕报废命令输出,您可能希望查看此注册表项:
HKEY_CURRENT_USER \ SOFTWARE \微软\的Windows \ CurrentVersion \ Lxss
它似乎有来自商店的安装发行版列表。来自商店可能解释了为什么这是HKCU而不是HKLM。
一个勇敢的新世界......叹息。