与Ansi版本相比,Inno Setup Unicode版本有任何缺点吗?
或者两个版本并行提供的原因是什么,而且不仅仅是Unicode版本了?
在使用Ansi版本开发的现有Inno Setup项目使用Unicode版本时是否存在任何潜在问题?
答案 0 :(得分:7)
没有真正的缺点。主要有优点。显然,Unicode版本不仅限于传统的Ansi字符集。 详见下文。
如果您要开始新的Inno Setup项目,请始终使用Unicode版本。没有理由将Ansi版本用于新项目。
原因,为什么Ansi版本的Inno Setup仍然可用,是Ansi和Unicode版本的Pascal脚本代码不是100%兼容的。它们大部分都是,但存在差异。
因此,如果您现有的安装程序脚本没有任何Pascal Script code(.iss
中没有[Code]
section),您可以(并且应该)升级到Unicode版本马上。
如果你有一些Pascal脚本代码,你应该更加小心。 详见下文。
例如Ansi版本的问题,如果你在英文系统上运行使用Ansi版本的Inno Setup构建的仅限日语的安装程序,你将获得:
另见Inno Setup installator has wrong text encoding。
出于同样的原因,Ansi版本将无法创建名称包含字符的文件,这些文件在目标计算机的旧版Ansi字符集中不存在。
Unicode版本没有这些问题,如Unicode Inno Setup article:
中所述Unicode Inno Setup的主要功能是能够在任何系统上显示任何语言,无论系统代码页如何,以及它使用Unicode文件名的能力。人们可以将Unicode Inno Setup视为新的标准Inno Setup和Non Unicode Inno Setup,作为一种旧的特殊Inno设置,适合那些想要尽可能小尺寸的用户。
同样对于Inno Setup 6,根本没有Ansi版本,所以如果你想使用最新版本的Inno Setup和its new features,你需要切换到Unicode版本。
此外,Unicode版Pascal脚本还有一些小的改进。它们记录在Unicode Inno Setup article中。最重要的是,几乎没有未记录的改进:
Inc
/ Dec
函数/语句。见Inc function Inno Setup。Variant
支持。例如,请参阅Inno Setup: Iterate through array of type Variant (from OleObject)或Is there a way to read the system's information in Inno Setup。case
陈述中的范围:"colon (':') expected" compiler error on character range in case statement in Inno Setup Pascal script。in
运算符:似乎在Ansi版本中,除非存储{{1},否则总是会出现"类型不匹配" 错误首先转换为set
变量
请注意,尽管Unicode版本确实支持具有常量集的set of
运算符,但它不支持集合表达式中的范围,因此in
是可能的,但X in [1, 2, 3]
是不可能的,你会得到"结束方括号(']')预期。" X in [1..3]
在Unicode版本中具有透明背景。请参阅Inno Setup - Transparency under text in page name and description labels Pascal脚本代码中可能出现问题的区域很少:
对DLL函数的任何调用都采用字符串参数 - TLabel
和string
类型。 PChar
应该没问题,因为它在Unicode版本中是相同的。
在Unicode版本中,AnsiString
已重命名为PChar
。
如果您调用任何使用字符串的Windows API函数,则应切换到其Wide版本。例如。使用PAnsiChar
代替GetFileAttributesW
。没有GetFileAttributesA
类型。因此,如果您的声明在Ansi版本中使用PWideChar
类型,并且您切换到该函数的宽版本,则必须使用PChar
类型。 Inno Setup会自动将其封送到string
(或类似的),即LPCTSTR
。
下面的声明在Ansi版本中是正确的,但在Unicode版本中是错误的,因为PWideChar
需要GetFileAttributesA
,但PAnsiChar
编组为string
的Unicode版本
PWideChar
有关完整示例和解决方案,请参阅Inno Setup FileExists unable to find existing file。
在极少数情况下,您正在调用具有function GetFileAttributes(lpFileName: string): DWORD;
external 'GetFileAttributesA@kernel32.dll stdcall';
参数PWideChar
}的函数,使用它时非常棘手,没有实际的var S: PWideChar
类型,因为在这种情况下,您不能使用PWideChar
编组。但它可行,请参阅Constant for AppData\LocalLow?
与Windows API类似,某些第三方库也在其API中提供带有Unicode字符串的单独Unicode版本。例如,ISSkin有string
。请参阅Getting ISSkin to work with latest Inno Setup 5.5.9 Unicode。
使用ISSkinU.dll
类型作为字节数组的任何代码(如在Unicode版本中,string
是宽字符(2字节)数组)。只有当您的代码使用string
类方法时,这才是最关心的问题:
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);
重新声明。对我来说看起来像个错误。
要使这些方法在Unicode版本中可用,请使用许多现有答案中使用的@ AnsiString
函数,例如:
Unicode版本不允许BufferToAnsi
变量(因为多字节类型不允许set of char
)。虽然有趣的是它支持表达式中的set
常量。见"Type mismatch" error on "set of char" in Pascal Script of the Inno Setup Unicode version。
FloatToStr
在Ansi版本中使用特定于语言环境的小数点分隔符,而在Unicode版本中始终使用点。
Unicode版本对分号的使用更为严格。 Ansi版本容忍一些丢失的分号,因此它甚至可以编译在这方面不是100%语法正确的代码。
如果你的代码没有使用上述任何一个,并且你的分号是正确的,那么你就不应该对Unicode版本有任何问题。
答案 1 :(得分:0)
在明确答案之后,没有真正的理由继续使用Ansi Inno安装版本,我们昨天将我们产品的测试版设置转换为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事件日志中的。我要求beta测试人员使用“/ LOG”参数运行设置,并且根本没有显示错误。只是完整的设置崩溃。
为了确保从Ansi到Unicode的更改导致了这个问题,我们向beta测试人员发送了另一个相同的版本,只是使用Ansi版本编译而没有崩溃。
因此,Unicode版本似乎有更多(负面)副作用。
我们无法自己重现此问题,只是我们的一位测试人员使用此设置: https://www.fs-flightcontrol.com/download/FS-FlightControl-Beta-InnoUnicode.exe 只需检查防火墙例外,它就会在安装过程结束时崩溃。
根据测试人员发送的安装日志文件,他有Windows版本10.0.14393。正如我写的那样,在日志中找不到这个问题的痕迹,它只会崩溃。