none
免注册COM部署过程中的问题 RRS feed

  • 问题

  • 项目需要用到免注册COM 技术来进行部署。 

    参照 使用 ClickOnce 部署 COM 组件 试着配置了一下,遇到两个个问题: 

    问题一: 

    文章中提到: 

    [每个应用程序只能隔离一次 COM 组件。例如,不能从作为同一应用程序的组成部分的两个不同“类库”项目隔离同一 COM 组件。这样做将导致生成警告,运行时应用程序将无法加载。为避免此问题,Microsoft 建议您在单个类库中封装 COM 组件。] 

    我的程序中,有两个不同的项目(A和B)同时使用了一个COM组件,为了解决这个问题,我做了如下尝试: 

    1,保留项目A中对这个COM组件的引用,在A中新定义了一个这个COM组件中类的子类(public class DHTMLEditSon:DHTMLEdit)。 

    2,在项目B中删除这个COM组件的引用,添加对项目A的引用,代码里使用到COM组件类的地方,都用项目A中的DHTMLEditSon代替。 

    这样做以后,项目A可以编译成功,项目B编译时,VisualStudio报告如下错误: 

     

    类型“AxDHTMLEDLib.AxDHTMLEdit”在未被引用的程序集中定义。必须添加对程序集“AxInterop.AxDHTMLEDLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”的引用。 

     

    这可能是[单个类库中封装 COM 组件]的方法不对,请问[单个类库中封装 COM 组件]是指什么,具体的做法是什么,有相应的例子吗? 

     
     

    问题二: 

    程序的一个类库项目中使用了SWFScout.dll和SWFScoutImgAddon.dll需要付费注册的COM组件,按照文章中的步骤配置, 

    成功编译后注销SWFScout.dll和SWFScoutImgAddon.dll 组件, 

    并在 Visual Studio IDE 之外运行程序在执行用到此组件的操作时,程序报错,然后调查程序的日志,发现下面这个错误: 

     

    无法将类型为“SWFScout.FlashMovieClass”的 COM 对象强制转换为接口类型“SWFScout.IFlashMovie”。此操作失败的原因是对 IID 为“{F380B108-C702-431F-AF30-5C426D26A8F8}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 不支持此接口 (异常来自 HRESULT:0x80004002 (E_NOINTERFACE))。  

     

    根据日志,找到代码中报错的位置,是在对收费组件进行认证并初始化的函数中出错: 

     

    SWFScout.FlashMovie Movie = new SWFScout.FlashMovie(); 

    Movie.InitLibrary("xxx", "yyy"); 

    xxx和yyy是认证用的信息 

     

    程序中在SWF以外,还有别的COM组件按照同样的步骤都可以成功部署,所以猜测SWF是不是比较特殊,认证的位置出错,可能是因为需要认证这个原因吗?面注册COM组件的部署对认证有什么特殊要求吗?[无法将类型为“SWFScout.FlashMovieClass”的 COM 对象强制转换为接口类型“SWFScout.IFlashMovie”]这个错误发生的原因可能有哪些?请尽可能提供与此相关的任何信息。 



    • 已编辑 dltenda 2012年12月19日 6:41
    2012年12月18日 9:36

答案

  • 程序中已经有一个项目引用这个DLL了,若这个项目也引用,就违反了文章中:

    不能从作为同一应用程序的组成部分的两个不同“类库”项目隔离同一 COM 组件。

    结果就是:

    这样做将导致生成警告,运行时应用程序将无法加载。

    我通过子类的方法已经知道不可行了,现在想知道

    请问[单个类库中封装 COM 组件]是指什么,具体的做法是什么,有相应的例子吗? 

    谢谢。

    public NewClass

    {

    private AxDHTMLEDLib.AxDHTMLEdit _axDHTMLEdit;

    }

    大概就是这个样子,注意 NewClass 的 public 修饰的成员不能是来自 AxDHTMLEDLib.AxDHTMLEdit  的类型。

    • 已标记为答案 dltenda 2012年12月19日 7:13
    • 取消答案标记 dltenda 2012年12月19日 7:17
    • 已标记为答案 Mike FengModerator 2012年12月25日 8:18
    2012年12月19日 7:04
  • 建议你先不要调用 Movie.InitLibrary("xxx", "yyy");

    先调用一个其它接口 Movie.XXXX,看看报什么错误。

    2012年12月20日 6:24

全部回复

  • 你好,

    》》我的程序中,有两个不同的项目(A和B)同时使用了一个COM组件,为了解决这个问题,

    我没看出这是个问题。

    既然是两个不同的项目,你B项目管A项目干嘛,你B项目该怎么引用就怎么引用啊。


    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    2012年12月19日 2:58
  • 组件隔离免注册后,就不能与其他程序共享了,如果需要在其他程序中也使用相同的组件,仍需要在使用的电脑上正确地注册。
    2012年12月19日 5:17
  • 隔离后的COM组件是放在各自的程序路径下的,找的时候都是在各自的当前程序路径下找,怎么就不能用了,有文档吗?有测试结果吗?

    我以上回复是基于 你认为两个程序使用的是同一位置的相同COM组件。


    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    2012年12月19日 6:05
  • 我这面的情况是,一个应用程序,里面有两个项目,

    文章中提到: 

    [每个应用程序只能隔离一次 COM 组件。例如,不能从作为同一应用程序的组成部分的两个不同“类库”项目隔离同一 COM 组件。这样做将导致生成警告,运行时应用程序将无法加载。为避免此问题,Microsoft 建议您在单个类库中封装 COM 组件。] 

    2012年12月19日 6:14
  • 类型“AxDHTMLEDLib.AxDHTMLEdit”

    这个错误应该是你封装的 NewClass 暴露了 类型“AxDHTMLEDLib.AxDHTMLEdit” 中含有的类型所致。

    2012年12月19日 6:28
  • 类型“AxDHTMLEDLib.AxDHTMLEdit”

    这个错误应该是你封装的 NewClass 暴露了 类型“AxDHTMLEDLib.AxDHTMLEdit” 中含有的类型所致。

    不好意思,原帖里有点错误,所谓的newclasss 就是DHTMLEditSon,即AxDHTMLEDLib.AxDHTMLEdit的子类。
    2012年12月19日 6:42
  • 类型“AxDHTMLEDLib.AxDHTMLEdit”

    这个错误应该是你封装的 NewClass 暴露了 类型“AxDHTMLEDLib.AxDHTMLEdit” 中含有的类型所致。

    不好意思,原帖里有点错误,所谓的newclasss 就是DHTMLEditSon,即AxDHTMLEDLib.AxDHTMLEdit的子类。

    不好意思,使用子类的方式就恰好暴露了 AxDHTMLEDLib.AxDHTMLEdit 类型,所以你需要引用相关的DLL。
    2012年12月19日 6:49
  • 程序中已经有一个项目引用这个DLL了,若这个项目也引用,就违反了文章中:

    不能从作为同一应用程序的组成部分的两个不同“类库”项目隔离同一 COM 组件。

    结果就是:

    这样做将导致生成警告,运行时应用程序将无法加载。

    我通过子类的方法已经知道不可行了,现在想知道

    请问[单个类库中封装 COM 组件]是指什么,具体的做法是什么,有相应的例子吗? 

    谢谢。

    2012年12月19日 6:59
  • 程序中已经有一个项目引用这个DLL了,若这个项目也引用,就违反了文章中:

    不能从作为同一应用程序的组成部分的两个不同“类库”项目隔离同一 COM 组件。

    结果就是:

    这样做将导致生成警告,运行时应用程序将无法加载。

    我通过子类的方法已经知道不可行了,现在想知道

    请问[单个类库中封装 COM 组件]是指什么,具体的做法是什么,有相应的例子吗? 

    谢谢。

    public NewClass

    {

    private AxDHTMLEDLib.AxDHTMLEdit _axDHTMLEdit;

    }

    大概就是这个样子,注意 NewClass 的 public 修饰的成员不能是来自 AxDHTMLEDLib.AxDHTMLEdit  的类型。

    • 已标记为答案 dltenda 2012年12月19日 7:13
    • 取消答案标记 dltenda 2012年12月19日 7:17
    • 已标记为答案 Mike FengModerator 2012年12月25日 8:18
    2012年12月19日 7:04
  • 程序中已经有一个项目引用这个DLL了,若这个项目也引用,就违反了文章中:

    不能从作为同一应用程序的组成部分的两个不同“类库”项目隔离同一 COM 组件。

    结果就是:

    这样做将导致生成警告,运行时应用程序将无法加载。

    我通过子类的方法已经知道不可行了,现在想知道

    请问[单个类库中封装 COM 组件]是指什么,具体的做法是什么,有相应的例子吗? 

    谢谢。

    public NewClass

    {

    private AxDHTMLEDLib.AxDHTMLEdit _axDHTMLEdit;

    }

    大概就是这个样子,注意 NewClass 的 public 修饰的成员不能是来自 AxDHTMLEDLib.AxDHTMLEdit  的类型。

    OK,我试试,原来所谓的封装,是指在类库项目的类中封装,谢谢!
    2012年12月19日 7:11
  • 你怎么把帖子结掉了  又开开?

    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    2012年12月20日 1:24
  • 两个问题,还有一个没有答案。。。
    2012年12月20日 5:46
  • 建议你先不要调用 Movie.InitLibrary("xxx", "yyy");

    先调用一个其它接口 Movie.XXXX,看看报什么错误。

    2012年12月20日 6:24