我用的Delphi2007,现在已经做好一个ActiveX,是要放在网页上的。
希望别人IE在访问页面的时候,根据提示进行下载安装,并自动注册。
好像说是得做成CAB才行,然后CAB里还得有个inf文件
但我找遍Delphi2007,也没看到在哪里能做成CAB,就是能做成OCX。
用cabarc命令是能做成CAB,但是里面却没有inf文件,那是不是就不能实现自动注册啊
希望别人IE在访问页面的时候,根据提示进行下载安装,并自动注册。
好像说是得做成CAB才行,然后CAB里还得有个inf文件
但我找遍Delphi2007,也没看到在哪里能做成CAB,就是能做成OCX。
用cabarc命令是能做成CAB,但是里面却没有inf文件,那是不是就不能实现自动注册啊
http://msdn.microsoft.com/en-us/library/aa376858(VS.85).aspx最好的做法是下载flash的cab包,打开看看人家的inf文件怎么写的.
按照他的写就可以了
AnsiString Templete =
"; \%Title\%\r\n\
; File Name \%DLLName\% File Version= \%DllVersion\%\r\n\
; ProgId= \%ProgId\% ClassId= \%DLLClsid\%\r\n\r\n\
[version]\r\n\
signature=\"$CHICAGO$\"\r\n\
AdvancedINF=2.0\r\n\r\n\
[Add.Code]\r\n\
\%DLLName\%=\%DLLName\%\r\n\r\n\
[\%DLLName\%]\r\n\
file-win32-x86=thiscab\r\n\
RegisterServer=yes\r\n\
clsid=\%DLLClsid\%\r\n\
DestDir=\r\n\
FileVersion=\%DLLVersion\%\r\n\r\n\
[Setup Hooks]\r\n\
AddToRegHook=AddToRegHook\r\n\r\n\
[AddToRegHook]\r\n\
InfSection=DefaultInstall\r\n\r\n\
[DefaultInstall]\r\n\
AddReg=AddToRegistry\r\n\r\n\
[AddToRegistry]\r\n\
HKLM,\"SOFTWARE\\Classes\\CLSID\\\%DLLClsid\%\\Implemented Categories\\{7DD95801-9882-11CF-9FA9-00AA006C42C4}\"\r\n\
HKLM,\"SOFTWARE\\Classes\\CLSID\\\%DLLClsid\%\\Implemented Categories\\{7DD95802-9882-11CF-9FA9-00AA006C42C4}\"";const AnsiString MakeCabDirective =
".OPTION EXPLICIT ; Generate errors\r\n\
.Set CabinetNameTemplate=\%CABFile\%\r\n\
.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory\r\n\
.Set CompressionType=MSZIP;** All files are compressed in cabinet files\r\n\
.Set UniqueFiles=\"OFF\"\r\n\
.Set Cabinet=on\r\n\
.Set DiskDirectory1=\%CABFilePath\%\r\n";//---------------------------------------------------------------------------
AnsiString __fastcall GetCLSID(AnsiString FileName)
{
HRESULT hr;
AnsiString Result="";
CComPtr<ITypeLib> spTypeLib;
USES_CONVERSION;
hr = LoadTypeLib(A2OLE(FileName.c_str()), &spTypeLib);
if (FAILED(hr)) return Result;
UINT n = spTypeLib->GetTypeInfoCount();
CComBSTR bstrName0;
hr = spTypeLib->GetDocumentation(-1,
&bstrName0, 0, 0, 0);
if(FAILED(hr))return Result;
for (UINT i=0; i<n; ++i)
{
CComPtr<ITypeInfo> spTypeInfo; hr = spTypeLib->GetTypeInfo(i, &spTypeInfo);
if (FAILED(hr)) return Result;
CComBSTR bstrName; hr = spTypeInfo->GetDocumentation(-1,
&bstrName, 0, 0, 0);
if (FAILED(hr)) return Result ;
TYPEATTR* pta = 0;
hr = spTypeInfo->GetTypeAttr(&pta);
if (FAILED(hr)) return Result;
CComBSTR bstrGuid(pta->guid);
if (TKIND_COCLASS == pta->typekind )
{
Result=AnsiString(bstrGuid);
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
return Result;
}
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
}
return Result;
}AnsiString __fastcall GetProgID(AnsiString FileName)
{
HRESULT hr;
AnsiString Result="";
CComPtr<ITypeLib> spTypeLib;
USES_CONVERSION;
hr = LoadTypeLib(A2OLE(FileName.c_str()), &spTypeLib);
if (FAILED(hr)) return Result;
UINT n = spTypeLib->GetTypeInfoCount();
CComBSTR bstrName0;
hr = spTypeLib->GetDocumentation(-1,
&bstrName0, 0, 0, 0);
if(FAILED(hr))return Result;
for (UINT i=0; i<n; ++i)
{
CComPtr<ITypeInfo> spTypeInfo; hr = spTypeLib->GetTypeInfo(i, &spTypeInfo);
if (FAILED(hr)) return Result;
CComBSTR bstrName; hr = spTypeInfo->GetDocumentation(-1,
&bstrName, 0, 0, 0);
if (FAILED(hr)) return Result ;
TYPEATTR* pta = 0;
hr = spTypeInfo->GetTypeAttr(&pta);
if (FAILED(hr)) return Result;
CComBSTR bstrGuid(pta->guid);
int iKind = pta->typekind ;
if (iKind == TKIND_COCLASS)
{
Result = AnsiString(bstrName0)+"."+AnsiString(bstrName);
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
return Result;
}
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
}
return Result;
}AnsiString __fastcall GetVersion(char *szFile)
{
DWORD dwHandle;
char m_szVersion[256];
DWORD dwVerSize = GetFileVersionInfoSize((char *)szFile, &dwHandle);
char *pbBuffer = new BYTE[dwVerSize];
VS_FIXEDFILEINFO *lpVSInfo = NULL;
UINT uiVerSize = 0;
if (!pbBuffer)
{
return E_OUTOFMEMORY;
}
if (GetFileVersionInfo((char *)szFile, 0, dwVerSize, pbBuffer))
{
if (VerQueryValue(pbBuffer, "\\", (void **)&lpVSInfo, &uiVerSize))
{
wsprintf(m_szVersion, "%d,%d,%d,%d", (lpVSInfo->dwFileVersionMS >> 16) & 0xFFFF
, lpVSInfo->dwFileVersionMS & 0xFFFF
, (lpVSInfo->dwFileVersionLS >> 16) & 0xFFFF
, lpVSInfo->dwFileVersionLS & 0xFFFF);
}
}
delete [] pbBuffer;
return AnsiString(m_szVersion);
}void __fastcall MakeCab(AnsiString FileName)
{
AnsiString FileVer = GetVersion(FileName.c_str());
AnsiString ClsID = GetCLSID(FileName);
AnsiString DLLName = ExtractFileName(FileName);
AnsiString ProgID = GetProgID(FileName);
AnsiString Title = "Ocx Inf file Maker";
AnsiString InfFileName = ChangeFileExt(FileName,".inf");
AnsiString CabFileName = ChangeFileExt(FileName,".cab");
AnsiString DDFFileName = ChangeFileExt(FileName,".ddf");
AnsiString CABDirective = StringReplace( MakeCabDirective,
"\%CABFile\%",
ExtractFileName(CabFileName),
TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
); CABDirective = StringReplace( CABDirective,
"\%CABFilePath\%",
ExtractFilePath(CabFileName),
TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
)
+ ExtractFileName(FileName)
+ "\r\n" + ExtractFileName(InfFileName); AnsiString InfFile;
InfFile = StringReplace( Templete,"\%Title\%", Title, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%DLLName\%", DLLName, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%DllVersion\%", FileVer, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%ProgId\%", ProgID, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%DLLClsid\%", ClsID, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
TFileStream *f = new TFileStream(InfFileName,fmCreate);
try
{
char *p = InfFile.c_str();
int iLen = InfFile.Length();
while (iLen){
int iWrote = f->Write(p,iLen);
p += iWrote;
iLen -= iWrote;
}
}
__finally
{
f->Free();
} f = new TFileStream(DDFFileName,fmCreate);
try
{
char *p = CABDirective.c_str();
int iLen = CABDirective.Length();
while (iLen){
int iWrote = f->Write(p,iLen);
p += iWrote;
iLen -= iWrote;
}
}
__finally
{
f->Free();
}
STARTUPINFO StartInfo; // name structure
PROCESS_INFORMATION ProcInfo; // name structure
memset(&ProcInfo, 0, sizeof(ProcInfo)); // Set up memory block
memset(&StartInfo, 0 , sizeof(StartInfo)); // Set up memory block
StartInfo.cb = sizeof(StartInfo); // Set structure size
if (!CreateProcess( NULL,
AnsiString("makecab /f \""+DDFFileName+"\"").c_str(),
NULL,
NULL,
NULL,
NULL,
NULL,
ExtractFilePath(FileName).c_str(),
&StartInfo,
&ProcInfo))
return; WaitForSingleObject(ProcInfo.hProcess,INFINITE);
CloseHandle(ProcInfo.hThread);
CloseHandle(ProcInfo.hProcess); HFILE hFile;
FILETIME mCreationTime;
FILETIME mLastAccessTime;
FILETIME mLastWriteTime;
hFile=_lopen(FileName.c_str(),OF_READWRITE);
GetFileTime( (HANDLE *)hFile,
&mCreationTime,
&mLastAccessTime,
&mLastWriteTime
); hFile=_lopen(CabFileName.c_str(),OF_READWRITE);
SetFileTime( (HANDLE *)hFile,
&mCreationTime,
&mLastAccessTime,
&mLastWriteTime
);
_lclose(hFile);}
code]
{
if (dlgOpenOCX->Execute()) {
AnsiString FileName = dlgOpenOCX->FileName;
if (SameText(ExtractFileExt(FileName),".OCX")) {
MakeCab(FileName);
}
}
AnsiString Templete =
"; \%Title\%\r\n\
; File Name \%DLLName\% File Version= \%DllVersion\%\r\n\
; ProgId= \%ProgId\% ClassId= \%DLLClsid\%\r\n\r\n\
[version]\r\n\
signature=\"$CHICAGO$\"\r\n\
AdvancedINF=2.0\r\n\r\n\
[Add.Code]\r\n\
\%DLLName\%=\%DLLName\%\r\n\r\n\
[\%DLLName\%]\r\n\
file-win32-x86=thiscab\r\n\
RegisterServer=yes\r\n\
clsid=\%DLLClsid\%\r\n\
DestDir=\r\n\
FileVersion=\%DLLVersion\%\r\n\r\n\
[Setup Hooks]\r\n\
AddToRegHook=AddToRegHook\r\n\r\n\
[AddToRegHook]\r\n\
InfSection=DefaultInstall\r\n\r\n\
[DefaultInstall]\r\n\
AddReg=AddToRegistry\r\n\r\n\
[AddToRegistry]\r\n\
HKLM,\"SOFTWARE\\Classes\\CLSID\\\%DLLClsid\%\\Implemented Categories\\{7DD95801-9882-11CF-9FA9-00AA006C42C4}\"\r\n\
HKLM,\"SOFTWARE\\Classes\\CLSID\\\%DLLClsid\%\\Implemented Categories\\{7DD95802-9882-11CF-9FA9-00AA006C42C4}\"";const AnsiString MakeCabDirective =
".OPTION EXPLICIT ; Generate errors\r\n\
.Set CabinetNameTemplate=\%CABFile\%\r\n\
.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory\r\n\
.Set CompressionType=MSZIP;** All files are compressed in cabinet files\r\n\
.Set UniqueFiles=\"OFF\"\r\n\
.Set Cabinet=on\r\n\
.Set DiskDirectory1=\%CABFilePath\%\r\n";//---------------------------------------------------------------------------
AnsiString __fastcall GetCLSID(AnsiString FileName)
{
HRESULT hr;
AnsiString Result="";
CComPtr<ITypeLib> spTypeLib;
USES_CONVERSION;
hr = LoadTypeLib(A2OLE(FileName.c_str()), &spTypeLib);
if (FAILED(hr)) return Result;
UINT n = spTypeLib->GetTypeInfoCount();
CComBSTR bstrName0;
hr = spTypeLib->GetDocumentation(-1,
&bstrName0, 0, 0, 0);
if(FAILED(hr))return Result;
for (UINT i=0; i<n; ++i)
{
CComPtr<ITypeInfo> spTypeInfo; hr = spTypeLib->GetTypeInfo(i, &spTypeInfo);
if (FAILED(hr)) return Result;
CComBSTR bstrName; hr = spTypeInfo->GetDocumentation(-1,
&bstrName, 0, 0, 0);
if (FAILED(hr)) return Result ;
TYPEATTR* pta = 0;
hr = spTypeInfo->GetTypeAttr(&pta);
if (FAILED(hr)) return Result;
CComBSTR bstrGuid(pta->guid);
if (TKIND_COCLASS == pta->typekind )
{
Result=AnsiString(bstrGuid);
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
return Result;
}
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
}
return Result;
}AnsiString __fastcall GetProgID(AnsiString FileName)
{
HRESULT hr;
AnsiString Result="";
CComPtr<ITypeLib> spTypeLib;
USES_CONVERSION;
hr = LoadTypeLib(A2OLE(FileName.c_str()), &spTypeLib);
if (FAILED(hr)) return Result;
UINT n = spTypeLib->GetTypeInfoCount();
CComBSTR bstrName0;
hr = spTypeLib->GetDocumentation(-1,
&bstrName0, 0, 0, 0);
if(FAILED(hr))return Result;
for (UINT i=0; i<n; ++i)
{
CComPtr<ITypeInfo> spTypeInfo; hr = spTypeLib->GetTypeInfo(i, &spTypeInfo);
if (FAILED(hr)) return Result;
CComBSTR bstrName; hr = spTypeInfo->GetDocumentation(-1,
&bstrName, 0, 0, 0);
if (FAILED(hr)) return Result ;
TYPEATTR* pta = 0;
hr = spTypeInfo->GetTypeAttr(&pta);
if (FAILED(hr)) return Result;
CComBSTR bstrGuid(pta->guid);
int iKind = pta->typekind ;
if (iKind == TKIND_COCLASS)
{
Result = AnsiString(bstrName0)+"."+AnsiString(bstrName);
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
return Result;
}
spTypeInfo->ReleaseTypeAttr(pta);
pta = 0;
}
return Result;
}AnsiString __fastcall GetVersion(char *szFile)
{
DWORD dwHandle;
char m_szVersion[256];
DWORD dwVerSize = GetFileVersionInfoSize((char *)szFile, &dwHandle);
char *pbBuffer = new BYTE[dwVerSize];
VS_FIXEDFILEINFO *lpVSInfo = NULL;
UINT uiVerSize = 0;
if (!pbBuffer)
{
return E_OUTOFMEMORY;
}
if (GetFileVersionInfo((char *)szFile, 0, dwVerSize, pbBuffer))
{
if (VerQueryValue(pbBuffer, "\\", (void **)&lpVSInfo, &uiVerSize))
{
wsprintf(m_szVersion, "%d,%d,%d,%d", (lpVSInfo->dwFileVersionMS >> 16) & 0xFFFF
, lpVSInfo->dwFileVersionMS & 0xFFFF
, (lpVSInfo->dwFileVersionLS >> 16) & 0xFFFF
, lpVSInfo->dwFileVersionLS & 0xFFFF);
}
}
delete [] pbBuffer;
return AnsiString(m_szVersion);
}void __fastcall MakeCab(AnsiString FileName)
{
AnsiString FileVer = GetVersion(FileName.c_str());
AnsiString ClsID = GetCLSID(FileName);
AnsiString DLLName = ExtractFileName(FileName);
AnsiString ProgID = GetProgID(FileName);
AnsiString Title = "Ocx Inf file Maker";
AnsiString InfFileName = ChangeFileExt(FileName,".inf");
AnsiString CabFileName = ChangeFileExt(FileName,".cab");
AnsiString DDFFileName = ChangeFileExt(FileName,".ddf");
AnsiString CABDirective = StringReplace( MakeCabDirective,
"\%CABFile\%",
ExtractFileName(CabFileName),
TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
); CABDirective = StringReplace( CABDirective,
"\%CABFilePath\%",
ExtractFilePath(CabFileName),
TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
)
+ ExtractFileName(FileName)
+ "\r\n" + ExtractFileName(InfFileName); AnsiString InfFile;
InfFile = StringReplace( Templete,"\%Title\%", Title, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%DLLName\%", DLLName, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%DllVersion\%", FileVer, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%ProgId\%", ProgID, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
InfFile = StringReplace( InfFile,"\%DLLClsid\%", ClsID, TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase);
TFileStream *f = new TFileStream(InfFileName,fmCreate);
try
{
char *p = InfFile.c_str();
int iLen = InfFile.Length();
while (iLen){
int iWrote = f->Write(p,iLen);
p += iWrote;
iLen -= iWrote;
}
}
__finally
{
f->Free();
} f = new TFileStream(DDFFileName,fmCreate);
try
{
char *p = CABDirective.c_str();
int iLen = CABDirective.Length();
while (iLen){
int iWrote = f->Write(p,iLen);
p += iWrote;
iLen -= iWrote;
}
}
__finally
{
f->Free();
}
STARTUPINFO StartInfo; // name structure
PROCESS_INFORMATION ProcInfo; // name structure
memset(&ProcInfo, 0, sizeof(ProcInfo)); // Set up memory block
memset(&StartInfo, 0 , sizeof(StartInfo)); // Set up memory block
StartInfo.cb = sizeof(StartInfo); // Set structure size
if (!CreateProcess( NULL,
AnsiString("makecab /f \""+DDFFileName+"\"").c_str(),
NULL,
NULL,
NULL,
NULL,
NULL,
ExtractFilePath(FileName).c_str(),
&StartInfo,
&ProcInfo))
return; WaitForSingleObject(ProcInfo.hProcess,INFINITE);
CloseHandle(ProcInfo.hThread);
CloseHandle(ProcInfo.hProcess); HFILE hFile;
FILETIME mCreationTime;
FILETIME mLastAccessTime;
FILETIME mLastWriteTime;
hFile=_lopen(FileName.c_str(),OF_READWRITE);
GetFileTime( (HANDLE *)hFile,
&mCreationTime,
&mLastAccessTime,
&mLastWriteTime
); hFile=_lopen(CabFileName.c_str(),OF_READWRITE);
SetFileTime( (HANDLE *)hFile,
&mCreationTime,
&mLastAccessTime,
&mLastWriteTime
);
_lclose(hFile);}
[AddToRegistry]
HKLM,"SOFTWARE\Classes\CLSID\%DLLClsid%\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}"
HKLM,"SOFTWARE\Classes\CLSID\%DLLClsid%\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}"可以参考:
Set the safe for scripting and safe for initialization value in the registry
uses
ActiveX
, SysUtils
, Classes
, Windows;//.inf文件模板
const
Templete =
'; %Title%'#13#10+
'; File Name %DLLName% File Version= %DllVersion%'#13#10+
'; ProgId= %ProgId% ClassId= %DLLClsid%'#13#10#13#10+
'[version]'#13#10+
'signature="$CHICAGO$"'#13#10+
'AdvancedINF=2.0'#13#10#13#10+
'[Add.Code]'#13#10+
'%DLLName%=%DLLName%'#13#10#13#10+
'[%DLLName%]'#13#10+
'file-win32-x86=thiscab'#13#10+
'RegisterServer=yes'#13#10+
'clsid=%DLLClsid%'#13#10+
'DestDir='#13#10+
'FileVersion=%DLLVersion%'#13#10#13#10+
'[Setup Hooks]'#13#10+
'AddToRegHook=AddToRegHook'#13#10#13#10+
'[AddToRegHook]'#13#10+
'InfSection=DefaultInstall'#13#10#13#10+
'[DefaultInstall]'#13#10+
'AddReg=AddToRegistry'#13#10#13#10+
'[AddToRegistry]'#13#10+
'HKLM,"SOFTWARE\Classes\CLSID\%DLLClsid%\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}"'#13#10+
'HKLM,"SOFTWARE\Classes\CLSID\%DLLClsid%\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}"';//MackCab 用的中间文件模板,文件附加在后面,不能带路径(估计可以支持8.3短路径)
MakeCabDirective =
'.OPTION EXPLICIT ; Generate errors'#13#10+
'.Set CabinetNameTemplate=%CABFile%'#13#10+
'.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory'#13#10+
'.Set CompressionType=MSZIP;** All files are compressed in cabinet files'#13#10+
'.Set UniqueFiles="OFF"'#13#10+
'.Set Cabinet=on'#13#10+
'.Set DiskDirectory1=%CABFilePath%'#13#10;//取得CoClass的ClassID
function GetCLSID(FileName: String): WideString;
//取得ProgID
function GetProgID(FileName: String): String;
//制作用于发布的CAB包
procedure MakeCAB(FileName: String);implementation//取得CoClass的ClassID
function GetCLSID(FileName: String): WideString;
var
spTypeLib: ITypeLib;
spTypeInfo: ITypeInfo;
pta: PTypeAttr;
hr: HRESULT;
Count, I: UINT;begin
Result := '{00000000-0000-0000-0000-000000000000}';
hr := LoadTypeLib(PWideChar(WideString(FileName)),spTypeLib);
if Failed(hr) then Exit;
Count := spTypeLib.GetTypeInfoCount;
I := 0;
while I < Count do begin
hr := spTypeLib.GetTypeInfo(I, spTypeInfo);
if Failed(hr) then Exit;
hr := spTypeInfo.GetTypeAttr(pta);
if Failed(hr) then Exit;
if TKIND_COCLASS = pta.typekind then begin
StringFromGUID2(pta.guid, PWideChar(Result), Length(Result)* sizeof(WideChar));
spTypeInfo.ReleaseTypeAttr(pta);
pta := Nil;
Exit;
end;
spTypeInfo.ReleaseTypeAttr(pta);
pta := Nil;
Inc(I);
end;
end;//取得ProgID
function GetProgID(FileName: String): String;
var
spTypeLib: ITypeLib;
spTypeInfo: ITypeInfo;
pta: PTypeAttr;
hr: HRESULT;
Count, I: UINT;
bstrName0, bstrName: WideString;
begin
Result := '';
hr := LoadTypeLib(PWideChar(WideString(FileName)),spTypeLib);
if Failed(hr) then Exit;
Count := spTypeLib.GetTypeInfoCount;
hr := spTypeLib.GetDocumentation( -1
, @bstrName0
, Nil
, 0
, Nil
);
if Failed(hr) then Exit;
I := 0;
while I < Count do begin
hr := spTypeLib.GetTypeInfo(I, spTypeInfo);
if Failed(hr) then Exit;
hr := spTypeInfo.GetDocumentation( -1
, @bstrName
, Nil
, 0
, Nil
);
if Failed(hr) then Exit;
hr := spTypeInfo.GetTypeAttr(pta);
if Failed(hr) then Exit;
if TKIND_COCLASS = pta.typekind then begin
Result := WideString(bstrName0) + '.' + WideString(bstrName);
spTypeInfo.ReleaseTypeAttr(pta);
pta := Nil;
Exit;
end;
spTypeInfo.ReleaseTypeAttr(pta);
pta := Nil;
Inc(I);
end;
end;//取得文件版本
function GetVersion(FileName: String): String;
var
dwHandle: DWORD ;
m_szVersion: array[0..255] of char;
dwVerSize: DWORD;
pbBuffer: PChar;
lpVSInfo: PVSFixedFileInfo;
uiVerSize: UINT;
begin
Result := '0,0,0,0';
uiVerSize := 0;
dwVerSize := GetFileVersionInfoSize(PChar(FileName), &dwHandle);
lpVSInfo := Nil;
pbBuffer := AllocMem( dwVerSize);
if (pbBuffer = Nil) then Exit;
if (GetFileVersionInfo(PChar(FileName), 0, dwVerSize, pbBuffer)) then begin
if (VerQueryValue(pbBuffer, '\', Pointer(lpVSInfo), uiVerSize)) then begin
Result := Format( '%d,%d,%d,%d',
[ (lpVSInfo^.dwFileVersionMS shr 16) and $FFFF,
lpVSInfo^.dwFileVersionMS and $FFFF,
(lpVSInfo^.dwFileVersionLS shr 16) and $FFFF,
lpVSInfo^.dwFileVersionLS and $FFFF
]
);
end;
end; FreeMem(pbBuffer);
end;
procedure MakeCAB(FileName: String);
var
CABFileName, DDFFileName, InfFileName: String;
F: TFileStream;
P: PChar;
iLen, iWrote: Integer; Title, DLLName, ProgID, ClsID, FileVer: String; CABDirective, InfFile: String; _hfile: HFILE;
mCreationTime, mLastAccessTime, mLastWriteTime: FILETIME; StartInfo: STARTUPINFO ; // name structure
ProcInfo: PROCESS_INFORMATION ; // name structure
begin
CoInitialize(Nil);
try
FileVer := GetVersion(FileName);
ClsID := GetCLSID(FileName);
DLLName := ExtractFileName(FileName);
ProgID := GetProgID(FileName);
Title := 'Ocx Inf file Maker';
InfFileName := ChangeFileExt(FileName, '.inf');
CabFileName := ChangeFileExt(FileName, '.cab');
DDFFileName := ChangeFileExt(FileName, '.ddf'); CABDirective := StringReplace( MakeCabDirective,
'%CABFile%',
ExtractFileName(CabFileName),
[rfReplaceAll, rfIgnoreCase]
);
CABDirective := StringReplace( CABDirective,
'%CABFilePath%',
ExtractFilePath(CabFileName),
[rfReplaceAll, rfIgnoreCase]
)
+ '"' + FileName + '"'
+ #13#10'"' + InfFileName + '"'; //如果还有其它附加文件需要打包请在这里增加一个CallBack
//直接按每文件一行往上附加 InfFile := StringReplace( Templete,
'%Title%',
Title,
[rfReplaceAll, rfIgnoreCase]
);
InfFile := StringReplace( InfFile,
'%DLLName%',
DLLName,
[rfReplaceAll, rfIgnoreCase]
);
InfFile := StringReplace( InfFile,
'%DllVersion%',
FileVer,
[rfReplaceAll, rfIgnoreCase]
);
InfFile := StringReplace( InfFile,
'%ProgId%',
ProgID,
[rfReplaceAll, rfIgnoreCase]
);
InfFile := StringReplace( InfFile,
'%DLLClsid%',
ClsID,
[rfReplaceAll, rfIgnoreCase]
); //写入INF文件
f := TFileStream.Create(InfFileName,fmCreate);
try
p := PChar(InfFile);
iLen := Length(InfFile);
while (iLen > 0) do begin
iWrote := f.Write(p^, iLen);
Inc(p, iWrote);
Dec(iLen, iWrote);
end;
finally
f.Free;
end; //如果还有其它附加文件请在这里增加一个CallBack
//文件通常有两类:1.需要注册的;2.不需要注册的.
//另外就是文件可能安装目录有两种:1.当前目录(即随机目录);2.特定目录(可以使用环境变量)
//写Inf文件请按照.Ini格式,比如TIniFile类或者API来操作等
//更新.INF的文件时间为.OCX的时间
_hFile := _lopen(PChar(FileName), OF_READWRITE);
GetFileTime( THANDLE(_hFile),
@mCreationTime,
@mLastAccessTime,
@mLastWriteTime
);
_lclose(_hFile); _hFile := _lopen(PChar(InfFile), OF_READWRITE);
SetFileTime( THANDLE(_hFile),
@mCreationTime,
@mLastAccessTime,
@mLastWriteTime
);
_lclose(_hFile); //写入DDF文件,供工具程序MakeCab.exe使用
f := TFileStream.Create(DDFFileName,fmCreate);
try
p := PChar(CABDirective);
iLen := Length(CABDirective);
while (iLen > 0) do begin
iWrote := f.Write(p^, iLen);
Inc(p, iWrote);
Dec(iLen, iWrote);
end;
finally
f.Free;
end; //执行MakeCAB创建CAB包 fillchar(ProcInfo, sizeof(ProcInfo), 0); // Set up memory block
fillchar(StartInfo, sizeof(StartInfo), 0); // Set up memory block
StartInfo.cb := sizeof(StartInfo); // Set structure size
if Not CreateProcess( Nil,
PChar('makecab /f "' + DDFFileName + '"'),
Nil,
Nil,
False,
0,
Nil,
PChar(ExtractFilePath(FileName)),
StartInfo,
ProcInfo) then
Exit; WaitForSingleObject(ProcInfo.hProcess, INFINITE);
CloseHandle(ProcInfo.hThread);
CloseHandle(ProcInfo.hProcess); //更新CAB的文件时间为.OCX的时间
_hFile := _lopen(PChar(FileName), OF_READWRITE);
GetFileTime( THANDLE(_hFile),
@mCreationTime,
@mLastAccessTime,
@mLastWriteTime
);
_lclose(_hFile); _hFile := _lopen(PChar(CabFileName), OF_READWRITE);
SetFileTime( THANDLE(_hFile),
@mCreationTime,
@mLastAccessTime,
@mLastWriteTime
);
_lclose(_hFile);
finally
CoUninitialize;
end;end;
end.
uses
UnitMakeCAB;
procedure TForm3.Button1Click(Sender: TObject);
var
FileName: String;
begin
if OpenDialog1.Execute then begin
FileName := OpenDialog1.FileName;
if SameText(ExtractFileExt(FileName), '.ocx') then begin
MakeCAB(FileName);
end;
end;
end;
问一下:
关于:
[AddToRegistry]
HKLM,"SOFTWARE\Classes\CLSID\%DLLClsid%\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}"
HKLM,"SOFTWARE\Classes\CLSID\%DLLClsid%\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}" 这里的7DD95801-9882-11CF-9FA9-00AA006C42C4是什么,是固定的吗?
现在发现浏览器会拦截我的ocx,而且就算设置了浏览器信任站点和自定义设置里对Activex的启动,但有些反病毒软件也会自动拦截。
如果有数字签名应该会解决这个问题。
1、点击makecab按钮,会把主程序窗口再弹出一个。
2、只生成了inf文件,但没生成cab文件
3、生成的inf文件里,FileVersion=0,0,0,0,是不是我应该设置ActiveX的版本为自动增长?
执行:
[code=BatchFile]makecab.exe /f xxx.ddf[/code]
这条注释是有问题的,忘改了.
实际上是对于长路径需要使用双引号将路径引起来。另外,我测试的系统是Win2003,不知道是否存在MakeCab.exe版本的问题。最最最为关键的是,你不能把自己的程序命名为MakeCab.exe...
1、因为我把这个工程生成的exe也命名为makecab.exe了。所以程序默认会执行我这个makecab.exe而不是系统的那个。
2、因为执行的是我的makecab.exe,所以不会生成cab。
3、ActiveX项目的project-options-version info,选中include version infomation in project就可以了
不承认的情况下你得修改ie设置才行.
做成CAB自带inf安装信息,通过页面下载安装也和直接OCX效果一样会被IE禁用吗?现在来看,购买数字签名是不太可能了,只能想其他的办法。
大家还有什么好的建议,是我们自己可以通过技术实现的呢?
简单的做法就是提供安装包,让用户手动安装.不买数字签名想通过ie安装比较困难.要不你给ie打补丁,让ie不验证数字签名.