明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3834|回复: 4

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

[复制链接]
发表于 2010-2-6 23:03:00 | 显示全部楼层 |阅读模式

由于用户的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[1];
            par[0] = 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[1] { 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["AutoCADVer"].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[1];
            par[0] = 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[2];
            LinePar[0] = new double[] { 10, 20, 0 };
            LinePar[1] = new double[] { 120, 190, 0 };
            object objLine = objModel.GetType().InvokeMember("AddLine", BindingFlags.InvokeMethod, null, objModel, LinePar);
            System.Type  typeLine = objLine.GetType();
            object length = objLine.GetType().InvokeMember("Length", BindingFlags.GetProperty, null, objLine, null);
            object[] CirPar = new object[2];
            CirPar[0] = new double[] { 3, 70, 0 };
            CirPar[1] = 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[3];
            TxtPar[0] = "CAD" + CADVer + "Reflect Success!";
            TxtPar[1] = new double[] { 0, 0, 0 };
            TxtPar[2] = 23;
            object objTxt = objModel.GetType().InvokeMember("AddText", BindingFlags.InvokeMethod, null, objModel, TxtPar);
            object layer = objLine.GetType().InvokeMember("Layer", BindingFlags.GetProperty, null, objTxt, null);
        }
    }
}

评分

参与人数 1威望 +1 明经币 +1 收起 理由
雪山飞狐_lzh + 1 + 1 【好评】表扬一下

查看全部评分

 楼主| 发表于 2010-2-6 23:04:00 | 显示全部楼层

另外还有配置文件App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>

    <!--Excel版本-->
    <!--注意:value=后面填写2003或2007>-->
    <add key="ExcelVer" value="2003" />


    <!--AutoCAD版本-->
    <!--注意:value=后面填写2004至2009的其中一个-->
    <add key="AutoCADVer" value="2006" />
   
   
    </appSettings>
</configuration>

发表于 2010-2-7 11:30:00 | 显示全部楼层
Com的反射C#很痛苦,呵呵,建议用VB.Net或C#4.0
 楼主| 发表于 2010-2-8 12:46:00 | 显示全部楼层
C#4.0怎么设置呢?在VS2008里面可以选择吗?还是要用VS2010呢?
发表于 2010-2-8 13:33:00 | 显示全部楼层

只能用VS2010,:)

C#4.0的自动反射,代码要简单多了,呵呵

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 20:27 , Processed in 0.180603 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表