制作OCX的网络发布CAB包

 

  1. #include <atl/atlbase.h>
  2. //.inf文件模板
  3. const
  4.   AnsiString Templete =
  5. "; /%Title/%/r/n/
  6. ; File Name /%DLLName/%  File Version= /%DllVersion/%/r/n/
  7. ; ProgId= /%ProgId/% ClassId= /%DLLClsid/%/r/n/r/n/
  8. [version]/r/n/
  9. signature=/"$CHICAGO$/"/r/n/
  10. AdvancedINF=2.0/r/n/r/n/
  11. [Add.Code]/r/n/
  12. /%DLLName/%=/%DLLName/%/r/n/r/n/
  13. [/%DLLName/%]/r/n/
  14. file-win32-x86=thiscab/r/n/
  15. RegisterServer=yes/r/n/
  16. clsid=/%DLLClsid/%/r/n/
  17. DestDir=/r/n/
  18. FileVersion=/%DLLVersion/%/r/n/r/n/
  19. [Setup Hooks]/r/n/
  20. AddToRegHook=AddToRegHook/r/n/r/n/
  21. [AddToRegHook]/r/n/
  22. InfSection=DefaultInstall/r/n/r/n/
  23. [DefaultInstall]/r/n/
  24. AddReg=AddToRegistry/r/n/r/n/
  25. [AddToRegistry]/r/n/
  26. HKLM,/"SOFTWARE//Classes//CLSID///%DLLClsid/%//Implemented Categories//{7DD95801-9882-11CF-9FA9-00AA006C42C4}/"/r/n/
  27. HKLM,/"SOFTWARE//Classes//CLSID///%DLLClsid/%//Implemented Categories//{7DD95802-9882-11CF-9FA9-00AA006C42C4}/"";
  28. //MackCab 用的中间文件模板,文件附加在后面,不能带路径(估计可以支持8.3短路径)
  29. const AnsiString MakeCabDirective =
  30. ".OPTION EXPLICIT     ; Generate errors/r/n/
  31. .Set CabinetNameTemplate=/%CABFile/%/r/n/
  32. .set DiskDirectoryTemplate=CDROM ; All cabinets go in a single  directory/r/n/
  33. .Set CompressionType=MSZIP;** All files are compressed in cabinet files/r/n/
  34. .Set UniqueFiles=/"OFF/"/r/n/
  35. .Set Cabinet=on/r/n/
  36. .Set DiskDirectory1=/%CABFilePath/%/r/n";
  37. //---------------------------------------------------------------------------
  38. //取得CoClass的ClassID
  39. AnsiString __fastcall GetCLSID(AnsiString FileName)
  40. {
  41.     HRESULT hr;
  42.     AnsiString Result="";
  43.     CComPtr<ITypeLib> spTypeLib;
  44.     USES_CONVERSION;
  45.     hr = LoadTypeLib(A2OLE(FileName.c_str()), &spTypeLib);
  46.     if (FAILED(hr)) return Result;
  47.     UINT n = spTypeLib->GetTypeInfoCount();
  48.     CComBSTR bstrName0;
  49.     hr = spTypeLib->GetDocumentation(   -1,
  50.                                         &bstrName0,
  51.                                         0,
  52.                                         0,
  53.                                         0
  54.                                         );
  55.     if(FAILED(hr))return Result;
  56.     for (UINT i=0; i<n; ++i)
  57.     {
  58.         CComPtr<ITypeInfo> spTypeInfo;
  59.         hr = spTypeLib->GetTypeInfo(i, &spTypeInfo);
  60.         if (FAILED(hr)) return Result;
  61.         CComBSTR bstrName;
  62.         hr = spTypeInfo->GetDocumentation(  -1,
  63.                                             &bstrName,
  64.                                             0,
  65.                                             0,
  66.                                             0
  67.                                             );
  68.         if (FAILED(hr)) return Result ;
  69.         TYPEATTR* pta = 0;
  70.         hr = spTypeInfo->GetTypeAttr(&pta);
  71.         if (FAILED(hr)) return Result;
  72.         CComBSTR bstrGuid(pta->guid);
  73.         if (TKIND_COCLASS == pta->typekind )
  74.         {
  75.             Result = AnsiString(bstrGuid);
  76.             spTypeInfo->ReleaseTypeAttr(pta);
  77.             pta = 0;
  78.             return Result;
  79.         }
  80.         spTypeInfo->ReleaseTypeAttr(pta);
  81.         pta = 0;
  82.      }
  83.      return Result;
  84. }
  85. //取得ProgID
  86. AnsiString __fastcall GetProgID(AnsiString FileName)
  87. {
  88.     HRESULT hr;
  89.     AnsiString Result="";
  90.     CComPtr<ITypeLib> spTypeLib;
  91.     USES_CONVERSION;
  92.     hr = LoadTypeLib(A2OLE(FileName.c_str()), &spTypeLib);
  93.     if (FAILED(hr)) return Result;
  94.     UINT n = spTypeLib->GetTypeInfoCount();
  95.     CComBSTR bstrName0;
  96.     hr = spTypeLib->GetDocumentation(   -1,
  97.                                         &bstrName0,
  98.                                         0,
  99.                                         0,
  100.                                         0
  101.                                         );
  102.     if(FAILED(hr))return Result;
  103.     for (UINT i=0; i<n; ++i)
  104.     {
  105.         CComPtr<ITypeInfo> spTypeInfo;
  106.         hr = spTypeLib->GetTypeInfo(i, &spTypeInfo);
  107.         if (FAILED(hr)) return Result;
  108.         CComBSTR bstrName;
  109.         hr = spTypeInfo->GetDocumentation(  -1,
  110.                                             &bstrName,
  111.                                             0,
  112.                                             0,
  113.                                             0
  114.                                             );
  115.         if (FAILED(hr)) return Result ;
  116.         TYPEATTR* pta = 0;
  117.         hr = spTypeInfo->GetTypeAttr(&pta);
  118.         if (FAILED(hr)) return Result;
  119.         CComBSTR bstrGuid(pta->guid);
  120.         int iKind = pta->typekind ;
  121.         if (iKind == TKIND_COCLASS)
  122.         {
  123.             Result = AnsiString(bstrName0)+"."+AnsiString(bstrName);
  124.             spTypeInfo->ReleaseTypeAttr(pta);
  125.             pta = 0;
  126.             return Result;
  127.         }
  128.         spTypeInfo->ReleaseTypeAttr(pta);
  129.         pta = 0;
  130.     }
  131.     return Result;
  132. }
  133. //取得文件版本
  134. AnsiString __fastcall GetVersion(char *szFile)
  135. {
  136.     DWORD dwHandle;
  137.     char m_szVersion[256];
  138.     DWORD dwVerSize = GetFileVersionInfoSize((char *)szFile, &dwHandle);
  139.     char *pbBuffer = new BYTE[dwVerSize];
  140.     VS_FIXEDFILEINFO     *lpVSInfo = NULL;
  141.     UINT    uiVerSize = 0;
  142.     if (!pbBuffer)
  143.     {
  144.         return E_OUTOFMEMORY;
  145.     }
  146.     if (GetFileVersionInfo((char *)szFile, 0, dwVerSize, pbBuffer))
  147.     {
  148.         if (VerQueryValue(pbBuffer, "//", (void **)&lpVSInfo, &uiVerSize))
  149.         {
  150.             wsprintf(   m_szVersion,
  151.                         "%d,%d,%d,%d",
  152.                         (lpVSInfo->dwFileVersionMS >> 16) & 0xFFFF,
  153.                         lpVSInfo->dwFileVersionMS & 0xFFFF,
  154.                         (lpVSInfo->dwFileVersionLS >> 16) & 0xFFFF,
  155.                         lpVSInfo->dwFileVersionLS & 0xFFFF
  156.                         );
  157.         }
  158.     }
  159.     delete [] pbBuffer;
  160.     return AnsiString(m_szVersion);
  161. }
  162. //制作用于发布的CAB包
  163. void __fastcall MakeCab(AnsiString FileName)
  164. {
  165.     AnsiString FileVer = GetVersion(FileName.c_str());
  166.     AnsiString ClsID = GetCLSID(FileName);
  167.     AnsiString DLLName = ExtractFileName(FileName);
  168.     AnsiString ProgID =  GetProgID(FileName);
  169.     AnsiString Title = "Ocx Inf file Maker";
  170.     AnsiString InfFileName = ChangeFileExt(FileName,".inf");
  171.     AnsiString CabFileName = ChangeFileExt(FileName,".cab");
  172.     AnsiString DDFFileName = ChangeFileExt(FileName,".ddf");
  173.     AnsiString CABDirective =   StringReplace(  MakeCabDirective,
  174.                                                 "/%CABFile/%",
  175.                                                 ExtractFileName(CabFileName),
  176.                                                 TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
  177.                                                 );
  178.     CABDirective =  StringReplace(  CABDirective,
  179.                                     "/%CABFilePath/%",
  180.                                     ExtractFilePath(CabFileName),
  181.                                     TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
  182.                                     )
  183.                     +   "/"" + FileName + "/""
  184.                     +   "/r/n/"" + InfFileName + "/"";
  185.     AnsiString InfFile;
  186.     InfFile =   StringReplace(  Templete,
  187.                                 "/%Title/%",
  188.                                 Title,
  189.                                 TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
  190.                                 );
  191.     InfFile =   StringReplace(  InfFile,
  192.                                 "/%DLLName/%",
  193.                                 DLLName,
  194.                                 TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
  195.                                 );
  196.     InfFile =   StringReplace(  InfFile,
  197.                                 "/%DllVersion/%",
  198.                                 FileVer,
  199.                                 TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
  200.                                 );
  201.     InfFile =   StringReplace(  InfFile,
  202.                                 "/%ProgId/%",
  203.                                 ProgID,
  204.                                 TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
  205.                                 );
  206.     InfFile =   StringReplace(  InfFile,
  207.                                 "/%DLLClsid/%",
  208.                                 ClsID,
  209.                                 TReplaceFlags()<<rfReplaceAll<<rfIgnoreCase
  210.                                 );
  211.     TFileStream *f = new TFileStream(InfFileName,fmCreate);
  212.     try
  213.     {
  214.         char *p = InfFile.c_str();
  215.         int iLen = InfFile.Length();
  216.         while (iLen){
  217.             int iWrote = f->Write(p,iLen);
  218.             p += iWrote;
  219.             iLen -= iWrote;
  220.         }
  221.     }
  222.     __finally
  223.     {
  224.         f->Free();
  225.     }
  226.     //更新.INF的文件时间为.OCX的时间
  227.     HFILE hFile;
  228.     FILETIME mCreationTime;
  229.     FILETIME mLastAccessTime;
  230.     FILETIME mLastWriteTime;
  231.     hFile=_lopen(FileName.c_str(),OF_READWRITE);
  232.     GetFileTime(    (HANDLE *)hFile,
  233.                     &mCreationTime,
  234.                     &mLastAccessTime,
  235.                     &mLastWriteTime
  236.                     );
  237.     hFile=_lopen(InfFile.c_str(),OF_READWRITE);
  238.     SetFileTime(    (HANDLE *)hFile,
  239.                     &mCreationTime,
  240.                     &mLastAccessTime,
  241.                     &mLastWriteTime
  242.                     );
  243.     _lclose(hFile);
  244.     f = new TFileStream(DDFFileName,fmCreate);
  245.     try
  246.     {
  247.         char *p = CABDirective.c_str();
  248.         int iLen = CABDirective.Length();
  249.         while (iLen){
  250.             int iWrote = f->Write(p,iLen);
  251.             p += iWrote;
  252.             iLen -= iWrote;
  253.         }
  254.     }
  255.     __finally
  256.     {
  257.         f->Free();
  258.     }
  259.     //执行MakeCAB创建CAB包
  260.     STARTUPINFO StartInfo; // name structure
  261.     PROCESS_INFORMATION ProcInfo; // name structure
  262.     memset(&ProcInfo, 0, sizeof(ProcInfo)); // Set up memory block
  263.     memset(&StartInfo, 0 , sizeof(StartInfo)); // Set up memory block
  264.     StartInfo.cb = sizeof(StartInfo); // Set structure size
  265.     if (!CreateProcess( NULL,
  266.                         AnsiString("makecab /f /""+DDFFileName+"/"").c_str(),
  267.                         NULL,
  268.                         NULL,
  269.                         NULL,
  270.                         NULL,
  271.                         NULL,
  272.                         ExtractFilePath(FileName).c_str(),
  273.                         &StartInfo,
  274.                         &ProcInfo))
  275.         return;
  276.     WaitForSingleObject(ProcInfo.hProcess,INFINITE);
  277.     CloseHandle(ProcInfo.hThread);
  278.     CloseHandle(ProcInfo.hProcess);
  279.     //更新CAB的文件时间为.OCX的时间
  280.     hFile=_lopen(FileName.c_str(),OF_READWRITE);
  281.     GetFileTime(    (HANDLE *)hFile,
  282.                     &mCreationTime,
  283.                     &mLastAccessTime,
  284.                     &mLastWriteTime
  285.                     );
  286.     hFile=_lopen(CabFileName.c_str(),OF_READWRITE);
  287.     SetFileTime(    (HANDLE *)hFile,
  288.                     &mCreationTime,
  289.                     &mLastAccessTime,
  290.                     &mLastWriteTime
  291.                     );
  292.     _lclose(hFile);
  293. }

示例:

  1. void __fastcall TfrmMakeCAB::btnMakeClick(TObject *Sender)
  2. {
  3.     if (dlgOpenOCX->Execute()) {
  4.         AnsiString FileName = dlgOpenOCX->FileName;
  5.         if (SameText(ExtractFileExt(FileName),".OCX")) {
  6.             MakeCab(FileName);
  7.         }
  8.     }
  9. }

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值