采用c#从头再开发wps插件,那么开发出来的office加载项就会出现两个。我们要实现的wps和word插件一致的功能。office加载项如图所示: 如何才能够让office和wps插件兼容呢?也就是说一个插件,既可以在word中使用,也可以在wps中使用。我做了个测试的插件wpsAddIn。上图是office下的,这个插件功能极其简单,往往简单的东西,能够直达事情的本质。 wpsAddin插件就一个Ribbon项,点击sayHello,它会向你问好。我们再来看看wps下的表现:
点击sayHello,如图: 这就是一个插件,在不同的word中,表现不同,实现的功能不同。这一切是如何做到的?且听我慢慢道来。 1 public partial class ThisAddIn 2 { 3 private object wordApplication; 4 5 6 private void ThisAddIn_Startup(object sender, System.EventArgs e) 7 { 8 9 wordApplication = this.Application; 10 11 string appName = "word"; 12 if (wordApplication.ToString().Contains("ComObject")) 13 { 14 appName = "wps"; 15 } 16 17 Console.WriteLine("现在notefirst运行在" + appName + "下"); 18 } vsto会自动帮我们生成一个重要的类:ThisAddIn,vsto的很多秘密就藏于此。当我在wps下打印 this.Application.ToString()的时候,发现了它包含ComObject字符串,而word没有。因此,我就以此来判断,用户当前打开的是office,还是wps。这不禁想起一首诗: 一片树林里分出两条路—— 而 ThisAddIn_Startup就是那片树林。如果你选择的是wps,那么插件中会调用wps的Api,选择的是word,同理。 上一篇,我们谈了插件开发原理,现在该是应用原理的时候了。工欲善其事必先利其器,首先安装wps 2016专业版,然后再开发。 第一步:打开vs2010,新建一个类库项目,项目结构如下:
说明:其中Resource1.resx是资源文件,它包括了两张png图片一个定义ribbon的txt文件。 第二步:项目生成设置 勾选com互操作注册。 第三步:设置程序集文件 打开AssemblyInfo.cs设置ComVisible为true,如图所示: 第四步:为程序集签名 第五步:准备工作做好了,现在可以安心写代码了。 添加com引用:
kingsoft Add-In Design中定义了com组件要实现的接口。 Upgrade Kingsoft Wps 3.0 公布了wps word api。 我们再看看WPSWord2016.cs中的核心代码: 1 public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom) 2 { 3 app = Application; 4 Console.WriteLine("插件已连接"); 5 } 6 public void OnStartupComplete(ref Array custom) 7 { 8 Process[] processes = Process.GetProcesses(); 9 foreach (Process process in processes) 10 { 11 if (process.ProcessName.ToLower() == "wps") 12 { 13 Console.WriteLine(process.ProcessName + "进程已启动"); 14 15 wpsapp = app as Word.Application; 16 wpsapp.DocumentBeforeClose += new ApplicationEvents4_DocumentBeforeCloseEventHandler(wpsapp_DocumentBeforeClose); 17 18 break; 19 } 20 } 21 } 22 void wpsapp_DocumentBeforeClose(Document Doc, ref bool Cancel) 23 { 24 Console.WriteLine(Doc.FullName + "wps文档将要关闭"); 25 } OnConnection的参数 Application代表了我们的应用程序,如果我们开发的是word,则代表Word.Application。 OnStartupComplete中,可以实现Application的文档相关事件,比如 DocumentBeforeClose。 第六步:生成解决方案。 com组件必须注册到注册表中,才能够使用。由于第二步的项目设置,所以这一步微软帮我们做了,接下来把插件信息写入到注册表中: 1 Windows Registry Editor Version 5.00 2 [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Word\Addins\WpsWordAddin.WPSWord2016] 3 "FriendlyName"="WpsWordAddin" 4 "Description"="wps word示例" 5 "LoadBehavior"=dword:00000003 6 "CommandLineSafe"=dword:00000001 7 [HKEY_CURRENT_USER\Software\Kingsoft\Office\WPS\AddinsWL] 8 "WpsWordAddin.WPSWord2016"="" 第七步:打开wps word查看插件是否能够正确地加载。 到这一步还不太清楚的话,可以下载源码。 上一篇,我们完成了具体的开发工作,但是最终必须得部署到客户机器上。所以,部署方面,我花费了一些时间去研究,现在总结下。上一篇中,我为什么建议开发人员安装wps专业版呢?因为装了专业版,方便我们开发,安装过程中会顺便把 office PIA安装到GAC中。否则,我们还得手动安装PIA,这个过程极其繁琐。 啥是PIA?说白了,就是office 或者wps提供给开发者的接口,学名叫互操作集。也就是说c#代码与office组件之间的交互。互操作集通过api,公布了word对象模型,供我们代码使用。 如果说客户机器上没有PIA,怎么安装呢?首先我们开发人员得自己生成PIA,然后部署到客户机器上,那么当前任务就是如何生成PIA? 打开vs 命令行:
执行TlbImp命令: 其实这一步是从com中导出到公共语言运行库程序集,它们保持了相同的方法定义。注意:etapi.dll 是wps的Excel组件,wpsapi.dll 是wps的word组件,会生成word.dll,根据自己需要导出,还有一个ksoapi.dll 是wps office组件,会生成office.dll。 导出后,接下来需要添加到GAC中。 什么是GAC?从程序的角度理解,那就是共享的程序集池。当然微软开发的很多dll,它的共享程度是最高的,所以把那些dll直接安装到GAC中了。我们刚才生成的word.dll要加入GAC,还必须得满足一个条件:强签名。这个导出的word.dll没有签名,怎么办呢?想办法签名吧。 经过以下3步即可签名: 1、第一步:生成随机密钥对
2.首先采用反汇编工具ildasm生成中间语言。 ildasm word.dll /out:word.il 生成的结果包括myTest.il文件和myTest.res文件 3.采用汇编工具ilasm重新生成我们自己的dll文件 ilasm /dll /res:word.res /key:wpsAddIn.snk word.il /out:word1.dll 签了名后,通过下面批处理方式添加到GAC中: @SET GACUTIL="C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\gacutil.exe" %GACUTIL% -i D:\mywork\word.dll 如果用户安装的是wps 2016的专业版,那么上面的步骤全部可以省略。注意:要安装.net framwork,我们是用c#开发的插件。 接下来要做的事情是 1、注册我们自己写的com组件 2、把插件信息写入注册表 我写了个批处理文件: @echo off echo import reg @set baseDir="D:\mywork\WordAddInTest2010\WpsWordAddin\WpsWordAddin\install\bin" regedit /s D:\mywork\WordAddInTest2010\WpsWordAddin\WpsWordAddin\install\bin\myreg.reg pause myreg.reg文件: Windows Registry Editor Version 5.00 插件运行截图: 点击测试,会在文档中写入文字和插入图片。 |
|