2

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

但我不断收到错误

运行时错误(在 6:366) - 地址 0042FD23 的访问冲突。读取地址 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)

提前感谢您的重要帮助。

4

2 回答 2

2

我认为您不能调用从 Inno Setup Pascal 脚本返回指向字符串(字符缓冲区)的指针的函数。

但是你可以像这样破解它:

  • 将函数声明为返回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;

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

于 2016-08-28T15:21:34.803 回答
1

您可以使用MediaInfo Command Line InterfaceInno 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;

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

于 2016-08-23T01:43:55.203 回答