从Ansi升级到Inno Setup的Unicode版本(任何缺点)

ab-*_*ols 6 inno-setup

与Ansi版本相比,Inno Setup Unicode版本有任何缺点吗?

或者是什么原因仍然是两个版本并行提供,而不仅仅是Unicode版本?

在使用Ansi版本开发的现有Inno Setup项目中使用Unicode版本时是否存在任何潜在问题?

Mar*_*ryl 11

没有真正的缺点.主要有优点.显然,Unicode版本不仅限于传统的Ansi字符集.请参阅下文了解详情.

如果要启动新的Inno Setup项目,请始终使用Unicode版本.没有理由将Ansi版本用于新项目.

原因,为什么Ansi版本的Inno Setup仍然可用,是Ansi和Unicode版本的Pascal脚本代码不是100%兼容的.他们大多是,但有差异.

因此,如果您现有的安装程序脚本没有任何Pascal脚本代码(您的内容中没有任何[Code]部分.iss),您可以(并且应该)立即升级到Unicode版本.

如果你有一些Pascal脚本代码,你应该更加小心.请参阅下文了解详情.

为什么要使用Unicode版本

例如Ansi版本的问题,如果您在英文系统上运行使用Ansi版本的Inno Setup构建的仅限日语的安装程序,您将获得:

英语系统上的日语安斯安装程序

另请参见Inno Setup安装程序具有错误的文本编码.

出于同样的原因,Ansi版本将无法创建名称包含字符的文件,这些文件在目标计算机的旧版Ansi字符集中不存在.

Unicode版本没有这些问题,如Unicode Inno Setup文章中所述:

Unicode Inno Setup的主要功能是能够在任何系统上显示任何语言,无论系统代码页如何,以及它使用Unicode文件名的能力.人们可以将Unicode Inno Setup视为新的标准Inno Setup和Non Unicode Inno Setup,作为一种旧的特殊Inno设置,适合那些想要尽可能小尺寸的人.

此外,Unicode版Pascal脚本还有一些小的改进.它们记录在Unicode Inno Setup文章中.最重要的是,几乎没有未记录的改进:

Pascal脚本代码中可能存在的问题

Pascal脚本代码中可能出现问题的区域很少:

  • 对DLL函数的任何调用都采用字符串参数 - stringPChar类型. AnsiString应该没问题,因为它在Unicode版本中是相同的.

    在Unicode版本中,PChar已重命名为PAnsiChar.

    如果您调用任何使用字符串的Windows API函数,则应切换到其Wide版本.例如使用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';
    
    Run Code Online (Sandbox Code Playgroud)

    有关完整示例和解决方案,请参阅Inno Setup FileExists无法找到现有文件.

    在极少数情况下,您正在调用具有out PWideChar参数(var S: PWideChar)的函数,使用它时非常棘手,没有实际PWideChar类型,因为在这种情况下您不能使用string编组.但它是可行的,请参阅AppData\LocalLow的常量?

    与Windows API类似,某些第三方库也在其API中提供带有Unicode字符串的单独Unicode版本.例如ISSkinISSkinU.dll.请参阅让ISSkin使用最新的Inno Setup 5.5.9 Unicode.

  • 任何使用stringtype作为字节数组的代码(如在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);
    
    Run Code Online (Sandbox Code Playgroud)

    应该真正重新声明这些方法AnsiString.对我来说看起来像个错误.

    要使这些方法在Unicode版本中可用,请使用BufferToAnsi许多现有答案中使用的@TLama函数,例如:

  • Unicode版本不允许set of char变量(因为set多字节类型不允许).虽然有趣的是它支持set of char表达式中的常量.请参阅Inno Setup Unicode版本的Pascal脚本中的"set of char"中的"类型不匹配"错误.

  • FloatToStr 在Ansi版本中使用特定于语言环境的小数点分隔符,而在Unicode版本中始终使用点.

  • Unicode版本对分号的使用更为严格.Ansi版本容忍一些丢失的分号,因此它甚至可以编译在这方面不是100%语法正确的代码.

如果您的代码不使用上述任何一项,并且您的分号正确,则不应该对Unicode版本有任何问题.


归档时间:

查看次数:

1681 次

最近记录:

6 年,7 月 前