2013-03-19 58 views
2

UPDATE:花了20多個小時試圖獲得一個簡單的示例工作後,我意識到這並不像看起來那麼簡單。文章like this揭示了「陷阱」 - 這是在Windows 7之前編寫的(它以不同方式處理清單)。我堅持將.NET程序集暴露給VBA via VSTO無法免費註冊COM從VBA工作


我做了一個簡單的COM-Visible .NET程序集,並試圖從Excel VBA中調用它。如果我在.NET構建期間「註冊COM Interop」,我可以成功從VBA調用它。

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

但是,我想免費註冊。

每提醒更新從漢斯:

我未選中註冊爲COM Interop,我app.Manifest設置爲:

<?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」 是這樣的:

<?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:

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上失敗,並且出現的錯誤號爲Method 'CreateObject' of object 'IActCtx' failed

sxstrace顯示它讀取client.manifest並創建激活上下文。 Process Monitor顯示它訪問ComTest.dll並在註冊表中搜索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

+0

使用clrClass而不是comClass。 – 2013-03-20 00:32:07

回答

0

要使用免註冊COM,服務器(組裝)和客戶端需要位於同一個文件夾中。參見:

http://msdn.microsoft.com/en-us/magazine/cc188708.aspx

+0

即使我將所有內容複製到我的Office12文件夾(EXCEL.exe所在的位置)並從此處運行,我也會得到該錯誤。 – nunzabar 2013-03-19 15:37:11

+0

哦,我錯過了你試圖從VBA中使用它。好吧,我不認爲你可以在這種情況下使免註冊的COM工作,因爲這需要爲Excel創建一個應用程序清單。另外,將東西複製到應用程序的安裝文件夾似乎不是一個好主意。我認爲無reg的COM是爲了便於部署而設計的,當你是服務器和客戶端的開發者時,但當客戶端不瞭解服務器時,它不能很好地工作,因爲客戶端需要引用服務器在其應用程序清單中。 – user1610015 2013-03-19 16:00:25

相關問題