Silverlight 4 и COM Interop - PullRequest
       18

Silverlight 4 и COM Interop

2 голосов
/ 18 декабря 2010

Я создал класс ComVisible:

[Guid("73a3f91f-baa9-46ab-94b8-e526c22054a4"), ComVisible(true)]
public interface ITest
{
    void Foo();
}

[Guid("99f72d92-b302-4fde-89bb-2dac899f5a48"), ComVisible(true)]
public class Class1 : ITest
{
    public void Foo() { }
}

и зарегистрировал его через

regasm ComClassTest.dll /tlb:ComClassTest.tlb

в реестре.Когда я пытаюсь вызвать его в моем приложении Silverlight 4 вне браузера, с повышенным уровнем доверия, например:

var foo = AutomationFactory.CreateObject("ComClassTest.Class1");

Я получаю исключение "{System.Exception: Не удалось создать экземпляр объекта для указанногоProgID. "

Однако я могу вызывать AutomationFactory.CreateObject (" Word.Application ") без исключения и вызывать Activator.CreateInstance (Type.GetTypeFromProgID (" ComClassTest.Class1 ")) в обычном режиме.C # -консольное приложение, если я копирую ComClassTest.dll в каталог bin.

Что я забыл?

1 Ответ

0 голосов
/ 18 декабря 2010

Первое, что нужно сделать, это проверить, что вы можете создать объект из другого места, такого как VBScript. Создайте файл .vbs с содержанием: -

o = CreateObject("ComClassTest.Class1")

Если это не приводит к ошибке, то есть что-то определенно, что SL OOB расстроен, иначе ваша проблема на самом деле не связана с Silverlight.

Рассмотрите возможность внесения следующих изменений в ваш код COM.

  • Часто проще указать ComVisible(true) на уровне сборки. Это можно сделать на вкладке приложения свойств проекта в диалоговом окне «Информация о сборке». Вы также можете заставить Visual Studio зарегистрировать сборку в COM и время сборки, используя параметр, указанный на вкладке сборки свойств проекта.

  • Это хорошая идея, чтобы конкретизировать ComInterfaceType, который вы хотите раскрыть.

  • Ситуация становится действительно запутанной, если вы предоставляете интерфейс класса напрямую, как правило, вы хотите, чтобы использовался только тот интерфейс, который вы определили, и это интерфейс по умолчанию для класса. Кроме того, вероятно, лучше придерживаться соглашений об именах COM для интерфейса класса по умолчанию.

  • Наконец (и, возможно, в вашем случае это очень важно), неплохо было бы четко указать ProgId для использования в классе.

Применяя вышеизложенное, получим: -

[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("73a3f91f-baa9-46ab-94b8-e526c22054a4")]
public interface _Class1
{
    void Foo();
}

[ClassInterface(ClassInterfaceType.None)] 
[Guid("99f72d92-b302-4fde-89bb-2dac899f5a48")]
[ProgId("ComClassTest.Class1")]
public class Class1 : _Class1
{
    public void Foo() { }
}
...