zoukankan      html  css  js  c++  java
  • How to Register COM in VS

    在 Visual Studio .Net 部署项目中注册 COM 模块的步骤

    1. 将 COM 对象添加到 Visual Studio 部署项目。
    2. 在解决方案资源管理器中,右键单击刚添加的模块,然后单击属性

      注意:“属性”窗口包含一个表,其中有两列和 x 行(行数取决于项目)。左列列出特定属性。右列将在步骤 4 中解释。
    3. 转到此模块的属性(默认情况下位于 .NET 部署项目的右上角),然后单击“注册表属性”。

      注意:注册表属性指定在安装过程中,应将文件、程序集还是项目输出组注册在目标计算机上。
    4. 在注册表属性的右列中有一个列表框,它显示供您选择的几个选项。请注意解释这些选项的下列详细信息:

        • 对于程序集,通常不需要注册,因而默认值是 DoNotRegister(这意味着安装过程中不会注册该项)。

        • 对于 COM 模块,您可以选择 COMCOMRelativePath 和 COMSelfReg。在安装过程中,这三个选项中的任何一个都将注册 COM 模块。

          请注意下列有关每个选项的详细信息:
        1. COM:模块将由 Windows 安装程序引擎注册为 COM 对象。部署项目将更新相应 .msi 文件的 Registry Tables 组中的 Class 表、ProgID 表和其他表。这是注册 COM 模块的建议方式。
        2. COMRelativePath:模块将由 Windows 安装程序引擎注册为独立的 COM 对象。请注意,此模块只能由安装它时使用的应用程序所使用。
        3. COMSelfReg:在安装模块时,安装程序调用此模块的 DllRegisterServer 函数;在卸载模块时,安装程序调用 DllUnregisterServer 函数。部署项目将更新相应 .msi 文件的 SelfReg 表。建议安装包不要使用自注册。相反,安装包应通过创作安装程序所提供的、用于此用途的一个或多个其他表注册模块(即选择 COM 或COMRelativePath 选项)。对于自注册,将失去拥有中央安装程序服务的许多好处,原因是自注册例程常常会隐藏关键配置信息。

      现在可以生成部署项目,以允许前面的修改依照在步骤 4 中选择的注册属性选项来注册 COM 对象。
    5. 编写批处理脚本.bat文件,使用regsvr32 /s命令注册,调用bat脚本。
    6. 用 LoadLibrary 和 GetProcAddress 取得控件中 DllRegisterServer 函数地址,然后调用注册。
      typedef LONG (*FUN)();
      HMODULE hDll = ::LoadLibrary(TEXT("C:\\WINDOWS\\system32\\Macromed\\Flash\\Flash10e.ocx"));
      if (!hDll)
      return;
       
      FUN fn = (FUN)GetProcAddress(hDll, "DllRegisterServer");
      if (fn)
      {
          fn();
      }
      FreeLibrary(hDll);

    7. 让应用程序在运行的时候自动检查所需要的支持文件和注册控件,免除安装和手动注册。适当修改下面的代码中的支持文件列表,并在App::InitInstance()中调用。
      #include <shlwapi.h>
      #pragma comment(lib, "shlwapi.lib")
      
      //检测需要的文件是否存在
      //并且对需要注册的文件进行注册
      //输入参数用于指示文件所在的路径
      //返回TRUE表示成功
      BOOL Check_Environment(LPCTSTR lpszAppPath) //传入文件路径
      {
        //列出所需要的文件列表
        typedef struct _FILE_CELL
        {
          LPCTSTR szFileName; //文件名
          BOOL bNeedRegister; //需要注册?
        }FILE_CELL;
        const FILE_CELL Support_FileList[] =
        {
          {_T("aaa.ocx"), TRUE},   {_T("bbb.ocx"), TRUE},   {_T("ccc.ocx"), TRUE}, 
          {_T("fff.dll"), TRUE},    {_T("other.sys")}, //other need file
      
          0, //Don't remove this line
        };
      
        BOOL bRet = 0;
        TCHAR e_mess[4096], mess[256];
        memset(e_mess, 0, sizeof(e_mess));
      
        int uIndex = 0;
        while(Support_FileList[uIndex].szFileName)
        {
          TCHAR fileName[MAX_PATH + 1];
          _tcscpy_s(fileName, lpszAppPath);
          PathAddBackslash(fileName);
          _tcscat_s(fileName, Support_FileList[uIndex].szFileName);
      
          if(PathFileExists(fileName))
          {
            //if(_tcsicmp(PathFindExtension(fileName),_T(".ocx"))==0) //是需要注册的OCX文件
            if(Support_FileList[uIndex].bNeedRegister) //需要注册
            {      
              //使用短路径名主要是为兼容Win98
              TCHAR shortfileName[MAX_PATH + 1];
              GetShortPathName(fileName, shortfileName, MAX_PATH);
      
              // Path to OLE Control in shortfileName
              HMODULE hModule = LoadLibrary(shortfileName);
              if(hModule)
              {
                typedef HRESULT (STDAPICALLTYPE *CTLREGPROC)() ; // Requires olectl.h
                CTLREGPROC DLLRegisterServer = 
                  (CTLREGPROC)GetProcAddress(hModule,"DllRegisterServer" ) ;
                if(DLLRegisterServer)
                {
                  if(DLLRegisterServer() != S_OK)
                  {
                    _stprintf_s(mess, _T("注册模块失败 %s\r\n"), fileName);
                    _tcscat_s(e_mess, mess);
                  }
                }
                else
                {
                  _stprintf_s(mess, _T("模块%s找不到指定注册入口\r\n"), fileName);
                  _tcscat_s(e_mess, mess);
                }
                FreeLibrary(hModule) ;
              }
              else
              {
                _stprintf_s(mess, _T("加载模块失败 %s\r\n"), fileName);
                _tcscat_s(e_mess, mess);
              }
            }
          }
          else //提示缺少必要的支持文件
          {
            _stprintf_s(mess, _T("缺少必要的文件 %s\r\n"), fileName);
            _tcscat_s(e_mess, mess);
          }
      
          uIndex++;
        }
      
        if(_tcslen(e_mess) > 0) //检测出错提示
        {
          MessageBox(NULL, e_mess, _T("Error"), MB_OK );
        }
        else
        {
          bRet = true;
        }
      
        return(bRet);
      }

  • 相关阅读:
    对软件未来走向的看法
    ubuntu:configure error:cannot find ssl libraries
    linux CentOS普通用户无法从ssh登录解决方案
    Can't locate IPC/Run.pm in @INC
    我也学erlang(一)
    我也学erlang(二)
    我也学erlang(四)
    第一篇献给church(丘奇)
    出现epoll failed: Bad file descriptor的原因
    最近看代码的一点总结
  • 原文地址:https://www.cnblogs.com/yefengmeander/p/2887550.html
Copyright © 2011-2022 走看看