在没有管理员权限的情况下注册 .Net COM DLL/regasm [英] Registering .Net COM DLLs without Admin rights / regasm

查看:37
本文介绍了在没有管理员权限的情况下注册 .Net COM DLL/regasm的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我用 C# 编写了一个用于 Office 应用程序的类库,其中包括一个约有 70 人使用的关键 Access 应用程序.对于具有管理员权限的用户来说,注册 DLL 是微不足道的,但让 DLL 在其他机器上运行却是个问题.

Recently, I wrote a class library in C# for use in Office applications, including a critical Access application used by ~70 people. For users with admin rights, registering the DLL is trivial, but getting the DLL working on other machines was problematic.

  • 在 Visual Studio 中构建 DLL.确保在项目的应用标签上选择这些选项:
    • 输出类型:类库
    • 程序集信息:使程序集对 COM 可见:已检查
    • Build the DLL in Visual Studio. Ensure these options are selected on the project's Application tab:
      • Output Type: Class Library
      • Assembly Information: Make assembly COM-visible: Checked
      • RegAsm YourDll.dll/tlb/codebase

      Regasm 在这里做了几件事.首先,它创建一个类型库 (YourDLL.tlb),它提供有关 DLL 中的类的信息.其次,它将有关库的信息存储在注册表中,以便系统知道"您要求将类实例化为对象时的意思.

      Regasm is doing several things here. First, it is creating a type library (YourDLL.tlb) which provides information about the classes that are in your DLL. Second, it is storing the information about the library in the registry so that the system "knows" what you mean when you ask for a class to be instantiated as an object.

      要查看 Regasm 添加的注册表项,您可以使用 /regfile 参数运行它:

      To see what registry entries Regasm is adding, you can run it with the /regfile parameter:

      Regasm YourDLL.dll/codebase/regfile

      (/regfile 选项对 /tlb 参数无效.)

      (The /regfile option is invalid with the /tlb parameter.)

      如果 /codebase 选项告诉 Regasm 包含有关 YourDLL.dll 在磁盘上的位置的信息,这对于创建对象很重要.

      If the /codebase option tells Regasm to include information about where YourDLL.dll is located on disk, which is important for creating the objects.

      如果您在文本编辑器中打开 YourDLL.reg,您将看到 Regasm 添加到注册表的条目:HKEY_Classes_Root 的条目(实际上只是重定向到 HKLMSoftwareClasses).不幸的是,您需要管理员权限才能修改 HKLM,因此这不适用于我们的其他用户.

      If you open YourDLL.reg in a text editor, you'll see the entries that Regasm is adding to the registry: entries to HKEY_Classes_Root (which is really just a redirect to HKLMSoftwareClasses). Unfortunately, you need admin privileges to modify HKLM, so this isn't going to work for our other users.

      还有一些其他主题(例如 注册没有管理员权限的 COM, 注册供 VBA 使用的 COM DLL为非管理员用户注册 DLL (ActiveX), 无法注册 .NET COM DLL, COM Interop without regasm) 讨论了该问题,但他们的解决方案很复杂(例如需要注册表重定向)或不完整(假设您已经知道至少一半的答案)或者不在混合 64/32 位环境中工作(例如Win64、Office32).

      There are a few other threads (e.g. Registering a COM without Admin rights, Register COM DLL for use by VBA, Register DLL (ActiveX) for non-admin user, Unable to register .NET COM DLL, COM Interop without regasm) that discuss the problem, but their solutions are complex (e.g. require registry redirection) or incomplete (assume you already know at least half of the answer) or do not work in mixed 64/32 bit environments (e.g. Win64, Office32).

      那么如何注册在 Visual Studio 中创建的 COM DLL,以便在没有管理权限的情况下为当前用户在 VBA 32 和 64 位环境中使用?

      推荐答案

      设置注册表文件

      要注册在 32 位和 64 位环境中使用的组件,我们需要修改我们在测试用例中创建的注册表文件.使用您最喜欢的文本编辑器打开它.条目应如下所示:

      Setting up the registry files

      To register the components for use in 32 and 64 bit environments, we are going to need to modify the registry file we created in our test case. Open it with your favorite text editor. The entries should look something like this:

      [HKEY_CLASSES_ROOT\YourAssembly.Class]
      @="YourAssembly.Class"
      
      [HKEY_CLASSES_ROOT\YourAssembly.Class\CLSID]
      @="{YourClassGUID}"

      确保它包含 "CodeBase"= 条目.

      进行全局查找/替换:

      • 更改HKEY_CLASSES_ROOT(别名为HKLMSoftwareClasses)
      • HKEY_CURRENT_USERSoftwareClasses

      将所有注册表项(及其值,列在键下方)复制到第二个文本文件.在第二个文本文件中:

      Copy all of the registry keys (and their values, which are listed below the keys) to a second text file. In the second text file:

      • 删除所有不包含CLSID的键(及其相关值)
      • 进行全局查找/替换:
        • 更改ClassesCLSID
        • 收件人:ClassesWow6432NodeCLSID
        • Delete all of the keys (and their related values) that do not contain CLSID
        • Do a global find/replace:
          • Change ClassesCLSID
          • To: ClassesWow6432NodeCLSID

          将第二个文本文件中的所有密钥复制到原始 .reg 文件中,然后保存.

          Copy all of the keys from the second text file to your original .reg file, and save it.

          使用 regasm 从 HKLM 中删除注册条目:

          Remove the registration entries from HKLM by using regasm:

          Regasm YourDLL.dll /unregister

          确保一切正常

          为了确保我们的更改有效(并且您不只是因为您最初使用 regasm 进行的注册而成功),我们需要确保 VBA 无法创建对象现在.

          打开您最喜欢的 VBA 应用程序,并添加对 YourDLL.tlb 的引用.创建一个类似这样的新程序:

          Open up your favorite VBA application, and add a reference to YourDLL.tlb. Create a new procedure that is something like this:

          Public Sub TestYourDLL()
            Dim x as AssemblyName.ClassName
            Set x = New AssemblyName.ClassName
            Debug.Print "Apparently this worked."
          End Sub
          

          运行 TestYourDLL.您应该会收到以下错误:

          Run TestYourDLL. You should receive the error:

          Run-time error '429':
          
          ActiveX component can't create object

          (如果您没有收到错误消息,则您的 DLL 仍处于注册状态.)

          (If you don't receive the error, your DLL is still registered.)

          保存并退出您的 VBA 应用程序.

          Save and exit your VBA application.

          现在,运行您之前创建的 YourDLL.reg 以将条目导入注册表.(如果您收到拒绝访问"消息,则是您忘记将 HKEY_CLASSES_ROOT 更改为 HKEY_CURRENT_USERSoftwareClasses)

          Now, run the YourDLL.reg that you created earlier to import the entries to the registry. (If you get an "Access denied" message, you forgot to change from HKEY_CLASSES_ROOT to HKEY_CURRENT_USERSoftwareClasses)

          再次打开您的 VBA 应用程序,然后运行 ​​TestYourDLL.您现在应该会看到显然这行得通".在您的直接窗口中.恭喜!您已经注册了 DLL!(如果您收到自动化错误:系统找不到指定的文件"类型的错误,您的注册表文件要么缺少 Codebase 条目,要么它们没有指向您的 DLL 的实际位置.)

          Open your VBA application again, and run TestYourDLL. You should now see "Apparently this worked." in your immediate window. Congratulations! You've registered the DLL! (If you get an "Automation error: The system cannot find the file specified"-type error, your registry file is either missing the Codebase entries, or they are not pointing to the actual location of your DLL.)

          就我而言,我将在一堆其他用户的计算机上与我的应用程序一起安装 DLL,因此在安装时我将更新 CodeBase 值以引用我安装 DLL 的位置,我还将通过代码安装注册表项,而不是通过执行 .reg 文件.但是,既然我知道了所需的条目,那么做这件事就很简单了.

          In my case, I'm going to be installing the DLL on a bunch of other users' computers alongside my application, so at installation time I'll update the CodeBase value to refer to the location where I'm installing the DLL, and I'll also install the registry entries through code, rather than by executing the .reg file. But, now that I know the required entries, doing that is trivial.

          这篇关于在没有管理员权限的情况下注册 .Net COM DLL/regasm的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆