Двоичные данные, возвращаемые из IWinHttpRequest, изменены, не удалось преобразовать Variant в массив байтов - PullRequest
0 голосов
/ 10 октября 2018

В моем сценарии установки в конце процесса установки каждый клиент загружает ключ приложения с сервера.Файл состоит из ~ 64 случайных байтов, двоичных, не закодированных.Он должен храниться в файле конфигурации в каталоге установки.

Настройка выполняется с помощью Inno Setup, которая вызывает процедуру генерации ключа во время события CurStepChanged.OLE WinHttp.WinHttpRequest.5.1 создан, отправлен запрос POST, содержащий данные клиента, и должен быть получен двоичный ответ.Ответ извлекается с помощью WinHttpReq.ResponseText и сохраняется в файл с использованием SaveStringToFile.

Однако полученный файл отличается от того, который был отправлен с сервера.Например, данные, зарегистрированные на стороне сервера:

5a7868256a890e25735f431351f023c143f0cc397e6ec01e8a81806564eaa9f4fc8a005d9035c18fa32f95daaeff34955f3f6e4bfc5051bd33a522cc2aaddac8f29a1031dcb23728250c4f0a73db6a5bcc64e1ddef71a6

принимаются как

5a7868256a3f0e25735f4313513f23c1433f49397e6e411e3f813f656465a9f4fc3f005d9035c13f4c2f3fdaae79343f5f3f6e4bfc505131335922492aadda456f3f1031dc323728250c4f0a73556a5b4964e1dd6971a6

(например, 6-й байт отличается),Нет таких проблем, если данные не содержат не-ascii данных.

Моя первая идея состояла в том, что в какой-то момент кодирование / декодирование двоичных данных в текст изменяет некоторые байты.Я хотел использовать IWinHttpRequest::ResponseBody для доступа к данным в двоичной версии вместо текстовой версии.Передача этого свойства приводит к заполнению целевого файла ? символами вместо данных.Были сохранены только символы ascii.

Я также пытался преобразовать ResponseBody в паскаль байтов, но получил ошибку Type Mismatch.VarType для ResponseBody возвращает декабрь 8209, который отображается на array и byte, но присвоение ResponseBody на array of byte приводит к указанной выше ошибке.

Какой правильный путь ксохранить двоичный результат HTTP в файл в Inno Setup?

1 Ответ

0 голосов
/ 10 октября 2018

Вы не показывали нам свой код, поэтому трудно сказать, какая у вас проблема.

Хотя я предполагаю, что вы передали WinHttpReq.ResponseText (широкий string) напрямую SaveStringToFile(что занимает AnsiString).Это подразумевает неявное преобразование кодировки UTF-16 в ANSI, что приводит к потере или преобразованию некоторых символов.

Это прекрасно работает в Unicode версии Inno Setup:

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 .

...