I want my inno setup to loop through dlls (both .net and com dlls) in particular folder and register each dll. Is there a way to identify each dll type (.net/com) and use regasm/regsvr depending on the type of the dll.
I have a code which loops through .net dlls in a folder and register each one. The code can be found here. In this case, all the dlls were .net type. How to achieve the same with both dlls present in the same folder.
The following function(s) (originally based on a same named method from this article
) might help you to determine if a file specified by the FileName
parameter is a .NET assembly or not. As its name proclaims, it should return True if the file is a .NET assembly, False if not. This function should work for 32-bit as well as for 64-bit libraries.
Please note that this code in its modification will work only in Unicode Inno Setup. It's not intended to be used with ANSI versions of Inno Setup. For ANSI versions use the helper functions posted below:
[Code]
function BufferToWord(const Buffer: string): Word;
begin
Result := Ord(Buffer[1]);
end;
function BufferToLongWord(const Buffer: string): LongWord;
begin
Result := (Ord(Buffer[2]) shl 16) + Ord(Buffer[1]);
end;
function ReadFromStream(Stream: TStream; Size: Integer): LongWord;
var
Buffer: string;
begin
SetLength(Buffer, Size div 2);
Stream.ReadBuffer(Buffer, Size);
case Size of
2: Result := BufferToWord(Buffer);
4: Result := BufferToLongWord(Buffer);
else
RaiseException('Unexpected byte size to be read.');
end;
end;
function IsDotNetAssembly(const FileName: string): Boolean;
var
FileStream: TFileStream;
PEOffset: LongWord;
MagicNumber: Word;
ComDescriptor: LongWord;
DataDirOffset: LongWord;
begin
// initialize result
Result := False;
// open the file to be read
FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
try
// seek to the PE header start offset and read the value of
FileStream.Position := $3C;
PEOffset := ReadFromStream(FileStream, SizeOf(PEOffset));
// seek to the optional header because of the Magic number,
// which will tell us if the image is 32 or 64-bit; read it
FileStream.Position := PEOffset + $18;
MagicNumber := ReadFromStream(FileStream, SizeOf(MagicNumber));
// according to image bitness we set the offset to the data
// directory
case MagicNumber of
$010B: DataDirOffset := $60; // 32-bit image
$020B: DataDirOffset := $70; // 64-bit image
else
RaiseException('Invalid image format.');
end;
// position to RVA 15 of the data directory array
FileStream.Position := PEOffset + $18 + DataDirOffset + $70;
// read the value of the COM descriptor
ComDescriptor := ReadFromStream(FileStream, SizeOf(ComDescriptor));
// if this value is non zero, the file is a CLR assembly
Result := ComDescriptor <> 0;
finally
FileStream.free;
end;
end;
To use the above code in the ANSI version of Inno Setup replace the above helper functions with these. It is important to do that, because streams in Inno Setup can use only string as a buffer and just strings has different size in bytes per char in Unicode and ANSI version of Inno Setup:
function BufferToWord(const Buffer: AnsiString): Word;
begin
Result := (Ord(Buffer[2]) shl 8) + Ord(Buffer[1]);
end;
function BufferToLongWord(const Buffer: AnsiString): LongWord;
begin
Result := (Ord(Buffer[4]) shl 24) + (Ord(Buffer[3]) shl 16) +
(Ord(Buffer[2]) shl 8) + Ord(Buffer[1]);
end;
function ReadFromStream(Stream: TStream; Size: Integer): LongWord;
var
Buffer: AnsiString;
begin
SetLength(Buffer, Size);
Stream.ReadBuffer(Buffer, Size);
case Size of
2: Result := BufferToWord(Buffer);
4: Result := BufferToLongWord(Buffer);
else
RaiseException('Unexpected byte size to be read.');
end;
end;
The usage of the above function is then straightforward:
if IsDotNetAssembly('C:\Wherever\WhateverBinary.dll') then
MsgBox('The binary file is a .NET assembly!', mbInformation, MB_OK)
else
MsgBox('The binary file is not a .NET assembly!', mbInformation, MB_OK);