Installation InstallScript GetLine()无法从命令提示符读取包含结果的文本文件

Installation InstallScript GetLine()无法从命令提示符读取包含结果的文本文件,installation,command-prompt,installshield,Installation,Command Prompt,Installshield,我的安装需要检查cmd.exe中命令的结果。因此,我将命令的结果重定向到文本文件,然后尝试读取该文件以获得如下结果: //向cmd发送命令以执行并将结果重定向到文本文件 //尝试读取该文件 szDir=“D:\\”; szFileName=“MyFile.txt”; 如果是(文件存在,szDir^szFileName),则 listID=ListCreate(STRINGLIST); 如果listID!=然后列出空值 如果OpenFIleMode(文件模式正常)=0,则 如果OpenFile(n

我的安装需要检查
cmd.exe
中命令的结果。因此,我将命令的结果重定向到文本文件,然后尝试读取该文件以获得如下结果:

//向cmd发送命令以执行并将结果重定向到文本文件
//尝试读取该文件
szDir=“D:\\”;
szFileName=“MyFile.txt”;
如果是(文件存在,szDir^szFileName),则
listID=ListCreate(STRINGLIST);
如果listID!=然后列出空值
如果OpenFIleMode(文件模式正常)=0,则
如果OpenFile(nFileHandle、szDir、szFileName)=0,则
//我在这里遇到了问题
while(GetLine(nFileHandle,szCurLine)=0)
ListAddString(listID、szCurLine、AFTER);
结束时;
CloseFile(nFileHandle);
endif;
endif;
endif;
endif;
问题是,在执行命令提示符后,结果被重定向到
MyFile.txt
,我可以设置打开文件模式,打开文件,但我无法在列表中读取任何文本<代码>ListReadFromFile()没有帮助。如果我打开文件,手动编辑并保存它,我的脚本就会工作

调试后,我发现
GetLine()
返回一个错误代码(-1),这意味着文件指针必须位于文件末尾或其他错误。但是,
FILE\u MODE\u NORMAL
将文件设置为只读,并将文件指针设置在文件的开头

我可能做错了什么?这是否与文件的读/写访问有关?我尝试了此命令,但没有结果:

icacls D:\MyFile.txt /grant Administrator:(R,W)
我正在使用IstallShield 2018和Windows 10 64位btw。非常感谢您的帮助

编辑1:我怀疑编码有问题,并尝试了一些方法:

  • 运行“wslconfig/l”后,在Notepad++中打开的MyFile.txt的内容没有编码,但仍然看起来正常且可读。我试图将内容转换为UTF-8,但没有成功

  • 如果我向文件中添加了一些内容(echo这一行被追加>>MyFile.txt),则编码会更改为UTF-8,但步骤1中的内容也会更改。将NULL(\0)添加到每个字符之间,甚至重新替换新行字符。也许这就是GetLine()读取文件失败的原因

  • 解决方法:在步骤1之后,我运行“查找”我想要的内容“MyFile.txt”>TempFile.txt并读取TempFile.txt(以UTF-8编码)


  • 我的最终目标是检查“wslconfig/l”的结果中是否出现了“我想要的内容”,这样就可以了。但是,我不明白的是,MyFile.txt和TempFile.txt都是从cmd命令创建的,但是它们的编码不同?

    问题是由于文件的内容。假设这是链接问题生成的文件,您可以在十六进制编辑器中检查其内容,以了解以下事实:

    • 其内容以UTF-16(LE)编码,无BOM
    • 它的新行编码为CR或CR,而不是CR LF
    我原以为换行符比文本编码更重要,但事实证明我把它颠倒了。如果我独立地更改其中的每一项,GetLine对于CR、CR或CR-LF似乎都能正常工作,但仅在存在BOM时处理UTF-16。(即,在十六进制编辑器中,文件以FF FE 57 00开头,而不是以字符W开头的文件以57 00开头。)

    我对解决这个问题的最佳方法有点不知所措。如果您面临挑战,您可以使用file_MODE_BINARYREADONLY读取文件,并且可以使用您关于文件中应该包含的内容的额外知识来确保正确解释其编码。请注意,对于大多数UTF-16,您可以通过以下方式组合两个字节来创建单个代码单元:

    szResult[i] = (nHigh << 8) + nLow;
    
    如果szDir^szFileName不存在,它现在将是一个只有UTF-16签名的文件

    假设该文件名为
    sig.txt
    ,则可以调用该命令
    wslconfig/l>sig.txt
    写入该文件。注意append的
    >
    。生成的文件将包括您提前创建的Unicode签名,以及wslconfig输出的Unicode数据,GetLine应该正确解释这些内容


    这里最大的问题是,它对wslconfig的行为进行了硬编码,并且这种行为可能会在任何时候发生变化。这就是为什么Christopher提到推荐API,我完全同意。同时,您可以尝试通过在
    cmd/U
    中调用它(但我对它的作用或保证的理解充其量是模糊的),或者尝试使用原始方式,然后使用BOM来增强它的健壮性。

    整个WSL都是全新的。我没有看到任何API,但您可能希望查看以下注册表项,而不是屏幕报废命令输出:

    HKEY\ U当前\用户\软件\ Microsoft\Windows\CurrentVersion\Lxss

    它似乎有来自商店的已安装发行版列表。来自商店可能解释了为什么这是HKCU而不是HKLM


    一个勇敢的新世界。。。。叹气。

    鉴于Michael在下面描述的问题,您能否让我们知道您在
    cmd.exe
    中正在做什么,以便我们可以看看是否有其他方法可以避免此技术问题?简而言之,我只想在cmd.exe中运行“wslconfig”后得到结果。你可以在这里找到你想要的:。是的,cmd提示符和处理重定向的各种方式几乎是神奇的。但是
    echo test>echo.txt
    echo line2>>echo.txt
    wslconfig/l>wsl.txt
    产生了非常不同的编码(ANSI CRLF与Unicode CR w/o签名)。还可以考虑<代码> > WSLCONFIG/L.FunSTRR故障或 WSLCONFIG/L.FUNSTRESE < /代码>;两者都会产生奇怪的结果。我将考虑WSLCONFIG如何将其输出写入TH。
    OpenFileMode(FILE_MODE_APPEND_UNICODE);
    CreateFile(nFileHandle, szDir, szFileName);
    CloseFile(nFileHandle);