【问题标题】:What is the different between /n and /i parameters of RegSvr32.exe?RegSvr32.exe 的 /n 和 /i 参数有什么区别?
【发布时间】:2012-06-14 22:55:09
【问题描述】:

要注册一个 COM 服务器,我们在提升模式下运行类似的东西:

regsvr32.exe com.dll

要执行每个用户的注册,请在用户帐户中执行:

regsvr32.exe /n /i:user com.dll

regsvr32.exe 支持这些参数:

/u - Unregister server 
/i - Call DllInstall passing it an optional [cmdline]; when used with /u calls dll uninstall 
/n - do not call DllRegisterServer; this option must be used with /i 
/s – Silent; display no message boxes (added with Windows XP and Windows Vista)

在 Delphi 中创建 COM 服务器时,这些方法被导出:

exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer,
  DllInstall;

我注意到这些会发生:

  1. “regsvr32.exe com.dll”调用 DllRegisterServer。
  2. “regsvr32.exe /u com.dll”调用 DllUnregisterServer。
  3. “regsvr32.exe /n /i:user com.dll”调用 DllInstall。
  4. “regsvr32.exe /u /n /i:user com.dll”调用 DllInstall。

我对参数 /n 和 /i 以及 DllUnregisterServer 和 DllInstall 感到困惑。有什么不同吗?

另外,为什么“/u /n /i:user”会调用 Dllinstall?我注意到“HKEY_CURRENT_USER\Software\Classes”中相应的注册表项已被删除。

【问题讨论】:

  • /n 只能 与 /i 一起使用,因此它不是“介于”之间。
  • 使用“/n /i”和没有参数(DllRegisterServer)有什么不同吗?什么时候使用“/n /i”,什么时候不使用任何参数?
  • 那么“何时使用 DllRegisterServer 而不是(仅)DllInstall”?
  • 或者简而言之,什么时候使用DllRegisterServer,什么时候使用DllInstall?有什么不同吗?
  • 是的,有区别。 DllRegisterServer() 是最常用的,但 DllInstall() 更灵活,因为您可以向它发送参数。

标签: windows winapi com


【解决方案1】:

The documentation for DllInstall() 解释区别:

DllInstall 仅用于应用程序安装和设置。它 不应由应用程序调用。它的目的类似于 DllRegisterServer 或 DllUnregisterServer。与这些功能不同, DllInstall 接受一个输入字符串,该字符串可用于指定一个 各种不同的动作。这允许将 DLL 安装在 不止一种方式,基于任何适当的标准。

要将 DllInstall 与 regsvr32 一起使用,请添加一个“/i”标志,后跟一个冒号 (:) 和一个字符串。该字符串将作为 pszCmdLine 参数。如果省略冒号和字符串,pszCmdLine 将被设置为 NULL。以下示例将用于安装 动态链接库。

regsvr32 /i:"Install_1" dllname.dll

DllInstall 被调用 bInstall 设置为 TRUE,pszCmdLine 设置为“Install_1”。卸载一个 DLL,使用如下:

regsvr32 /u /i:"Install_1" dllname.dll

有 上述两个示例,DllRegisterServer 或 DllUnregisterServer 也会被调用。要仅调用 DllInstall,请添加“/n”标志。

regsvr32 /n /i:"Install_1" dllname.dll

【讨论】:

    【解决方案2】:

    我的建议是完全跳过使用 regsvr32.exe —— 自己完成这项工作也很容易:

    int register(char const *DllName) { 
            HMODULE library = LoadLibrary(DllName); 
            if (NULL == library) { 
                    // unable to load DLL 
                    // use GetLastError() to find out why. 
                    return -1;      // or a value based on GetLastError() 
            } 
            STDAPI (*DllRegisterServer)(void); 
            DllRegisterServer = GetProcAddress(library, "DllRegisterServer"); 
            if (NULL == DllRegisterServer) { 
                    // DLL probably isn't a control -- it doesn't contain a 
                    // DllRegisterServer function. At this point, you might 
                    // want to look for a DllInstall function instead. This is 
                    //  what RegSvr32 calls when invoked with '/i' 
                    return -2; 
            } 
            int error; 
            if (NOERROR == (error=DllRegisterServer())) { 
                    // It thinks it registered successfully. 
                    return 0; 
            } 
            else 
                    return error; 
    } 
    

    这个特定的代码调用DllRegisterServer,但根据需要将其参数化为调用DllInstallDllUninstall 等很简单。这消除了关于何时调用什么等的任何问题。

    【讨论】:

    • -1 没有回答被问到的问题,一个可以回答的问题。
    • @DavidHeffernan:你无疑是对的——回答他提出的问题比试图真正帮助他更好。我可能应该因为做了这么可怕的事情而被永久开除。
    • @JerryCoffin:你的回答对我也有帮助,虽然不是直接回答这个问题。我也通过使用编程技术而不是使用命令行注册 dll 从您的答案中学习。
    • 谢谢,对我来说真的很有帮助。
    猜你喜欢
    • 2014-11-23
    • 1970-01-01
    • 2019-11-17
    • 2011-03-21
    • 2021-08-25
    相关资源
    最近更新 更多