在 Inno Setup Pascal Script 中使用 MediaInfo 库获取图像文件信息
Posted
技术标签:
【中文标题】在 Inno Setup Pascal Script 中使用 MediaInfo 库获取图像文件信息【英文标题】:Get Image File Information using MediaInfo library in Inno Setup Pascal Script 【发布时间】:2016-12-28 02:11:44 【问题描述】:两天多来,我一直在尝试在我的 Pascal 脚本中使用 MediaInfo.DLL
获取 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)
提前感谢您的重要帮助。
【问题讨论】:
您从哪里获得MediaInfo.DLL
的那些DLL 调用?它们是从Delphi自带的Example中获得的吗?
是的@GTAVLover ......我觉得他们很好......你的推荐也很好......我想要的是通过LoadStringFromFile
获取 CMD 输出。 :-)
【参考方案1】:
您可以将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;
现在,以管理员身份使用 Run (Windows Key + R) 命令导航到 Inno Setup 临时目录,并查看您的媒体信息日志文件是否存在,其中包含您在命令中提供的文件的信息。
【讨论】:
【参考方案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 的唯一版本)。
【讨论】:
好像有点难,怎么声明StrCpyN
?
抱歉,我忘记了StrCpyN
声明。现已添加。
这很好用,但我不确定它是否适用于所有 Windows 版本..... :-(
为什么您认为这不适用于所有版本的 Windows?
StrCpyN
是否存在于包括 W. XP 和 98 在内的所有 ShlwAPI.DLL 版本中?以上是关于在 Inno Setup Pascal Script 中使用 MediaInfo 库获取图像文件信息的主要内容,如果未能解决你的问题,请参考以下文章