Chinaunix首页 | 论坛 | 博客
  • 博客访问: 874731
  • 博文数量: 372
  • 博客积分: 10063
  • 博客等级: 中将
  • 技术积分: 4220
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 11:36
文章分类

全部博文(372)

文章存档

2012年(372)

分类: 虚拟化

2012-04-19 11:58:39

通常的场景是我们用VSTO创建了一个office应用程序,里面用托管代码定义了一些方法,我们想通过外部程序打开该VSTO程序,获取VSTO对象引用,然后调用这些方法,以达到控制Office文档的目的。 直接获取失败

  以下代码试图从外部程序获取VSTO对象引用,然而失败了!

using System; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Threading; using Microsoft.Office.Tools.Excel.Extensions; using IExcel = Microsoft.Office.Interop.Excel; using TExcel = Microsoft.Office.Tools.Excel; namespace ClientApplication { class Program { static int Main(string[] args) { /* To avoid any problem (exception of type "Invalid format") when manipulating the * workbook, we'll specify here the culture en-US to avoid forcing the client to * have a language pack for excel */ Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); //Get the application and set it visible (ie, seeing the excel front end) IExcel.Application application = new IExcel.Application(); application.Visible = true; //Let's create the path to the file and then : open it string basePath = @"D:\Projects\PDA - Blog\Blog Research\VSTO - WCF\ServerApplication"; string fileName = "ServerApplication.xlsx"; IExcel.Workbook book = application.Workbooks.Open(Path.Combine(basePath, fileName), Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); /* Let's now use the .NET 3.5 SP1 functionality to convert an interop * object to a VSTO object * As it is an extension method, we could also use * TExcel.Workbook workbook = book.GetVstoObject(); */ TExcel.Workbook workbook = WorkbookExtensions.GetVstoObject(book); //Let's now check that the conversion did work Debug.Assert(workbook != null, "The conversion to VSTO did not work"); //It will fail ! return 0; } } }

  也就是说我们从VSTO程序外部,试图获取的VSTO对象总是为空!

原因其实很简单:

  我们在试图获取另一个进程中的对象引用,而一个进程是不可以直接访问另一个进程的内存空间的。这个道理我们都知道,我们对进程间通讯的方法也耳 熟能详,什么消息发送、命名管道、匿名管道、共享内存和Socket等。令我们不解的往往是:既然能取得Interop的Appliction、 WorkBook等对象,为什么不能取得托管的VSTO对象呢?如果我们了解COM就不难理解了,.net与office的Com的互操作其实也是进程间 的一种通信机制,只不过是通过COM组件掩盖了底层的通信机制,看来进程间通信的最高境界就是通过COM组件的方式。也就是说Interop的 Appliction等对象是由COM接口公开出来的,本例中后台其实启动了一个Excel进程作为COM服务器,我们的外部程序,本例中的命令行程序充 当了一个COM客户端。而我们的VSTO对象没有公开为COM可见的形式。

如何实现从外部调用VSTO程序的托管方法呢?

  答案就是使用进程间通信,有兴趣的可以参考这篇文章:http://www.pedautreppe.com/post/How-can-we-manipulate-the-VSTO-objects-when-opening-a-VSTO-document-from-command-line-.aspx  ,是通过.net remoting实现的。

阅读(1117) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~