这是我的当前实现(在FF 5和FF 6中可以工作,可能在以后的所有版本中都可以)
type
TCIDEntry = record
CID: PGUID;
Service: BOOL;
GetFactoryProc: Pointer;
ConstructorProc: Pointer;
end;
TContract = record
ContractID: PChar;
CID: PGUID;
end;
TCategory = record
Category: PChar;
Entry: PChar;
Value: PChar;
end;
TModule = record
Version: UINT;
CIDs: Pointer;
Contracts: Pointer;
Categories: Pointer;
GetFactory: Pointer;
Load: Pointer;
Unload: Pointer;
end;
PModule = ^TModule;
var
NSModule: PModule;
implementation
var
mtModule: TModule;
CIDs: array[0..1] of TCIDEntry;
Contracts: array[0..1] of TContract;
function GetFileVersionResourceInfo(const FileName, VerValue: string): string;
var
S: string;
Value: Pointer;
ValueSize: DWORD;
VerInfoSize: DWORD;
VersionInfo: Pointer;
GetInfoSizeJunk: DWORD;
begin
VerInfoSize := GetFileVersionInfoSize(PChar(FileName), GetInfoSizeJunk);
if VerInfoSize > 0 then
begin
GetMem(VersionInfo, VerInfoSize);
try
if GetFileVersionInfo(PChar(FileName), 0, VerInfoSize, VersionInfo) then
if VerQueryValue(VersionInfo, '\\VarFileInfo\\Translation', Value, ValueSize) then
begin
S := '\\StringFileInfo\\' +
IntToHex(LoWord(LongInt(Value^)), 4) +
IntToHex(HiWord(LongInt(Value^)), 4) + '\\';
if VerQueryValue(VersionInfo, PChar(S + VerValue), Value, ValueSize) then Result := PChar(Value);
end;
finally
FreeMem(VersionInfo, VerInfoSize);
end;
end;
end;
function GetVersion: Integer;
var
I: Integer;
sProductVersion: string;
sModuleFileName: array[0..MAX_PATH] of Char;
begin
Result := 1;
FillChar(sModuleFileName, MAX_PATH, 0);
if GetModuleFileName(0, sModuleFileName, SizeOf(sModuleFileName)) > 0 then
begin
sProductVersion := Trim(GetFileVersionResourceInfo(sModuleFileName, 'ProductVersion'));
if (sProductVersion <> '') and (sProductVersion[1] in ['4'..'9']) then
begin
I := StrToInt(sProductVersion[1]);
if I <= 5 then
Result := I - 3
else
Result := I;
end;
end;
end;
function MyConstructor(aOuter: nsISupports; const aIID: TGUID; out aResult): nsresult; cdecl;
begin
end;
initialization
mtModule.Version := GetVersion;
CIDs[0].CID := @Sample_CID;
CIDs[0].ConstructorProc := @MyConstructor;
mtModule.CIDs := @CIDs;
Contracts[0].ContractID := Sample_CONTRACTID;
Contracts[0].CID := @Sample_CID;
mtModule.Contracts := @Contracts;
NSModule := @mtModule;
end.