Обновление Ansi до версии Inno Setup для Unicode (любые недостатки)

Есть ли какие-либо недостатки у версии Inno Setup Unicode по сравнению с версией Ansi?

Или по какой причине обе версии предлагаются параллельно, а не только Unicode?

Есть ли потенциальные проблемы при использовании версии Unicode для моего существующего проекта Inno Setup, разработанного с версией Ansi?

2 ответа

Решение

Там нет никаких реальных недостатков. Есть в основном преимущества. Очевидно тот факт, что версия Unicode не ограничивается устаревшим набором символов Ansi. Смотрите ниже для деталей.

Если вы начинаете новый проект Inno Setup, всегда используйте версию Unicode. Нет причин использовать версию Ansi для новых проектов.

Причина, по которой версия Inno Setup от Ansi по-прежнему доступна, заключается в том, что код Pascal Script для версий Ansi и Unicode несовместим на 100%. В основном они есть, но есть различия.

Так что, если в вашем существующем установочном скрипте нет кода Pascal Script (нет [Code] раздел в вашем .iss), вы можете (и должны) сразу перейти на версию Unicode.

Если у вас есть некоторый код Pascal Script, вам следует быть более осторожным. Смотрите ниже для деталей.

Почему вы хотите использовать версию Unicode

Например, проблемы с версией Ansi: если вы запустите установщик только на японском языке, созданный с помощью версии Inno Setup для Ansi в английской системе, вы получите:

Японский установщик анси на английской системе

См. Также Установщик Inno Setup имеет неправильную кодировку текста.

По той же причине версия Ansi не сможет создавать файлы с именами, содержащими символы, которых нет в устаревшем наборе символов Ansi целевого компьютера.

Версия Unicode не имеет этих проблем, как описано в статье Установка Unicode Innoode:

Ключевыми особенностями Unicode Inno Setup являются его способность отображать любой язык в любой системе независимо от системной кодовой страницы и способность работать с именами файлов Unicode. Можно рассматривать Unicode Inno Setup как новый стандарт Inno Setup, а не Unicode Inno Setup как старую специальную Inno Setup для тех, кто хочет минимально возможный размер.

Кроме того, в Unicode-версии Pascal Script есть несколько небольших улучшений. Они описаны в статье "Настройка Unicode Inno". Кроме того, есть несколько недокументированных улучшений:

Возможные проблемы в коде Pascal Script

Есть несколько областей, где могут возникнуть проблемы в коде Pascal Script:

  • Любые вызовы функций DLL, которые принимают строковые параметры - string а также PChar типы. AnsiString должно быть в порядке, так же, как и в версии Unicode.

    В версии Unicode, PChar был переименован в PAnsiChar,

    Если вы вызываете какую-либо функцию Windows API, которая использует строки, вам следует переключиться на ее широкую версию. Например использовать GetFileAttributesW, вместо GetFileAttributesA, Нет никаких PWideChar тип. Так что если ваша декларация используется PChar введите версию Ansi, и вы переключитесь на широкую версию функции, вы должны использовать string введите вместо. Inno Setup автоматически направит его в LPCTSTR (или аналогичный), иначе PWideChar,

    Объявление ниже является правильным в версии Ansi, но неверным в версии Unicode, так как GetFileAttributesA принимает PAnsiChar, но string маршалы к PWideChar в версии Unicode.

    function GetFileAttributes(lpFileName: string): DWORD;
      external 'GetFileAttributesA@kernel32.dll stdcall';
    

    Полный пример и решение см. В разделе Inno Setup FileExists, который не может найти существующий файл.

    В редких случаях вы вызываете функцию, которая имеет выход PWideChar параметр (var S: PWideChar), это очень сложно использовать, без фактического PWideChar типа, так как в этом случае вы не можете использовать string сортировочный. Но это выполнимо, видите Constant для AppData\LocalLow?

    Подобно API Windows, некоторые сторонние библиотеки также предоставляют отдельную версию Unicode со строками Unicode в своем API. Например, ISSkin имеет ISSkinU.dll, См. Получение ISSkin для работы с последней версией Inno Setup 5.5.9 Unicode.

  • Любой код, который использует string введите как байтовый массив (как в версии Unicode, string является широким массивом символов (2 байта). Это в основном касается, только если ваш код использует TStream методы класса, такие как:

    function Read(Buffer: String; Count: Longint): Longint;
    function Write(Buffer: String; Count: Longint): Longint;
    procedure ReadBuffer(Buffer: String; Count: Longint);
    procedure WriteBuffer(Buffer: String; Count: Longint);
    

    Эти методы должны были быть повторно объявлены AnsiString, Похоже, ошибка для меня.

    Чтобы использовать эти методы в версии Unicode, используйте BufferToAnsi функция @TLama, которая используется во многих существующих ответах, например:

  • Unicode версия не позволяет set of char переменная (как set не допускается для многобайтовых типов). Хотя интересно это поддерживает set of char константы в выражениях. См. "Несоответствие типов" для "set of char" в Pascal Script версии Inno Setup для Inno Setup.

  • FloatToStrиспользует специфичный для локали десятичный разделитель в версии Ansi, в то время как в версии Unicode всегда точка.

  • Версия Unicode более строга к использованию точек с запятой. Версия Ansi допускает некоторые пропущенные точки с запятой, поэтому она может компилировать даже код, который не является на 100% синтаксически правильным в этом отношении.

Если ваш код не использует ничего из вышеперечисленного и у вас есть правильные точки с запятой, у вас не должно возникнуть проблем с версией Unicode.

После четкого ответа, что у нас нет реальной причины оставаться с версией Ansi Inno Setup, мы вчера переключили бета-настройку нашего продукта на версию Unicode и не увидели никаких проблем в наших собственных тестах.

Но сегодня один из наших бета-тестеров сообщил, что эта версия дает сбой при создании исключения брандмауэра со следующим кодом:

try
  FirewallObject := CreateOleObject('HNetCfg.FwAuthorizedApplication');
  FirewallObject.ProcessImageFileName := 'C:\Program Files (x86)\FS-FlightControl\FS-FlightControl.exe';
  FirewallObject.Name := 'FS-FlightControl';
  FirewallObject.Scope := NET_FW_SCOPE_ALL;
  FirewallObject.IpVersion := NET_FW_IP_VERSION_ANY;
  FirewallObject.Enabled := True;
  FirewallManager := CreateOleObject('HNetCfg.FwMgr');
  FirewallProfile := FirewallManager.LocalPolicy.CurrentProfile;
  FirewallProfile.AuthorizedApplications.Add(FirewallObject);
except
  Log('Error setting firewall exception: ' + GetExceptionMessage);
end;

Если этот код выполняется, установка завершается с

Exception code: 0xc0000005
Error offset: 0x0005584c

в журнале событий Windows. Я попросил бета-тестера запустить установку с параметром "/LOG", и там вообще не было ошибок. Просто полная настройка вылетает.

Чтобы быть уверенным, что это было изменение с Ansi на Unicode, вызвавшее эту проблему, мы отправляем бета-тестеру еще одну идентичную сборку, только что скомпилированную с версией Ansi, и никаких сбоев там нет.

Так что, похоже, есть некоторые (отрицательные) побочные эффекты от версии Unicode.

Мы не могли воспроизвести эту проблему сами, только один из наших бета-тестеров, использующий эту настройку: https://www.fs-flightcontrol.com/download/FS-FlightControl-Beta-InnoUnicode.exe Просто оставьте флажок исключения брандмауэра, и он должен сбой где-то ближе к концу процесса установки.

На основании файла журнала установки тестер отправил ему версию Windows 10.0.14393. Поскольку я написал, никаких следов этой проблемы не может быть найдено в журнале, он просто вылетает.

Другие вопросы по тегам