我正在尝试从我的“Inno Setup”脚本构建一个用于调查 MSI 文件属性的函数。 (我特别追求“版本”。)
我正在使用这个 powershell 脚本作为参考:https://technotes.khitrenovich.com/check-msi-version-powershell/
我不能让它在 Inno Setup 中工作。所以,我已经切换到 Delphi。 (更好的工具等)并且 Delphi 代码输出与 Inno Setup 完全相同的错误。 (所以,就是这样。)
我做了这个测试功能:
procedure Test( MsiFileName : String ) ;
var
installer : Variant;
database : Variant;
sql : String;
view : Variant;
rec : Variant;
dummy1 : Boolean;
dummy2 : Integer;
dummy3 : array of String;
begin
MsiFileName := 'C:\Users\....\My.msi'; //Test
CoInitialize(nil);
installer := CreateOleObject('WindowsInstaller.Installer');
database := installer.OpenDatabase( MsiFileName, 0 );
sql := 'SELECT Value FROM Property WHERE Property = ''ProductVersion''';
view := database.OpenView(sql);
view.Execute();
rec := view.Fetch();
dummy1 := rec.IsNull; //Fail!
dummy2 := rec.DataSize; //Fail!
dummy3 := rec.StringData; //Fail!
end;
我已经用 msi 文件和 powershell 脚本做了几次测试。 powershell 脚本有效,msi 文件有效。 (可以对其进行调查。)但无论我做什么,我都无法使其在 Inno Setup 和/或 Delphi 中运行。 当代码到达“记录属性”时,它会失败并出现“类型不匹配”异常。我已经尝试了几乎所有可能的“类型”。虽然我不是 Delphi 程序员。我的猜测是,返回的“记录”在某种程度上不是记录......? 记录/获取的文档可以在这里找到:https://learn.microsoft.com/en-us/windows/win32/msi/view-fetch
同样,代码在 Powershell 中运行良好。而且我还看到了 VBScripts 的这种工作方式。 有人知道我错过了什么吗?
他们需要使用
InvokeMember
hack imo 的事实表明 API 中有些东西已经烂掉了。
如果 PowerShell 适合您,您可以调用 PowerShell 为您获取数据。
事实上,我在回答中这样做了:
如何在 Inno Setup 中获取 msi 文件的文件版本
那是用于编译时查询。对于运行时查询,它应该更容易。