inno-setup - 从 IWinHttpRequest 返回的二进制数据已更改,无法将 Variant 转换为字节数组
问题描述
在我的安装过程结束时的设置场景中,每个客户端都从服务器下载应用程序密钥。该文件由约 64 个随机字节组成,二进制,非编码。它应该存储在安装目录的配置文件中。
CurStepChanged
设置由 Inno Setup 处理,它在事件期间调用密钥生成过程。创建OLE WinHttp.WinHttpRequest.5.1
,发送包含客户端数据的 POST 请求,并应接收二进制响应。使用 提取响应WinHttpReq.ResponseText
并将其存储到文件中SaveStringToFile
。
但是,生成的文件与从服务器发送的文件不同。例如在服务器端记录的数据:
5a7868256a890e25735f431351f023c143f0cc397e6ec01e8a81806564eaa9f4fc8a005d9035c18fa32f95daaeff34955f3f6e4bfc5051bd33a522cc2aaddac8f29a1031dcb23728250c4f0a73db6a5bcc64e1ddef71a6
被接收为
5a7868256a3f0e25735f4313513f23c1433f49397e6e411e3f813f656465a9f4fc3f005d9035c13f4c2f3fdaae79343f5f3f6e4bfc505131335922492aadda456f3f1031dc323728250c4f0a73556a5b4964e1dd6971a6
(例如第 6 个字节不同)。没有这样的问题是数据不包含非ASCII数据。
我的第一个想法是,在某些时候将二进制数据编码/解码为文本会修改一些字节。我想用IWinHttpRequest::ResponseBody
二进制版本而不是文本版本来访问数据。传递此属性会导致目标文件填充?
字符而不是数据。仅保留 ascii 字符。
我也尝试转换ResponseBody
为 pascal 字节数组,但收到Type Mismatch
错误。VarType
forResponseBody
返回 dec 8209,它映射到and array
,byte
但分配ResponseBody
到array of byte
会导致上述错误。
在 Inno Setup 中将二进制 HTTP 结果存储到文件的正确方法是什么?
解决方案
你没有向我们展示你的代码,所以很难说你可能有什么问题。
虽然我猜你已经直接通过WinHttpReq.ResponseText
(wide string
) 到SaveStringToFile
(which takes AnsiString
)。这涉及到隐式 UTF-16 到 ANSI 编码的转换,这会导致某些字符的丢失或转换。
这工作得很好,在Inno Setup 的Unicode版本(Inno Setup 6 的唯一版本):
var
WinHttpReq: Variant;
S: string;
I: Integer;
Data: AnsiString;
begin
WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
WinHttpReq.Open('GET', 'https://www.example.com/key.dat', False);
WinHttpReq.Send('');
if WinHttpReq.Status <> 200 then
begin
Log('HTTP Error: ' + IntToStr(WinHttpReq.Status) + ' ' + WinHttpReq.StatusText);
end
else
begin
S := WinHttpReq.ResponseText;
SetLength(Data, Length(S));
for I := 1 to Length(S) do
begin
Data[I] := S[I];
end;
SaveStringToFile(ExpandConstant('{app}\key.dat'), Data, False);
end;
end;
该代码对于下载大型二进制文件可能效率低下。但是对于 64 字节来说就可以了。对于较大的文件,可能可以使用ADODB.Stream
class。
推荐阅读
- outlook - 获取在共享辅助日历上创建事件的用户的名称
- ruby-on-rails - 我不知道如何在 windows8.1 上的 ruby 上安装 postgresql10.7
- json - 使用 Postgres 触发器仅记录修改字段的 JSON
- android - Firebase 身份验证 - 没有来自谷歌登录提供商的电子邮件
- javascript - 如何从firebase的嵌套文档中删除数组项?
- javascript - getInitialProps 在 Next.js 中导入数据
- numpy - 带有偏移量Python的块对角矩阵
- r - tstr 在一轮中拆分到不同的列
- svg - 如何填充这个 SVG?
- google-cloud-datastore - Google Datalab:我可以查询 Google Cloud Datastore 以获取模型的训练数据吗?