我想通过在特定文件夹中的DLL(.NET和COM DLL)的我的Inno Setup的循环和注册每个DLL。 有没有一种方法来识别每个DLL类型(.NET / COM),并取决于DLL的类型使用regasm / regsvr。
我有通过在文件夹中的DLL .NET循环一个码,并注册每一个。 该代码可以找到这里 。 在这种情况下,所有的DLL .NET类型。 如何实现与存在于同一文件夹中的DLL都相同。
我想通过在特定文件夹中的DLL(.NET和COM DLL)的我的Inno Setup的循环和注册每个DLL。 有没有一种方法来识别每个DLL类型(.NET / COM),并取决于DLL的类型使用regasm / regsvr。
我有通过在文件夹中的DLL .NET循环一个码,并注册每一个。 该代码可以找到这里 。 在这种情况下,所有的DLL .NET类型。 如何实现与存在于同一文件夹中的DLL都相同。
下面的函数(S)(最初基于来自同名方法this article
)可以帮助你确定是否由指定的文件FileName
参数是一个.NET程序集或不。 正如它的名字宣布,它应该如果该文件是一个.NET组件,假如果不返回True。 这个功能应该工作的32位以及64位库。
请注意,这个代码在其修改就可以只使用Unicode Inno Setup的。 它不打算与创新安装的ANSI版本中使用。 对于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;
要在创新安装的ANSI版本使用上面的代码替换这些上面的辅助功能。 要做到这一点,因为在Inno Setup的流只能使用字符串作为缓冲,只是串具有在创新安装的Unicode和ANSI版本每个字符的字节大小不同是很重要的:
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);