通过VB.net进行Word自动化时避免跨进程调用

时间:2010-10-05 21:46:48

标签: vb.net ms-office com-interop cross-process

简短版 我在VB.net和VSTO中有一个Word Addin通过Word.COMAddins.Object公开COM兼容对象,因此addin功能可以被称为外部到Word,而不会访问Word本身是跨进程的。

该技术在VB6中有效,但是使用VB.net,它仍然可以工作,但它比通过任务窗格直接从插件运行的相同代码要慢得多,好像这些调用都是跨进程的是。 X

长版 这个插件基本上对Word文档进行了大量处理。 插件可以通过两种方式运行。

  1. 在Word中,使用任务窗格
  2. 外部,通过一组类 暴露给COM(因为我必须 提供对功能的访问 到VB6客户端应用程序。
  3. 但是,这就是问题。任何曾经完成Word自动化的人都知道,使用Word运行完全可接受的INPROC代码(在这种情况下是Word本身加载的ADDIN实例),通常会在进程(或交叉进程)之外缓慢地运行。

    此应用程序也不例外。

    在很久以前,我利用一个方便的手段来规避这个问题。

    1. 像往常一样创建Word Addin
    2. 通过电子曝光物体 Word.COMAddin.Object属性 将允许外部代码访问您的 插件。
    3. 在您的外部项目中,而不是 直接操纵Word,使用 Application.COMAddins集合, 找到你的插件,检索 暴露COMAddin.Object属性 从它然后调用一个方法 那个完成工作的对象。
    4. 当然,对COMAddin.Object对象的调用仍然是跨进程的,但是,一旦执行在使用Word的IN PROCESS中,你的插件现在可以执行它想要的所有Word对象操作并且它很快因为那时候他们都在进行中。

      这适用于VB6 COM时代。

      但是,我将这个VB.net vsto addin放在一起,并通过VSTO的Connect对象的RequestComAddInAutomationService函数公开我的addin对象

      我可以在外部调用我的插件,它们都完全像我期望的那样工作,除非它们都是+慢+,非常像调用Word仍在执行跨进程,即使代码生成这些对Word的调用是由Word加载进程的加载DLL的一部分!

      并且因为大约10比1而缓慢;通过任务窗格直接从ADDIN运行需要3秒才能运行,从外部代码通过COMADDIN.object对象调用时需要大约30秒运行。

      我猜我在.net APPDOMAINS或其他什么问题上遇到了某种问题,而且真正的+构成了.net中的跨进程调用,但到目前为止我什么都没找到,甚至暗示这种情况事情。

      我的下一步,除了一些神秘的洞察力,将编写一个repro,由于游戏中元素的剪切数量,这可能会变得棘手。

      有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我用VSTO Word添加了相同的观察结果。我想在此处添加:当您将过程作为点击处理程序添加到按钮时:

`this.testButton.Click + = new Office._CommandBarButtonEvents_ClickEventHandler(YourProcedure);'

并在“YourProcedure”中实施昂贵的程序,您可以使用

调用Word的UI线程

this.testButton.Execute();

这也不是一个优雅的解决方案,但如果碰巧在CommandBar中准备好按钮,这可能很有用。

答案 1 :(得分:0)

不幸的是,Thorben提到的Event钩子技术对我的特殊情况不起作用。

所以我用评论中提到的解决方法结束了这个问题,我将在这里重复...

嗯,不是一个完美的解决方案,但我找到了+ a +解决方案。它涉及一个计时器,所以它绝对不是最理想的,当插件由Word加载时(即在STARTUP事件期间),初始化一个计时器(一个WINFORMS计时器,而不是一个线程计时器),并将它的间隔设置为500。代码通过COMADDIN.OBject属性连接到addin,并调用addin,设置一个变量标志,由计时器轮询。当计时器看到它设置时,它会重置标志并执行操作。

这不是我喜欢的干净解决方案,但它实现起来相当容易,事后容易理解,它绝对避免了xprocess COM调用到Word的速度减慢。