在 Inno Setup Pascal 脚本中使用 MediaInfo 库获取图像文件信息

Get Image File Information using MediaInfo library in Inno Setup Pascal Script

两天多来我一直在尝试在我的 Pascal 脚本中使用 MediaInfo.DLL 获取 JPEG 图像和 MP4 视频文件信息。

但我一直收到错误

Runtime Error (at 6:366) - Access Violation at address 0042FD23. Read of address 8065241E.'

错误主要指向(在 6:366)。

我想不出在尝试使用 MediaInfo.DLL.

获取媒体信息时导致此异常的问题

我添加到脚本中的代码:

[Files]
Source: Lamborghini_Aventador.jpg; DestDir: {tmp}; Flags: dontcopy
Source: MediaInfo.dll; DestDir: {tmp}; Flags: dontcopy

[Code]
#ifdef UNICODE
type
  PWideChar = WideString;
#endif

const
  StreamKind_Image = 5;
  InfoKind_Text = 1;

function MediaInfo_New: Cardinal;
  external 'MediaInfo_New@{tmp}\MediaInfo.dll stdcall delayload';
function MediaInfo_Open(Handle: Cardinal; File__: PWideChar): Boolean;
  external 'MediaInfo_Open@{tmp}\MediaInfo.dll stdcall delayload';
function MediaInfo_Get(Handle: Cardinal; StreamKind: Integer; StreamNumber: Integer; Parameter: PWideChar; KindOfInfo: Integer; KindOfSearch: Integer): PWideChar;
  external 'MediaInfo_Get@{tmp}\MediaInfo.dll stdcall delayload';

procedure RetrieveImageInformation;
var
  IHandle: Cardinal;
  Width: PWideChar;
begin
  ExtractTemporaryFile('Lamborghini_Aventador.jpg');
  ExtractTemporaryFile('MediaInfo.dll');
  IHandle := MediaInfo_New();
  MediaInfo_Open(IHandle, PWideChar(ExpandConstant('{tmp}\Lamborghini_Aventador.jpg')));
  Width := MediaInfo_Get(IHandle, StreamKind_Image, 0, 'Width', InfoKind_Text, 0);
  Log('Width of the JPEG Image: ' + PWideChar(Width) + '.');
end;

生成异常的行是:

Width := MediaInfo_Get(IHandle, StreamKind_Image, 0, 'Width', InfoKind_Text, 0);

我预计编译器输出将是 Width of the JPEG Image: 1920.

我使用最新版本的 Unicode Inno Setup Compiler (5.5.9 - U)

在此先感谢您的重要帮助。

您可以将 MediaInfo Command Line Interface 与 Inno Setup Ansi 或 Unicode 版本一起使用。

用法示例:

[Files]
Source: MediaInfo.exe; DestDir: {tmp}; Flags: Dontcopy

[code]
function InitializeSetup(): Boolean;
var
   ErrorCode: Integer;
begin
   ExtractTemporaryFile('MediaInfo.exe');
   ShellExec('Open', 'MediaInfo.exe', ExpandConstant('"YourFileName.mp4" --LogFile="YourFileName Prperties.log"'), ExpandConstant('{tmp}'), SW_HIDE, ewWaitUntilTerminated, ErrorCode);
   if SysErrorMessage(DLLGetLastError) = SysErrorMessage(0) then
   Result := True;  
end;

现在,使用 运行(Windows 键 + R)命令以管理员身份导航到 Inno Setup 临时目录,然后查看存在的媒体信息日志文件,其中包含有关文件的信息命令中给出。

我认为您不能从 Inno Setup Pascal Script 中调用 returns 指向字符串(字符缓冲区)的指针的函数。

但你可以这样破解它:

  • 像声明函数一样声明函数 returns Cardinal;
  • 使用一些可用的函数获取一个指针并将其复制到另一个指针。将源指针声明为 Cardinal,将目标指针声明为 string。其中一个函数是 StrCpyN.
function MediaInfo_Get(
  Handle: Cardinal; StreamKind: Integer; StreamNumber: Integer;
  Parameter: string; KindOfInfo: Integer; KindOfSearch: Integer): Cardinal;
  external 'MediaInfo_Get@{tmp}\MediaInfo.dll stdcall delayload';

function StrCpyN(S1: string; S2: Cardinal; Max: Cardinal): Cardinal;
  external 'StrCpyNW@shlwapi.dll stdcall';
var
  P: Cardinal;
  S: string;
begin
  P := MediaInfo_Get(IHandle, StreamKind_Image, 0, 'Width', InfoKind_Text, InfoKind_Name);
  S := StringOfChar(' ', 1024);
  StrCpyN(S, P, Length(S) - 1);
  S := Trim(S);
  ...
end;

代码需要 (Inno Setpu 6 的唯一版本)。