【问题标题】:Reg free COM interop with C#, possible?Reg free COM 与 C# 互操作,可能吗?
【发布时间】:2012-03-24 01:36:48
【问题描述】:

是否可以将免注册 COM 与 Dotnet 互操作和 C# 一起使用?如果是这样,如何在 C# 项目中添加对 COM 对象的引用?

我有一个带有嵌入式清单和两个测试客户端的无 reg ATL COM 服务器 dll,一个 cpp 另一个 c#。 cpp 客户端使用 import 语句正确引用 COM 对象,并且

#pragma comment(linker, "\"/manifestdependency:type='win32' name='TestComSvr2' version='1.0.0.0'\"")

或在Linker->Manifest File选项下将'Additional Manifest Dependencies'设置为“type='win32' name='TestComSvr1' version='1.0.0.0'”,之后cpp客户端将正确运行,只要COM 组件在同一目录中。

c# 客户端虽然根本拒绝播放。

尝试向未注册的 COM 组件 dll 或未注册的 tlb 添加文件引用会导致错误:

“无法添加对 'blah blah' 的引用。请确保该文件可访问,并且它是有效的程序集或 COM 组件”。

只使用“regtlib TestComSvr”注册类型库,然后创建一个文件或 COM 引用导致 c# 项目无法构建:

“加载类型库/Dll 时出错。(来自 HRESULT 的异常:0x80029C4A (TYPE_E_CANTLOADLIBRARY))”。

在c#项目中正常注册COM组件并创建引用,将引用设置为Isolated,构建c#项目然后注销组件并运行c#项目会导致此异常:

由于以下错误,检索具有 CLSID {B1D0A80F-0050-4856-BACD-87D664E58CBE} 的组件的 COM 类工厂失败:80040154 未注册类(HRESULT 异常:0x80040154 (REGDB_E_CLASSNOTREG))。

注意:即使这有效,它也不会是一个有用的案例,因为最终它仍然需要注册组件,我只是测试了它的完整性。

到目前为止,我能够从 C# 引用 COM 对象的唯一方法是注册 COM 对象本身,这当然完全违背了这一点,因为它根本不是无注册的。

有人有什么想法吗?

(这是在带有 VS2010 sp1 的 WinXP 上)。

【问题讨论】:

  • 想知道是否需要为 Visual Studio exe 本身创建清单文件?找到了这个链接,但不确定它是否有用msdn.microsoft.com/en-us/library/ms973913.aspx
  • 另外,如果您使用 tlbimp 创建一个互操作 dll 并引用它会怎样?即使用 'tlbimp '?

标签: c# visual-studio-2010 com


【解决方案1】:

你需要:


  1. 您需要提供免注册 COM 程序集清单,在其中说明您对 Neutrino.TestComSvr2 程序集的依赖:

    <?xml version="1.0" encoding="utf-8"?>
    <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" 
                xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" 
                xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
       <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
    
       <!-- We depend on our COM object -->
       <dependency>
          <dependentAssembly>
              <assemblyIdentity type="win32" name="Neutrino.TestComSvr2" version="1.0.0.0" />
          </dependentAssembly>
       </dependency>
    
    
       <!-- 
           Everything else in this sample manifest is not relavent to this answer, 
           but every developer should be doing their job and writing correct 
           Windows programs 
       -->
    
       <!-- Disable file and registry virtualization. -->
       <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
          <security>
             <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
             </requestedPrivileges>
          </security>
       </trustInfo>
    
       <!-- We are high-dpi aware on Windows Vista -->
       <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
          <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
             <dpiAware>true</dpiAware>
          </asmv3:windowsSettings>
       </asmv3:application>
    
       <!-- Declare that we were designed and tested on Windows 7-->
       <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
          <application>
              <!--The ID below indicates application support for Windows 7 -->
              <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
              <!--The ID below indicates application support for Windows Vista -->
              <!-- supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/ -->
          </application>
       </compatibility>
    
       <!-- We depend on Common Controls version 6 (i.e. "enable themes") -->
       <dependency>
          <dependentAssembly>
             <assemblyIdentity
                   type="win32"
                   name="Microsoft.Windows.Common-Controls"
                   version="6.0.0.0"
                   processorArchitecture="*"
                   publicKeyToken="6595b64144ccf1df"
                   language="*"
             />
          </dependentAssembly>
       </dependency>
    

    注意:我的问题 Registration-Free COM from ASP.NET?

    中有类似的清单
  2. 然后你需要在你的 C# exe 中包含这个应用程序清单:

    1. 在解决方案资源管理器中右键单击项目。
    2. 点击“添加新项目”
    3. 选择“应用程序清单文件”

这些步骤与 MSDN 上的adding a manifest to a managed application 类似。

您还需要确保您的 Neutrino.TestComSvr2 程序集包含它的免注册 COM 条目:

Neutrino.TestComSvr2.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

   <assemblyIdentity type="win32" name="Neutrino.TestComSvr2" version="1.0.0.0" />

   <file name = "ContosoFrobber.dll">

      <comClass
            progid="Frobber.Gizmo"
            clsid="{00028C00-0000-0000-0000-000000000046}"
            description="Gizmo Frobber by Contoso"
            threadingModel = "Apartment" />

      <typelib 
            tlbid="{00028C01-0000-0000-0000-000000000046}"
            version="1.0" 
            helpdir=""/>
   </file>
</assembly>

还有 blingo blango,你应该在工作。

【讨论】:

  • 结合了这个和 PeskyGnat 的建议,直接从 tlb 生成互操作程序集,最终得到了这个工作,而无需注册 COM 组件或其类型库。非常感谢。
  • 这个清单对我来说几乎是按原样工作的,但我必须在应用程序清单中的dependendAssebmly 名称的末尾加上“.dll”:name="mycomserver.dll"。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2014-09-03
  • 2011-07-02
  • 1970-01-01
  • 2010-12-14
  • 2012-06-18
  • 1970-01-01
相关资源
最近更新 更多