我希望我的 inno 设置循环遍历特定文件夹中的 dll(.net 和 com dll)并注册每个 dll。有没有办法识别每种 dll 类型(.net/com)并根据 dll 的类型使用 regasm/regsvr。
我有一个代码循环遍历文件夹中的 .net dll 并注册每个。代码可以在这里找到。在这种情况下,所有的 dll 都是 .net 类型的。如何使用同一文件夹中的两个 dll 实现相同的目的。
我希望我的 inno 设置循环遍历特定文件夹中的 dll(.net 和 com dll)并注册每个 dll。有没有办法识别每种 dll 类型(.net/com)并根据 dll 的类型使用 regasm/regsvr。
我有一个代码循环遍历文件夹中的 .net dll 并注册每个。代码可以在这里找到。在这种情况下,所有的 dll 都是 .net 类型的。如何使用同一文件夹中的两个 dll 实现相同的目的。
以下函数(最初基于来自 的同名方法this article
)可能会帮助您确定参数指定的文件FileName
是否为 .NET 程序集。正如它的名字所宣称的,如果文件是一个 .NET 程序集,它应该返回 True,否则返回 False。此函数应适用于 32 位和 64 位库。
请注意,此代码在其修改中仅适用于 Unicode Inno 设置。它不适用于 ANSI 版本的 Inno Setup。对于 ANSI 版本,请使用下面发布的辅助函数:
[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;
要在 Inno Setup 的 ANSI 版本中使用上述代码,请将上述帮助函数替换为这些。这样做很重要,因为 Inno Setup 中的流只能使用字符串作为缓冲区,并且在 Unicode 和 ANSI 版本的 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;
上述函数的用法很简单:
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);