gsteven 发表于 2010-2-6 23:03:00

[讨论]使用多版本Excel和CAD的应用程序

由于用户的Excel版本可能是2003、2007
CAD版本可能是2000到2010,如何比较好的实现多版本呢?并且不需要修改程序代码
以下是一个简单的利用反射实现的例子,希望大家多提意见,谢谢
(VS2008,.net framework3.5,添加了System.Configuration引用,实现2个按钮事件)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;//使用Marshal获得进程
using System.Reflection;//用于反射
using System.Configuration;//操作app.config文件
namespace SeedFileReport
{
    public partial class Main : Form
    {
      //string excelAssPath;
      //string CADAssPath;
      string ExcelVer;
      string CADVer;
      //Assembly excelAss;
      //Assembly CADAss;
      Type excelType;
      Type CADType;
      object excelApp;
      object CADApp;
      string AppPath;
      string ExcelAppProID;
      string CADAppProID;
      public Main()
      {
            InitializeComponent();
            AppPath = System.Windows.Forms.Application.StartupPath;
            //Debug文件的上一级目录,不包含斜杠\
            AppPath = AppPath.Substring(0, AppPath.LastIndexOf("\\"));
      }
      //Excel
      private void button1_Click(object sender, EventArgs e)
      {
            //修改为通过注册表来创建进程Excel.Application.11/Excel.Application.12
            ExcelVer = System.Configuration.ConfigurationManager.AppSettings["ExcelVer"].ToString();
            if (ExcelVer == "2003")
            {
                //excelAssPath = AppPath + @"\Dll\Excel\2003\Microsoft.Office.Interop.Excel.dll";
                ExcelAppProID="Excel.Application.11";
                //excelAssPath = @"C:\WINDOWS\assembly\GAC\Microsoft.Office.Interop.Excel\11.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll";
            }
            if (ExcelVer == "2007")
            {
                //excelAssPath = AppPath + @"\Dll\Excel\2007\Microsoft.Office.Interop.Excel.dll";
                ExcelAppProID="Excel.Application.12";
                //excelAssPath = @"C:\WINDOWS\assembly\GAC\Microsoft.Office.Interop.Excel\12.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll";
            }
            //excelAss = Assembly.LoadFile(excelAssPath);
            //excelType = excelAss.GetType("Microsoft.Office.Interop.Excel.ApplicationClass");
            excelType = System.Type.GetTypeFromProgID(ExcelAppProID);
            //excelApp = excelAss.CreateInstance("Microsoft.Office.Interop.Excel.ApplicationClass");
            excelApp = Activator.CreateInstance(excelType);
            object[] par = new object;
            par = true;
            excelType.InvokeMember("Visible", BindingFlags.SetProperty, null, excelApp, new object[] { true });
            excelType.InvokeMember("UserControl", BindingFlags.SetProperty, null, excelApp, par);
            //获取Workbook集
            object objBooks = excelApp.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, excelApp, null);
            //添加一个新的Workbook
            object objBook = objBooks.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, objBooks, null);
            //获取Sheet集
            object objSheets = objBook.GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, objBook, null);
            //获取第一个Sheet对象
            object[] Parameters = new Object { 3 };
            object objSheet = objSheets.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, objSheets, Parameters);
            objSheet.GetType().InvokeMember("Activate", BindingFlags.InvokeMethod , null, objSheet, null);
            
            object Cells1 = objSheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty, null, objSheet, new object[] { 1, 1 });
            Cells1.GetType().InvokeMember("NumberFormatLocal", BindingFlags.SetProperty, null, Cells1, new object[] { "@" });
            Cells1.GetType().InvokeMember("FormulaR1C1", BindingFlags.SetProperty, null, Cells1, new object[] { "反射测试" });
            //foreach (Module aaa in excelAss.GetModules())
            //{
            // Console.WriteLine(aaa.Name);    // 显示该dll下所有的类
            //}
            
            object range = objSheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, objSheet, new object[] { "B2:G8"});
                range.GetType().InvokeMember("Value", BindingFlags.SetProperty, null, range, new object[] { "反射Excel.Range成功啦!" });
                //反射枚举型
                //System.Type t1 = excelAss.GetType("Microsoft.Office.Interop.Excel.XlRangeValueDataType");
                //object[] o1s = t1.GetMembers();
                //object o1 = t1.GetMember("xlRangeValueDefault");
                //MessageBox.Show(o1.GetType().ToString());
                //range.GetType().InvokeMember("set_Value", BindingFlags.InvokeMethod, null, range, new object[] {o1, "反射B" });
                //object res = range.GetType().InvokeMember("Value", BindingFlags.GetProperty, null, range, null);
      }
      //CAD
      private void button2_Click(object sender, EventArgs e)
      {
            //获得解决方案的所有Assembly
            //Assembly[] AX = AppDomain.CurrentDomain.GetAssemblies();
            //遍历显示每个Assembly的名字
            //foreach (object var in AX)
            //{
            //    Console.WriteLine("Assembly的名字:" + var.ToString());
            //}         
            CADVer = System.Configuration.ConfigurationManager.AppSettings["Ver"].ToString();
            //修改为通过注册表来创建进程AutoCAD.Application.16/AutoCAD.Application.17
            if (CADVer == "2004")
            {
                //CADAssPath = AppPath + @"\Dll\AutoCAD\2004\Interop.AutoCAD.dll";
                //CADAssPath = AppPath + @"\Dll\AutoCAD\2006\Autodesk.AutoCAD.Interop.dll";
                CADAppProID = "AutoCAD.Application.16";
                //CADAssPath = @"C:\WINDOWS\assembly\GAC\Autodesk.AutoCAD.Interop\16.2.54.0__eed84259d7cbf30b\Autodesk.AutoCAD.Interop.dll";
            }
            if (CADVer == "2006")
            {
                //CADAssPath = AppPath + @"\Dll\AutoCAD\2006\Autodesk.AutoCAD.Interop.dll";
                CADAppProID = "AutoCAD.Application.16";
                //CADAssPath = @"C:\WINDOWS\assembly\GAC\Autodesk.AutoCAD.Interop\16.2.54.0__eed84259d7cbf30b\Autodesk.AutoCAD.Interop.dll";
            }
            if (CADVer == "2007")
            {
                //CADAssPath = AppPath + @"\Dll\AutoCAD\2007\Autodesk.AutoCAD.Interop.dll";
                CADAppProID = "AutoCAD.Application.17";
                //CADAssPath = @"C:\WINDOWS\assembly\GAC_MSIL\Autodesk.AutoCAD.Interop\17.2.0.0__eed84259d7cbf30b\Autodesk.AutoCAD.Interop.dll";
            }
            //CADAss = Assembly.LoadFile(CADAssPath);
            //if (CADVer == "2004")
            //{
            //    CADType = CADAss.GetType("AutoCAD.AcadApplicationClass");
            //}
            //if (CADVer != "2004")
            //{
            //    CADType = CADAss.GetType("Autodesk.AutoCAD.Interop.AcadApplicationClass");
            //}
            CADType = System.Type.GetTypeFromProgID(CADAppProID);
            CADApp = Activator.CreateInstance(CADType);
            object[] par = new object;
            par = true;                        
            CADType.InvokeMember("Visible", BindingFlags.SetProperty, null, CADApp, par);
            //获取Documents集
            object objDocs = CADApp.GetType().InvokeMember("Documents", BindingFlags.GetProperty, null, CADApp, null);
            //添加一个新的Document
            object objDoc = objDocs.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, objDocs, new object[]{Missing.Value});
            //获得模型空间
            object objModel = objDoc.GetType().InvokeMember("ModelSpace", BindingFlags.GetProperty, null, objDoc, null);
            object[] LinePar = new object;
            LinePar = new double[] { 10, 20, 0 };
            LinePar = new double[] { 120, 190, 0 };
            object objLine = objModel.GetType().InvokeMember("AddLine", BindingFlags.InvokeMethod, null, objModel, LinePar);
            System.TypetypeLine = objLine.GetType();
            object length = objLine.GetType().InvokeMember("Length", BindingFlags.GetProperty, null, objLine, null);
            object[] CirPar = new object;
            CirPar = new double[] { 3, 70, 0 };
            CirPar = 150;
            object objCir = objModel.GetType().InvokeMember("AddCircle", BindingFlags.InvokeMethod, null, objModel, CirPar);
            object center = objLine.GetType().InvokeMember("Center", BindingFlags.GetProperty, null, objCir, null);
            object[] TxtPar = new object;
            TxtPar = "CAD" + CADVer + "Reflect Success!";
            TxtPar = new double[] { 0, 0, 0 };
            TxtPar = 23;
            object objTxt = objModel.GetType().InvokeMember("AddText", BindingFlags.InvokeMethod, null, objModel, TxtPar);
            object layer = objLine.GetType().InvokeMember("Layer", BindingFlags.GetProperty, null, objTxt, null);
      }
    }
}

gsteven 发表于 2010-2-6 23:04:00

另外还有配置文件App.Config


   
    -->
   
   
   
   
   
   
   

雪山飞狐_lzh 发表于 2010-2-7 11:30:00

Com的反射C#很痛苦,呵呵,建议用VB.Net或C#4.0

gsteven 发表于 2010-2-8 12:46:00

C#4.0怎么设置呢?在VS2008里面可以选择吗?还是要用VS2010呢?

雪山飞狐_lzh 发表于 2010-2-8 13:33:00

只能用VS2010,:)
C#4.0的自动反射,代码要简单多了,呵呵
页: [1]
查看完整版本: [讨论]使用多版本Excel和CAD的应用程序