分享

关于.net:无法从VBA实例化用C#编写的COM对象(VB6正常) | 码农家园

 F2967527 2022-10-18 发布于北京

使用VS 2008,这是我的COM对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestCom
{    
    [Guid('9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E')]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ProgId('Test9.COMINT')]
    public class TestComClass  
    {
        public void Init(string userid, string password)
        {
            MessageBox.Show(string.Format('{0}/{1}', userid, password));
        }      
    }
}

如果我构建此文件并将其注册到生产机器上,如下所示

1
REGASM /CODEBASE TESTCOM.DLL

从简单的VB6应用程序可以正常工作

1
2
3
4
5
Private Sub Form_Load()
  Dim o As Object
  Set o = CreateObject('Test9.COMINT')
  o.Init'A','B'
End Sub

与Excel中的VBA调用的代码完全相同,

'automation error' (0x80131700)

一切都可以在开发计算机上正常运行,而不能在仅安装.NET和MS Office的生产计算机上运行。

更新资料

我认为这与在Excel下运行时未正确初始化.NET框架有关。 如果我使用Filemon,可以看到它在寻找MSCORWKS.DLL时跳过了。 当我从VBScript调用同一对象时,它发现MSCorwks.dll很好。

当我从VBA调用CorBindToCurrentRunTime尝试强制加载CLR时,有趣的是,我得到了与在VBA中执行CreateObject()时完全相同的HRESULT (0x80131700)

因此,我认为这是一个框架初始化问题。

  • 我只是经过尝试并重现了它,并且在我的机器上也可以正常工作。 希望我能提供更多帮助
  • 因为您的计算机具有Visual Studio等,所以我敢打赌。 如果有解决方案,我一定会在这里发布。 谢谢大家的时间。
  • @ rc1:太好了……Sysinternals为另一天节省了一天! :)

我将回答我自己的问题,希望可以使其他人摆脱我刚刚经历的繁琐繁琐的工作。

如果得到这个,那是因为基于.NET的COM程序集找不到.NET框架

解决方案很简单。创建一个包含以下内容的文件

1
2
3
4
5
6
<?xml version='1.0'?>
<configuration>
  <startup>
   <supportedRuntime version='v2.0.50727'/>
  </startup>
</configuration>

命名为' Excel.Exe.Config',并将其放置在与' EXCEL.EXE'相同的目录中

问题解决了!

  • 美好永远不会猜到
  • 我不建议这样做,特别是对于真正的已部署应用程序(即,请不要在用户计算机上部署Excel.exe.config文件!)。 Excel是您并不真正拥有的共享应用程序主机-此配置文件更改了所有托管代码在Excel中的工作方式。这将破坏任何不使用CLR 2.0的托管Excel加载项。通过正确的注册(检查对象的CLSID注册表项下的CLR版本)和/或CLR加载填充程序,您应该能够获得相同的效果。

安装以下修复程序将解决此问题
http://www.microsoft.com/downloads/details.aspx?FamilyID=1b0bfb35-c252-43cc-8a2a-6a64d6ac4670&displaylang=en


RC1,我用VBScript和Office 2007的Excel中的代码对它进行了测试,一切正常。

由于您能够从VB6表单中创建COM对象,因此我们应该假定您的.net框架还可以。您可以排除VBA的问题吗?您可以创建一个.vbs文件并将其放入其中吗:

1
2
3
Dim o As Object  
Set o = CreateObject('Test9.COMINT')  
o.Init'A','B'

保存文件,然后双击它。如果您遇到错误,那么我认为它正在注册存在问题,如果您没有错误,那么我将查看Office和VBA,看看是否缺少某些东西或未正确安装。

另一个选择是添加对COM对象的引用并使用早期绑定吗?我认为您可能需要首先导出一个类型库,但是您应该能够添加一个引用并简单地将对象新添加起来。

  • 在VBScript中也能正常工作(需要丢失as对象),我刚刚围绕C#com对象创建了VB6 COM DLL包装器。 Excel可以很好地实例化该DLL,并调用其自己的方法,但是当该VB6 DLL依次调用C#对象中的方法时,我再次遇到'自动化错误'。
  • ...所以似乎与Excel运行有关的问题

rc1是正确的,因为这是一个.net错误,当Office无法确定要使用哪个版本的Framework时引发。但是,Office并不是仅仅因为它被宠坏了而引发混乱。 Office 2003与.net 2.0交互的方式存在一个错误。

与强制Excel在特定版本的.net中运行相比,从Microsoft(KB908002)安装此修补程序是解决问题的更灵活的方法。

另请参阅:http://www./guide/trouble_shoot_microsoft_office_2003.php


从VBA对我来说这是有效的...我使用Word&Excel 2003(SP3)进行了尝试。

我不确定您所说的'生产'机器是什么意思。因为这是一个'客户端'应用程序,必须使用Excel在客户端上执行。

如果您要在服务器上自动执行Excel并通过VBA调用触发此'互操作',那么您会遇到麻烦:)

假设按生产,您的意思是用户将使用Excel模板/ doc的客户端计算机,这些是以下指针:

  • 确保您拥有合适的.Net框架
  • 您拥有Office的最新Service Pack
  • 尝试确定这是否是供股问题。
  • 如果您喜欢冒险,可以使用[来自Microsoft sysinternals网站的]进程浏览器查看DLL加载的是什么以及您在哪里得到错误,并将其与开发框上的列表进行比较。

    希望这可以帮助。

    • 谢谢维斯。是的,对于生产机器,我只是指具有Office和.NET的最终用户机器,而没有Visual Studio等。它是否可以在类似的机器上工作?您可以共享一些代码吗?谢谢!

      本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
      转藏 分享 献花(0

      0条评论

      发表

      请遵守用户 评论公约

      类似文章 更多