Inno Setup GetStringFileInfo无法读取AssemblyTitle的问题咨询
没错,这正是你遇到AppName has invalid value错误的核心原因!
Inno Setup的内置GetStringFileInfo函数确实不支持读取Title这个属性——从ISPP内置函数的实现来看,它只预定义了CompanyName、ProductName、FileVersion等有限的几个文件信息字段,.NET中AssemblyTitle对应的PE文件属性并不在这个支持列表里,所以直接调用该函数读取Title会失败,进而导致AppName赋值报错。
为什么ProductName能正常读取?
因为.NET的AssemblyProduct属性会直接映射到PE文件的ProductName字段,而这个字段刚好是GetStringFileInfo函数支持的,所以你能顺利获取到对应值;但AssemblyTitle对应的PE字段不在函数的预定义范围内,自然无法被识别和读取。
可行的解决办法
有两个实用方案可以解决这个问题:
方案一:改用函数支持的字段
如果业务上不需要严格区分Title和ProductName,可以把AssemblyTitle的内容迁移到AssemblyProduct属性中,然后通过GetStringFileInfo(RootDirectory + "Sample.exe", "ProductName")来读取,这样就能正常给AppName赋值了。方案二:自定义函数读取
Title字段
要是必须读取AssemblyTitle的值,可以自己编写Pascal脚本函数,通过调用Windows API直接读取PE文件的版本资源。大致思路是利用GetFileVersionInfoSize、GetFileVersionInfo和VerQueryValue这几个API来定位并获取Title字段的值,然后在脚本中用这个自定义函数替代内置的GetStringFileInfo。
以下是一个简化版的自定义函数示例,你可以根据实际需求调整:
[Code] function GetFileTitle(const Filename: string): string; var VerInfoSize: DWORD; VerInfo: Pointer; VerValueSize: DWORD; VerValue: PChar; LangCode: array[0..1] of Word; begin Result := ''; VerInfoSize := GetFileVersionInfoSize(PChar(Filename), VerInfoSize); if VerInfoSize = 0 then Exit; GetMem(VerInfo, VerInfoSize); try if not GetFileVersionInfo(PChar(Filename), 0, VerInfoSize, VerInfo) then Exit; if not VerQueryValue(VerInfo, '\VarFileInfo\Translation', Pointer(LangCode), VerValueSize) then Exit; if VerQueryValue(VerInfo, PChar(Format('\StringFileInfo\%.4x%.4x\Title', [LangCode[0], LangCode[1]])), Pointer(VerValue), VerValueSize) then Result := VerValue; finally FreeMem(VerInfo); end; end;
之后在脚本中这样调用即可:
AppName={#GetFileTitle(RootDirectory + "Sample.exe")}
内容的提问来源于stack exchange,提问作者Youngjae

