Обновление 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". Кроме того, есть несколько недокументированных улучшений:
Inc
/Dec
функции / заявление. Смотри функцию Inc Inno Setup.- Лучше
Variant
служба поддержки. Например, см. Inno Setup: итерируйте по массиву типа Variant (из OleObject) или есть способ прочитать информацию о системе в Inno Setup. - Лучшая поддержка высокого разрешения (и нестандартного экрана в целом). Например, см. Значок панели задач Inno Setup размытым или установщик Inno Setup сжал окно в XP?
- Диапазон в
case
оператор: "двоеточие (':') ожидаемое" ошибка компилятора в диапазоне символов в операторе case в сценарии Inno Setup Pascal. in
оператор с постоянным набором: кажется, что в версии Ansi вы всегда получаете ошибку "Несоответствие типов", если вы не сохранитеset
вset of
переменная первая.
Обратите внимание, что хотя версия Unicode и поддерживаетin
оператор с постоянным набором, он не поддерживает диапазоны в выражении набора, поэтомуX in [1, 2, 3]
возможно, ноX in [1..3]
невозможно, вы получите "Закрывающую квадратную скобку (']') ожидаемо".TLabel
имеет прозрачный фон в версии Unicode. См. Inno Setup - Прозрачность под текстом в названии страницы и метках описания.
Возможные проблемы в коде 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. Поскольку я написал, никаких следов этой проблемы не может быть найдено в журнале, он просто вылетает.