最近在做一个C#操作word的程序,由于word有多个版本,每个版本的com组件不一样,所以不能在项目中引用固定的com组件,只能动态调用,因此想到了之前略过的反射,各种网页搜了半天,自己写写改改,终于可以运行了。
- 首先读出注册表中的word版本
public class TestOffice { public static void GetWordVersion(out int wordVerNum, out string wordAppName) { //word版本号 wordVerNum = 0; //word应用程序名称 wordAppName = null; string str_KeyName = "Path"; object objResult = null; Microsoft.Win32.RegistryValueKind regValueKind;//指定在注册表中存储值时所用的数据类型,或标识注册表中某个值的数据类型。 Microsoft.Win32.RegistryKey regKey = null;//表示 Windows 注册表中的项级节点(注册表对象?) Microsoft.Win32.RegistryKey regSubKey = null; try { regKey = Microsoft.Win32.Registry.LocalMachine;//读取HKEY_LOCAL_MACHINE项 //office2010 if (regSubKey == null) { regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Office\14.0\Word\InstallRoot", false); wordVerNum = 14; wordAppName = "Word2010"; str_KeyName = "Path"; } //office2007 if (regSubKey == null) { regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Office\12.0\Word\InstallRoot", false); wordVerNum = 12; wordAppName = "Word2007"; str_KeyName = "Path"; } //Office2003 if (regSubKey == null) { regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Office\11.0\Common\InstallRoot", false); wordVerNum = 11; wordAppName = "Word2003"; str_KeyName = "Path"; } objResult = regSubKey.GetValue(str_KeyName); regValueKind = regSubKey.GetValueKind(str_KeyName); if (regValueKind == Microsoft.Win32.RegistryValueKind.String) { wordAppName = objResult.ToString(); } } catch (Exception ex) { throw ex; } finally { if (regKey != null) { regKey.Close(); regKey = null; } if (regSubKey != null) { regSubKey.Close(); regSubKey = null; } } } }
- 然后用反射机制加载针对不同版本编写的dll,如Word2010Operator,Word2007Operator,Word2003Operator(这些dll已经放到\bin\Debug目录下):
/// <summary> /// 因为要在所有方法执行前加载dll,所以简单的方法是创建一个实例,在constructor里面加载dll,但是这个类基本等同静态类,所以只创建一个实例就好了,就用了单例模式 /// </summary> class WordOperator { private static WordOperator singletonWordOperator = null; private static string dllPath = null; private static Type wordOperator = null; public static char nextParaMark = '`'; private WordOperator() { int wordVerNum = 0; string wordAppName = string.Empty; TestOffice.GetWordVersion(out wordVerNum, out wordAppName); switch (wordVerNum) { case 14: dllPath = "Word2010Operator.dll"; break; case 12: dllPath = "Word2007Operator.dll"; break; case 11: dllPath = "Word2003Operator.dll"; break; default: break; } if (dllPath != null) { System.Reflection.Assembly assmb = System.Reflection.Assembly.LoadFrom(dllPath); wordOperator = assmb.GetType("WordOperator.WordOperator"); } } public static WordOperator getInstance() { if (singletonWordOperator == null) singletonWordOperator = new WordOperator(); return singletonWordOperator; } /// <summary> /// 将word转换为rtf格式(因为是实例方法,不能用static啦) /// </summary> public string saveAsRtf(string sourceFilePath) { return (string)wordOperator.InvokeMember("saveAsRtf", System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, null, new object[] { sourceFilePath }); } }
- 最后再来一个Form测试小程序,测试通过!
public partial class Form1 : Form { public Form1() { InitializeComponent(); dynamicLoadDll(); } void dynamicLoadDll() { WordOperator wordOperator = WordOperator.getInstance(); string rtfPath = wordOperator.saveAsRtf(AppDomain.CurrentDomain.BaseDirectory + "word.doc"); richTextBox1.LoadFile(rtfPath); } }
本文介绍如何使用C#通过反射动态操作不同版本的Word。首先,通过读取注册表确定Word版本,然后根据版本加载对应DLL(如Word2010Operator、Word2007Operator、Word2003Operator),实现对Word的操作,例如将Word转换为RTF格式。
8594

被折叠的 条评论
为什么被折叠?



