无法从VBA获得免注册COM [英] Cannot get registration-free COM working from VBA

查看:108
本文介绍了无法从VBA获得免注册COM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:在花了20多个小时尝试使一个简单的示例工作之后,我意识到这并不像看起来那样简单。文章像这样揭示陷阱-这是在Windows 7之前编写的(处理清单的方式不同)。我坚持将.NET程序集暴露给VBA 通过VSTO

UPDATE: After spending 20+ hours trying to get a simple example working, I have realized that this is not as simple as it seems. Articles like this reveal the "gotchas" - and this was written before Windows 7 (which handles manifests differently). I'm sticking with exposing .NET assemblies to VBA via VSTO.

我制作了一个简单的COM-Visible .NET程序集,并试图从Excel VBA中调用它。如果我在.NET构建过程中注册COM Interop,则可以成功地从VBA调用它。

I made a simple COM-Visible .NET assembly and am trying to call it from Excel VBA. If I "Register for COM Interop" during my .NET build, I can call it from VBA successfully.

Sub VBA()    
    Dim obj As Object
    Set obj = actCtx.CreateObject("ComTest.Main")
    MsgBox obj.Test() '<-- Displays "Hello"
End Sub

但是,我想免注册。

根据Hans的建议进行更新:

我未选中,注册COM Interop,并将我的应用设置为:

I unchecked Register for COM Interop, and set my app.Manifest to:

<?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
    type="win32"
    version="1.0.0.0" 
    name="ComTest" 
    publicKeyToken="a36a7110110d7bd7" />

  <clrClass
      clsid="{975DC7E0-4596-4C42-9D0C-0601F86E3A1B}"
      progid="ComTest.Main"
      threadingModel="Both"
      name="ComTest.Main"
      runtimeVersion="v4.0.30319">
  </clrClass>

  <file name = "ComTest.dll"></file>   
</asmv1:assembly>

我创建了一个虚拟的 client.manifest,如下所示:

I created a dummy "client.manifest" like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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">

    manifestVersion="1.0" 
    xmlns="urn:schemas-microsoft-com:asm.v1" >
    <assemblyIdentity
        name="xxx"
        version="1.0.0.0" />
    <dependency>
        <dependentAssembly>
            <assemblyIdentity
                type="win32"
                name="ComTest" 
                version="1.0.0.0"
                publicKeyToken="a36a7110110d7bd7" />
        </dependentAssembly>            
    </dependency>
</asmv1:assembly>

我在创建对象时修改了VBA以使用client.manifest:

I modified my VBA to use client.manifest when creating my object:

Sub VBA()    
    Dim actCtx As Object
    Set actCtx = CreateObject("Microsoft.Windows.ActCtx")
    actCtx.Manifest = "C:\Users\me\Desktop\COM Test\ComTest\ComTest\bin\Debug\client.manifest"

    Dim obj As Object
    Set obj = actCtx.CreateObject("ComTest.Main")  '<-- Fails here.
    MsgBox obj.Test()    
End Sub

在CreateObject上失败小于有用的错误对象'IActCtx'的方法'CreateObject'失败

It fails on CreateObject with the less-than helpful error Method 'CreateObject' of object 'IActCtx' failed.

sxstrace显示它读取client.manifest并创建激活上下文。进程监视器显示它访问ComTest.dll并在注册表中搜索类975DC7E0-4596-4C42-9D0C-0601F86E3A1B。

sxstrace shows that it reads client.manifest and creates the Activation Context. Process Monitor shows that it accesses ComTest.dll and searches the Registry for class 975DC7E0-4596-4C42-9D0C-0601F86E3A1B.

我缺少什么?

这是.NET代码:

<ComVisible(True)>
<Guid("EB6AA207-ECC7-413B-9A9B-9D142FF2701D")>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IMain
    Function Test() As String
End Interface

<ComVisible(True)>
<Guid("975DC7E0-4596-4C42-9D0C-0601F86E3A1B")>
<ProgId("ComTest.Main")>
<ClassInterface(ClassInterfaceType.None)>
<ComDefaultInterface(GetType(IMain))>
Public Class Main
    Implements IMain
    Public Function Test() As String Implements IMain.Test
        Return "HELLO"
    End Function
End Class

我正在运行64位Windows 7。

I'm running 64-bit Windows 7.

推荐答案

要使用免注册COM,服务器(程序集)和客户端都必须位于同一文件夹中。请参阅:

To use registration-free COM, both the server (the assembly) and the client need to be in the same folder. See:

http: //msdn.microsoft.com/zh-CN/magazine/cc188708.aspx

这篇关于无法从VBA获得免注册COM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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