2

I have been trying for more than two days to get JPEG Image and MP4 Video File Information using MediaInfo.DLL in my Pascal Script.

But I keep getting error

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

The error mostly points to (at 6:366).

I can't think what problem is causing this exception when trying to get Media Information using MediaInfo.DLL.

The code I added to my Script:

[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;

The line which the exception is generating is:

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

I expected that the compiler output will be Width of the JPEG Image: 1920.

I use latest version of Unicode Inno Setup Compiler (5.5.9 - U)

Thanks in advance for your important help.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Blueeyes789
  • 543
  • 6
  • 18
  • Where did you obtained those DLL Calls for `MediaInfo.DLL`? Are they obtained from the Delphi Example comes with it? – GTAVLover Aug 23 '16 at 01:45
  • Yes @GTAVLover......... I think they're fine.......Your recommendation is also fine.......Just what I want is to get CMD Output via `LoadStringFromFile`. :-) – Blueeyes789 Aug 30 '16 at 15:44

2 Answers2

2

I do not think you can call a function that returns a pointer to a string (character buffer) from Inno Setup Pascal Script.

But you can hack it like this:

  • Declare the function as if it returns Cardinal;
  • Use some available function that takes a pointer and copies it to another pointer. Declare the source pointer as Cardinal and the target pointer as string. One such function is the 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;

The code requires Unicode Inno Setup (the only version as of Inno Setpu 6).

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • It seems bit hard, how can I declare `StrCpyN` ? – Blueeyes789 Aug 30 '16 at 08:17
  • Sorry, I've forgot the `StrCpyN` declaration. Added now. – Martin Prikryl Aug 30 '16 at 11:53
  • This works well, but I can't sure will it work well in all Windows versions..... :-( – GTAVLover Aug 30 '16 at 15:05
  • Why do you think this won't work on all versions of Windows? – Martin Prikryl Aug 30 '16 at 15:09
  • Is `StrCpyN` exist in all Versions of ShlwAPI.DLL including W. XP and 98? – GTAVLover Aug 30 '16 at 15:34
  • @MartinPrikryl thx for giving this hacking method, but I don't see any performance difference between getting those info using MediaInfo Library and retrieving them (like -GTAVLover said), using Command Line and getting CMD Output via `LoadStringFromFile.` That's Why? – Blueeyes789 Aug 30 '16 at 15:38
  • The `StrCpyN` is definitely available on Windows XP too. Not sure about 98. Do you even expect the Media Info to run on 98? – Martin Prikryl Aug 30 '16 at 15:43
  • To me a hack is calling an external exe to retrieve media file information. Anyway, I was just answering your question (why the `MediaInfo_Get` is crashing). Chose the solution you like. – Martin Prikryl Aug 30 '16 at 15:44
  • Yes....... Is the crashing of the function `MediaInfo_Get` caused the shown exception ? – Blueeyes789 Aug 30 '16 at 15:47
  • @MartinPrikryl I just asked..........It is good to hear `StrCpyN` exists in XP too.........Thank you for the given Important Information about `StrCpyN` Function.......... ;-) – GTAVLover Aug 30 '16 at 15:49
  • No the exception is caused by Inno Setup Pascal Script not being able to handle the `PChar` returned by the function. Not by the function itself. – Martin Prikryl Aug 30 '16 at 15:50
  • I finally like to know will this work on both Unicode and Ansi Inno Setup Compiler. – Blueeyes789 Aug 30 '16 at 22:35
  • As is, the code works on Unicode version only. While the code can be made running on Ansi version, you should not use the Ansi version nowadays anymore. – Martin Prikryl Aug 31 '16 at 06:05
1

You can use the MediaInfo Command Line Interface with Inno Setup Ansi or Unicode Version.

Usage Example:

[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;

Now, navigate to the Inno Setup Temporary Directory as Administrator using Run (Windows Key + R) Command and see your Media Information Log File exists there which contains the Information about the File you given in the Command.

GTAVLover
  • 1,407
  • 3
  • 22
  • 41