Не удается создать экземпляр COM-объекта, написанного на C#, из VBA (VB6 в порядке)

Используя VS 2008, вот мой COM-объект

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));
        }       
    }
}

Если я соберу это и зарегистрирую на производственной машине следующим образом

REGASM /CODEBASE TESTCOM.DLL

Из простого приложения VB6 это отлично работает

Private Sub Form_Load()
  Dim o As Object
  Set o = CreateObject("Test9.COMINT")
  o.Init "A", "B" 
End Sub

Этот точно такой же код, вызываемый из VBA в Excel, дает

«ошибка автоматизации» (0x80131700)

Все отлично работает на машине разработки, но не на рабочей машине, где установлены только .NET и MS Office.

Обновлять

Я думаю, что это как-то связано с неправильной инициализацией .NET framework при работе в Excel. Если я использую Filemon, я вижу, что он пропускает поиск MSCORWKS.DLL. Когда я вызываю тот же объект из VBScript, он находит MSCorwks.dll в порядке.

Когда я вызывал CorBindToCurrentRunTime из VBA, чтобы попытаться принудительно загрузить CLR, что интересно, я получаю то же самое HRESULT (0x80131700), что и при выполнении CreateObject() в VBA.

Поэтому я думаю, что это проблема инициализации фреймворка.


person Community    schedule 17.12.2008    source источник
comment
Я только что прошел и попытался воспроизвести это, и на моей машине тоже все работает. Хотел бы я помочь больше   -  person JoshBerke    schedule 17.12.2008
comment
потому что на вашей машине есть Visual Studio и т. д., держу пари. Я обязательно напишу здесь, когда у меня будет решение. Спасибо всем за ваше время.   -  person    schedule 17.12.2008
comment
@rc1: Отлично... Sysinternals спасает день для другого! :)   -  person Vyas Bharghava    schedule 18.12.2008


Ответы (5)


Я собираюсь ответить на свой вопрос, надеюсь, избавить других от часов утомительной тяжелой работы, которую я только что пережил.

Если вы получаете это, это это потому, что сборка COM на основе .NET не может найти платформу .NET.

Решение простое. Создайте файл, содержащий следующее

<?xml version="1.0"?>
<configuration>
  <startup>
   <supportedRuntime version="v2.0.50727"/>
  </startup>
</configuration>

Назовите его «Excel.Exe.Config» и поместите в тот же каталог, что и «EXCEL.EXE».

Задача решена!

person Community    schedule 17.12.2008
comment
красиво никогда бы не догадался - person JoshBerke; 18.12.2008
comment
Я бы не рекомендовал это, особенно для реального развернутого приложения (т.е. не развертывайте файлы Excel.exe.config на компьютерах пользователей!). Excel — это общий узел приложений, которым вы на самом деле не владеете. Этот файл конфигурации меняет способ работы всего управляемого кода в Excel. Это нарушит работу любой управляемой надстройки Excel, которая не использует CLR 2.0. Вы должны быть в состоянии получить тот же эффект с правильной регистрацией (проверьте версию CLR в записи реестра CLSID вашего объекта) и/или прокладкой для загрузки CLR. - person nitzmahone; 23.06.2011

установка следующего исправления решит эту проблему http://www.microsoft.com/downloads/details.aspx?FamilyID=1b0bfb35-c252-43cc-8a2a-6a64d6ac4670&displaylang=en

person ryang    schedule 08.07.2010

RC1, я проверил это с вашим кодом из VBScript и из Excel Office 2007, все работает нормально.

Поскольку вы можете создать COM-объект из формы VB6, мы должны предположить, что ваша платформа .net в порядке. Можно ли исключить проблемы с VBA? Можете ли вы создать файл .vbs и поместить в него это:

Dim o As Object  
Set o = CreateObject("Test9.COMINT")  
o.Init "A", "B"

Сохраните файл и дважды щелкните его. Если вы получите сообщение об ошибке, то я думаю, что возникла проблема с его регистрацией, если вы не получите сообщение об ошибке, я посмотрю на Office и VBA и посмотрю, не отсутствует ли что-то или установлено неправильно.

Другой вариант — добавить ссылку на COM-объект и использовать раннее связывание? Я думаю, вам может понадобиться сначала экспортировать библиотеку типов, но вы должны иметь возможность добавить ссылку и просто создать новый объект.

person JoshBerke    schedule 17.12.2008
comment
Отлично работает и с VBScript (нужно потерять «как объект»). Я только что создал оболочку VB6 COM DLL вокруг объекта C # com. Excel может создать экземпляр этой DLL в порядке и вызвать свои собственные методы, но когда эта DLL VB6, в свою очередь, вызывает методы в объекте С#, я снова получаю ошибку автоматизации. - person ; 17.12.2008
comment
... так что, похоже, проблема связана с тем, что Excel работает - person ; 17.12.2008

Это работает для меня из VBA... Я попробовал это с помощью Word и Excel 2003 (SP3).

Я не уверен, что вы подразумеваете под «производственной» машиной. Потому что это "клиентское" приложение и должно выполняться на клиенте с помощью Excel.

Если вы автоматизируете Excel на сервере и запускаете это «взаимодействие» через вызов VBA, вы напрашиваетесь на неприятности :)

Предполагая, что под производством вы подразумеваете клиентский компьютер, на котором пользователь будет использовать шаблон/документ Excel, это следующие указатели:

  1. Убедитесь, что у вас есть соответствующая платформа .Net.
  2. Наличие последних пакетов обновлений для Office
  3. Попробуйте выяснить, не является ли это нарушением прав.

Если вы чувствуете себя авантюристом, вы можете использовать обозреватель процессов [с сайта Microsoft sysinternals], чтобы увидеть, какие библиотеки DLL загружены и где именно вы получаете сообщение об ошибке, и сравнить его со списком в вашем окне разработчика.

Надеюсь это поможет.

person Vyas Bharghava    schedule 17.12.2008
comment
Спасибо Вьяс. Да, под производственной машиной я имею в виду машину конечного пользователя с Office и .NET, но без Visual Studio и т. д. Работает ли она у вас на аналогичной машине? Вы можете поделиться кодом? Спасибо! - person ; 17.12.2008

rc1 верен в том смысле, что это является ошибкой .net, возникающей, когда Office не может решить, какую версию Framework использовать. Тем не менее, Office не шатается просто потому, что он избалован выбором. Существует ошибка в том, как Office 2003 взаимодействует с .net 2.0.

Установка исправления от Microsoft (KB908002) — более гибкий способ решения проблемы. чем заставить Excel работать в определенной версии .net.

См. также: http://www.biopdf.com/guide/trouble_shoot_microsoft_office_2003.php

person Robino    schedule 23.08.2011