.Net COM + из проекта .Net: System.IO.FileNotFoundException

Я написал компонент .Net, который работает в приложении COM +. Компонент наследуется от ServicedComponent и помечен для запуска как серверный процесс (потому что мне нужно поддерживать статические данные посредством активации от нескольких потребителей).

Регистрация осуществляется с помощью RegAsm.exe:

c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase MyObject.dll

Приложение COM + было создано вручную, а компонент добавлен после создания.

Если я создаю экземпляр своего компонента из PHP, код работает так, как ожидалось: экземпляр создается в отдельном процессе, который указан в консоли служб компонентов.

<?php
    $obj = new COM("MyObject.Sender");
    $obj->SendMessage("Hello world");
?>

Однако, когда я пытаюсь создать экземпляр компонента из тестового исполняемого файла .Net, я получаю исключение «Невозможно создать компонент ActiveX»:

Try
    Using gw = CreateObject("MyObject.Sender") 'Exception thrown HERE
        Dim gwsender As IMsgSender = gw
        gwsender.SendMessage("Hello world")
    End Using
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Исполняемый файл теста - это простое приложение WinForm.

Настроив отладчик на остановку при всех исключениях, я смог получить следующие MDA:

Сборка с именем MyObject была загружена из файла: /// c: /MyObject/bin/Debug/MyObject.dll с использованием контекста LoadFrom. Использование этого контекста может привести к неожиданному поведению при сериализации, приведении типов и разрешении зависимостей. Практически во всех случаях рекомендуется избегать контекста LoadFrom. Это можно сделать, установив сборки в глобальном кэше сборок или в каталоге ApplicationBase и используя Assembly.Load при явной загрузке сборок.

Чего я и ожидал, потому что он был зарегистрирован с использованием / CodeBase вместо использования GAC. Но потом:

Сборке с отображаемым именем MyObject не удалось загрузить в контексте привязки LoadFrom домена приложения с идентификатором 1. Причина сбоя: System.IO.FileNotFoundException: не удалось загрузить файл или сборку MyObject, версия = 1.0 .0.0, Культура = нейтральный, PublicKeyToken = 92a84ff3d67c82b9 'или одна из его зависимостей. Система не может найти указанный файл.

Компонент MyObject (который отлично загружается при вызове из PHP) не имеет особых зависимостей (только .Net). При отслеживании с помощью монитора процессов sysinternal я не видел, чтобы что-то выходило из строя, и доступ к моей .dll прошел успешно (CreateFileMapping, Load Image и т. Д.). Не похоже, что это проблема доступа к файлу, но некоторая проверка во время выполнения, сделанная фреймворком.

И тестовый клиент .net, и компонент COM + были скомпилированы из одного компилятора; все соответствующие параметры выглядят одинаково (платформа установлена ​​на x86, .Net Framework 4). В качестве дополнительной меры отладки я записываю версию фреймворка в файл как в компоненте, так и в тестовой программе, хотя они одинаковы (4.0.30319.34209). Все работает на одной машине.

Журнал Fusion предполагает, что среда выполнения пытается загрузить двоичный файл напрямую (без вызова экземпляра COM +).

Мне нужно это запутанное взаимодействие (.Net -> COM + ->. Net) по устаревшим причинам, но я не могу заставить его работать. Что могло случиться?


person Guillermo Prandi    schedule 23.10.2015    source источник


Ответы (1)


Оказывается, регистрация с помощью RegAsm.exe не является правильной процедурой для этой операции. Сначала необходимо добавить сборку в GAC, а затем создать приложение COM + с помощью утилиты regsvcs. В противном случае .Net вообще не заглядывает в каталог COM +:

"c:\Windows\Microsoft.NET\Framework\v4.0.30319\regsvcs.exe" MyObject.dll
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe" /i MyObject.dll

Примечание: путь утилит в вашей системе может быть другим.

person Guillermo Prandi    schedule 23.10.2015