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

Использование 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.

Update

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

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

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

Ответ 1

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

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

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

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

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

Проблема решена!

Ответ 3

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

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

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

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

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

Ответ 4

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

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

Если вы автоматизируете Excel на сервере и запускаете этот "interop" через вызов VBA, вы просите о проблемах:)

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

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

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

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

Ответ 5

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