2010-12-18 104 views
2

我已经创建了一个标记有ComVisible特性级:的Silverlight 4和COM互操作

[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”),并在普通C#控制台应用程序中调用Activator.CreateInstance(Type.GetTypeFromProgID(“ComClassTest.Class1”))if我将ComClassTest.dll复制到bin目录中。

我忘了什么?

回答

0

首先要做的是测试你可以从别的地方创建对象,比如VBScript。与内容创建.vbs文件: -

o = CreateObject("ComClassTest.Class1") 

如果不产生错误,则有一些特别的是SL OOB是生气与否则您的问题没有多大关系在所有的Silverlight。

考虑对您的COM代码进行以下更改。

  • 在装配级别指定ComVisible(true)通常更容易。您可以从Assembly Information对话框的项目属性的应用程序选项卡中执行此操作。您还可以让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() { } 
} 
+0

我已经做了所有您的建议,但例外的是仍然是相同的。如上所述,我可以从C#调用应用程序调用程序集 - 这不是证明它是Silverlight问题吗? – 2010-12-18 19:08:40

+0

@Papa:C#控制台应用程序未使用Silverlight代码尝试使用的“IDispatch”OLE自动化接口。我答案中的单行VBScript是否成功? – AnthonyWJones 2010-12-18 22:11:47

+0

我有同样的问题;测试了你的vbs脚本(运行在bin/Debug/DLL项目中),但它给了我:第1行,char 1:系统找不到指定的文件。如Papa所述,使用Activator的C#控制台应用程序可以正常工作。我在汇编级别上有ComVisible。 – gauteh 2011-01-15 18:43:29