"Type mismatch" Inno 安装程序 Unicode 版本的 Pascal 脚本中"set of char"错误



我有一个用于Inno Setup的Pascal脚本,但最近我们遇到了Unicode字符的问题。在将Inno设置更改为Unicode版本后,我们在现有脚本中出现了错误。这个错误太笼统了——对于某一行来说,"类型不匹配"。由于我们的主脚本是由包含的许多其他脚本组成的,我不确定这一行是否正确,它指向下面的这个函数,并与Set of Char对齐。在查看了Inno-Setup文档后,我发现Unicode版本在某些方面更加严格,而且在ANSI字符串处理方面也有一些变化(可能还有Char)。

function IsValidName(Name: String):String;
var
  Valid_Ch: Set of Char;
  Location: Integer;
begin
    Valid_Ch := ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-'];
    Result := '';
    for Location := 1 to Length(Name) do
    begin
        if Name[Location] in Valid_Ch then
        begin
            Result := Result + Name[Location];
        end
        else
        begin
            Result := Result + '_';
        end;
    end;    
end;

这一切对我来说都很好,但这是我第一次接触帕斯卡。如果有更有经验的人能在这方面帮助我,我将不胜感激。谢谢

在Pascal(Script)中,set只能包含256(2^8)个值。在Unicode Inno设置中,Char是2字节,因此它可以包含超过256个不同的值。因此,您不能再将其与set一起使用。

您有以下选项:

  • 在您的情况下,由于集合实际上是常量,因此可以在if表达式中使用常量集合。有趣的是,这甚至在Unicode版本中也有效(可能内置了一些允许此异常的破解)。

    function IsValidName(Name: string): string;
    var
      Location: Integer;
    begin
      Result := Name;
      for Location := 1 to Length(Name) do
      begin
        if not (Name[Location] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-']) then
        begin
          Result[Location] := '_';
        end;
      end;    
    end;
    

如果你需要设置为可变的(不是你的情况):

  • 使用Byte并在CharByte之间强制转换,并用Ord() > 255显式替换所有字符
  • 或者使用string而不是set。有关示例,请参见下文。

    function IsValidName(Name: string): string;
    var
      Valid_Ch: string;
      Location: Integer;
    begin
      Valid_Ch := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_-';
      Result := Name;
      for Location := 1 to Length(Result) do
      begin
        if Pos(Result[Location], Valid_Ch) = 0 then
        begin
          Result[Location] := '_';
        end;
      end;    
    end;
    

还要注意,一个字符接一个字符地附加字符串可能效率很低。将字符替换到位(如上面两个示例所示)。

对于一组字符,最好使用类型化的TSysCharSet或类似StrToCharSet的转换器来避免类型不匹配,例如在maXbox4:中

  function IsValidName2(Name: string): string;
  var Location: Integer;
  begin
    Result:= Name;
    for Location := 1 to Length(Name) do begin
    if not (Name[Location] in StrToCharSet(lowercase(LETTERSET)+
                            LETTERSET+DIGISET+ '_'+'-')) then begin
      Result[Location] := '_';
    end;
  end;    
 end;

相关内容

最新更新