SolidWorks_PDM软件开发的技术纪要(1)

本次主要针对已完成的和部分完成的功能进行一次总结。
语言:C#,接口SW API,WINDOWS API
包括:

  1. 新建功能
  2. 红绿灯实时刷新
  3. 搜索功能
  4. 文件属性中信息提取

1.新建功能

要求:

  1. 点击“新建”按钮后,跳出选择窗口,可分别点选part、assmbly和两个对应的工程图文档,工程图新建要求为若当前激活存在零件或装配体,根据模板直接生成其对应的工程图,若无存在的零件或装配体,按模板创建xin'd。
  2. 新建的工程图应该对应零件模型,检测是否链接上模型;可以实现Sw中的参考替换功能

实现原理及代码:

  • 添加二级窗口,窗口内实现新建功能的具体需求。
    图片说明

新建零件

    //新建零件代码示例
    private void NewPart_Click(object sender, EventArgs e)
    {      
        //零件体模板路径
        string Modelpath1 = @"C:\ProgramData\SOLIDWORKS\SOLIDWORKS 2019\templates\li_part.PRTDOT";
        //NewDocument():(模板路径及名称,纸张尺寸,纸张的宽,高)[后两参数仅在纸张尺寸为自定义时设定,其余为0]
        ModelDoc2 SwPartDoc = swApp.NewDocument(Modelpath1, 0, 0, 0);
        SwPartDoc.Visible = true;
        MessageBox.Show("新建文档成功,当前文档名为:" + SwPartDoc.GetTitle());         
    }

从零件生成工程图

        private void NewPrtDrw_Click(object sender, EventArgs e)
        {
            int IntError = -1;
            int IntWarning = -1;
            object Nothing = "";
            string Modelpath1 = @"C:\ProgramData\SOLIDWORKS\SOLIDWORKS 2019\templates\li_part.DRWDOT";
            ModelDoc2 swDoc = swApp.ActiveDoc;
            if (swDoc != null)
            {
                //当前文件的名称
                string filepath = swDoc.GetPathName();

                //获取新newfilepath
                string NewFileath = filepath.Substring(0, filepath.LastIndexOf(@"."))+".SLDDRW";
                MessageBox.Show(NewFileath);

                //打开模板并保存
                //NewDocument():(模板路径及名称,纸张尺寸,纸张的宽,高)[后两参数仅在纸张尺寸为自定义时设定,其余为0]
                ModelDoc2 SwPartDrwDoc = swApp.NewDocument(Modelpath1, 0, 0, 0);
                SwPartDrwDoc.Extension.SaveAs(NewFileath, 0, 1, Nothing, ref IntError, ref IntWarning);  
                ModelDoc2 SwDrwDoc=swApp.OpenDoc6(NewFileath, (int)swDocumentTypes_e.swDocDRAWING, (int)swOpenDocOptions_e.swOpenDocOptions_LoadModel, "", ref IntError, ref IntWarning);

                Sheet swSheet = ((DrawingDoc)SwDrwDoc).GetCurrentSheet();
                MessageBox.Show("预定义" + swSheet.GetName());

                //InsertModelInPredefinedView() 在当前激活的sheet下的预定义的视图插入模型***
                bool status = ((DrawingDoc)SwDrwDoc).InsertModelInPredefinedView(filepath);
                MessageBox.Show("从零件体到工程图"+status.ToString());
            }
            else 
            {
                MessageBox.Show("无打开的Part文档!");
                //NewDocument():(模板路径及名称,纸张尺寸,纸张的宽,高)[后两参数仅在纸张尺寸为自定义时设定,其余为0]
                ModelDoc2 SwPartDrwDoc = swApp.NewDocument(Modelpath1, 0, 0, 0);
                SwPartDrwDoc.Visible = true;
                MessageBox.Show("新建文档成功,当前文档名为:" + SwPartDrwDoc.GetTitle());        
            }
        }

工程图的参考替换

        //工程图---文档参考源替换测试,需要查找,需修改的工程图,原参考的零件/装配体文档,现参考的零件/装配体文档
        //沟通更改参考方式2020/6/3
        private void ReplaceRefTest_Click(object sender, EventArgs e)
        {
            int IntError = -1;
            int IntWarning = -1;
            string ReferencingDoc = ScanFile();
            Referencing.Text = ReferencingDoc;
            Referencing.Enabled = false;
            //string ReferencingDoc = @"D:\Csharp_study\RectanglePlug\PlugBottomBox.SLDDRW";

            ModelDoc2 SwDrwDoc = swApp.OpenDoc6(ReferencingDoc, (int)swDocumentTypes_e.swDocDRAWING, (int)swOpenDocOptions_e.swOpenDocOptions_LoadModel, "", ref IntError, ref IntWarning);
            MessageBox.Show("目标文档" + ReferencingDoc);
            swApp.CloseDoc(ReferencingDoc);

            //string ReferencedDoc = @"D:\Csharp_study\RectanglePlug\PlugBottomBox.SLDPRT";
            //string NewReference = @"D:\Csharp_study\RectanglePlug\PlugTopBox.SLDPRT";

            //ReferencedDoc,原参考的文档
            string ReferencedDoc = ScanFile();
            Referenced.Text = ReferencedDoc;
            Referenced.Enabled = false;

            //NewReference,新参考的文档
            string NewReference = ScanFile();
            NewReferenced.Text = NewReference;
            NewReferenced.Enabled = false;

            swApp.ReplaceReferencedDocument(ReferencingDoc, ReferencedDoc, NewReference);
            //swApp.ReplaceReferencedDocument(ReferencingDoc, NewReference, ReferencedDoc);
            SwDrwDoc = swApp.OpenDoc6(ReferencingDoc, (int)swDocumentTypes_e.swDocDRAWING, (int)swOpenDocOptions_e.swOpenDocOptions_LoadModel, "", ref IntError, ref IntWarning);
            MessageBox.Show("参考文档" + SwDrwDoc.GetPathName());
        }
        //浏览 方法
        private string ScanFile()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            DialogResult dr = dialog.ShowDialog();//是调用openFileDialog实例

            dialog.Title = "选择文件";//选择框名称
            dialog.Filter = "所有文件 (*.*)|*.*";//选择文件的类型专为Xls表格

            if (dr == DialogResult.OK)//是判断对话框返回结果
            {
                MessageBox.Show(dialog.FileName);//弹出选择文件名信息
            }
            return dialog.FileName;
        }

2.红绿灯实时刷新

要求:
如果有SW程序正在运行,显示绿灯(常亮);没有则显示红灯(常亮)。无需点击按钮监测。且实现每1s自动刷新检测是否存在,以更新按LED指示灯。C#中使用了Button更改背景色代表LED指示灯。
图片说明 图片说明
实现原理:
检测SW进程方法,调用此方法以改变LED指示灯颜色,并将此事件加入定时器控件中,设置定时器刷新频率1s。
红绿灯

        //红绿灯按钮
        private void LED_Button_Click(object sender, EventArgs e)
        {

            bool Exist = ProcessExited();
            if (Exist == true)
            {
                LED_Button.BackColor = System.Drawing.Color.Green;
                LED_Button.Text = "Open";
            }
            else
            {
                LED_Button.BackColor = System.Drawing.Color.Red;
                LED_Button.Text = "Close";
            }
        }
        //是否有进程
        private static bool ProcessExited()
        {
            Process[] processes = Process.GetProcessesByName("SLDWORKS");
            foreach (Process process in processes)
            {
                if (process.ProcessName == "SLDWORKS")
                {
                    return true;
                }
            }
            return false;
        }

定时器

        //红绿灯定时刷新的定时器
        private void timer_LED_Tick(object sender, EventArgs e)
        {
            LED_Button_Click(sender, e);
        }

3. 搜索功能

要求:

  1. 两个listview,一个为使用当前文档的其他文档,一个为当前文档使用的其他文档(未完成)
  2. 如何在win环境下找到文件相关的其他文件;例如:如何找到当前指定文件夹下使用M6螺栓的文档(未完成)
  3. 同一个框搜索不同类型属性,根据前方的下拉栏选择搜索类型(完成)
  4. 单机listview里显示缩略图(完成)
  5. 完成单一根据属性信息搜索(部分完成,各文件下对应的system.name不一样)
    实现原理及代码:
    图片说明
    选择路径,根据类型和关键字搜索,类型底层采用字典结构,下拉栏为combbox控件。
    属性搜索需要调用windows api中shell的库类。但需注意,不同类型文件调用接口显示的system信息不同。

搜索功能关键代码,以file类搜索示例

        //搜索路径的选择,将路径存放在SearFolderPath.Text文本框
        private void SearchPath_Click(object sender, EventArgs e)
        {
            DialogResult dr = folderBrowserDialog1.ShowDialog(); //是调用文件浏览器控件;           
            if (dr == DialogResult.OK)//是判断文件浏览器控件是否返回ok,即用户是否确定选择。如果确定选择,则弹出用户在文件浏览器中选择的路径:
            {
                SearFolderPath.Text = folderBrowserDialog1.SelectedPath;
                MessageBox.Show(SearFolderPath.Text);
            }
        }

        //private enum Types {名称, 路径, 日期};
        //根据类型选择在指定文件夹下搜索,文件,并以预定义格式显示出来
        private void Search_Click(object sender, EventArgs e)
        {
            //每次搜索前移除之前所有
            SearchList.Items.Clear();
            //获得类型和搜索关键字
            string Searchtype = SearchcomboBox.SelectedItem.ToString();
            string Keyword = SearchCon.Text;
            MessageBox.Show("搜索类型:" + Searchtype + "\r\n" + "搜索关键字:" + Keyword);

            //通过类型选择,调用不同函数
            //string PublicPara = "";  此处采用每个都调用一次不同函数,其实应整合一起,此处使用的PublicPara便是为了存储,但未实现***
            switch(Searchtype)
            {
                case "名称":
                    SearchByName(Keyword);
                    break;
                case "路径":
                    SearchByPath(Keyword);
                    break;
                case "日期":
                    SearchByDate(Keyword);
                    break;

            }//switch(Searchtype)
        }

        #region 通过类型选择,调用不同的具体方法实现
        private void SearchByName(string Keyword) 
        {
            DirectoryInfo dir = new DirectoryInfo(SearFolderPath.Text);
            //实例化DirectoryInfo
            SearchList.View = System.Windows.Forms.View.Details;//定义列表显示的方式        
            //先遍历出的是子文件夹 GetDirectories()

            foreach (DirectoryInfo d in dir.GetDirectories())
            {
                if (d.Name.Contains(Keyword))
                {
                    //获取名称并添加到SearchList中
                    SearchList.Items.Add(d.Name);
                    //获取路径
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        d.FullName);
                    //获取创建时间
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        d.CreationTime.ToShortDateString());
                }
                else
                    continue;

            }
            //后遍历文件 GetFiles("*.SLDPRT") //文件类型
            FileInfo[] files = dir.GetFiles("*.*");
            foreach (FileInfo f in files)
            {
                if (f.Name.Contains(Keyword))
                {
                    //获取名称并添加到SearchList中
                    SearchList.Items.Add(f.Name);
                    //获取路径
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        f.FullName);
                    //获取创建时间
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        f.CreationTime.ToShortDateString());
                }
                else
                        continue;
            }
        }//private void SearchByName(string Keyword)


        //根据路径搜索
        private void SearchByPath(string Keyword)
        {
            DirectoryInfo dir = new DirectoryInfo(SearFolderPath.Text);
            //实例化DirectoryInfo
            SearchList.View = System.Windows.Forms.View.Details;//定义列表显示的方式 
            //先遍历出的是子文件夹 GetDirectories()
            foreach (DirectoryInfo d in dir.GetDirectories())
            {
                if (d.FullName.Contains(Keyword))
                {
                    //获取名称并添加到SearchList中
                    SearchList.Items.Add(d.Name);
                    //获取路径
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        d.FullName);
                    //获取创建时间
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        d.CreationTime.ToShortDateString());
                }
                else
                    continue;

            }
            //后遍历文件 GetFiles("*.SLDPRT") //文件类型
            FileInfo[] files = dir.GetFiles("*.*");
            foreach (FileInfo f in files)
            {
                if (f.FullName.Contains(Keyword))
                {
                    //获取名称并添加到SearchList中
                    SearchList.Items.Add(f.Name);
                    //获取路径
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        f.FullName);
                    //获取创建时间
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        f.CreationTime.ToShortDateString());
                }
                else
                    continue;
            }
        }//private void SearchByPath(string Keyword)


        //根据日期搜索
        private void SearchByDate(string Keyword)
        {
            DirectoryInfo dir = new DirectoryInfo(SearFolderPath.Text);
            //实例化DirectoryInfo
            SearchList.View = System.Windows.Forms.View.Details;//定义列表显示的方式        
            //先遍历出的是子文件夹 GetDirectories()

            foreach (DirectoryInfo d in dir.GetDirectories())
            {
                if (d.CreationTime.ToShortDateString().Contains(Keyword))
                {
                    //获取名称并添加到SearchList中
                    SearchList.Items.Add(d.Name);
                    //获取路径
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        d.FullName);
                    //获取创建时间
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        d.CreationTime.ToShortDateString());
                }
                else
                    continue;

            }
            //后遍历文件 GetFiles("*.SLDPRT") //文件类型
            FileInfo[] files = dir.GetFiles("*.*");
            foreach (FileInfo f in files)
            {
                if (f.CreationTime.ToShortDateString().Contains(Keyword))
                {
                    //获取名称并添加到SearchList中
                    SearchList.Items.Add(f.Name);
                    //获取路径
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        f.FullName);
                    //获取创建时间
                    SearchList.Items[SearchList.Items.Count - 1].SubItems.Add(
                        f.CreationTime.ToShortDateString());
                }
                else
                    continue;
            }
        }//根据日期搜索private void SearchByDate(string Keyword)
        #endregion

缩略图相关代码

        #region 缩略图相关代码
        //单击选中后显示缩略图方法
        private void SearchList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (SearchList.SelectedItems != null && SearchList.SelectedItems.Count > 0)
            {
                //获取文件的完整路径fullname
                string File = SearchList.SelectedItems[0].ToString();
                MessageBox.Show(File);
                string subfile = File.Substring(File.LastIndexOf("{") + 1, File.Length - 1 - (File.LastIndexOf("{") + 1));
                string TempPath = SearFolderPath.Text + @"\" + subfile;
                MessageBox.Show(TempPath);
                //调用子方法,显示缩略图
                ThumbnailPic(TempPath);
            }
        }

        //单击打显示缩略图测试代码
        private void pictureBox1_Click(object sender, EventArgs e)
        {
            ShellFile shellFile = ShellFile.FromFilePath(@"D:\Csharp_study\视频缓存区\5月工资明细.avi");
            Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
            pictureBox1.Image = shellThumb;
            //GetShellThumbnailImage
            /*
            int pic_size = 256;
            string path = @"D:\Csharp_study\视频缓存区\5月工资明细.avi";
            Bitmap bm = WindowsThumbnailProvider.GetThumbnail(path, pic_size, pic_size, ThumbnailOptions.None);
            pictureBox1.Image = bm;
            */
        }

        //pictureBox1中显示缩略图子方法,
        private void ThumbnailPic(string filename)
        {
            //仅可为文件file的缩略图,不显示文件夹缩略图,因此依然采用原方法
            if (Directory.Exists(filename))
            {
                ShellObject shellObject = ShellFolder.FromParsingName(filename);
                Bitmap shellThumb = shellObject.Thumbnail.ExtraLargeBitmap;
                pictureBox1.Image = shellThumb;
            }
            else if (File.Exists(filename))
            {
                ShellFile shellFile = ShellFile.FromFilePath(filename);
                Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
                pictureBox1.Image = shellThumb;
            }
            else
                return;
            /*
            //已导入shell包,不再使用此法
            int pic_size = 256;
            Bitmap bm = WindowsThumbnailProvider.GetThumbnail(filename, pic_size, pic_size, ThumbnailOptions.None);
            pictureBox1.Image = bm;
            */  
        }
        #endregion

4. 文件属性中信息提取

要求:
提取文件右键属性中的详细信息具体内容。包括标题,作者,备注,说明等具体信息。
图片说明
实现原理及代码:
采用windows api接口,调用shell库实现
部分属性提取代码测试(.jpg文件示例)

        private void PropertyInfo_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder("");
            //更换路径,读取不同文件的属性信息
            foreach (var prop in new ShellPropertyCollection(@"D:\Csharp_study\RectanglePlug\M\100001-101000\100014.SLDASM"))
            {
                string Value = string.Empty;
                Value = prop.ValueAsObject == null ? "" : prop.FormatForDisplay(
                    PropertyDescriptionFormatOptions.None);
                sb.Append(prop.CanonicalName + "=" + Value + "\r\n");
            }
            MessageBox.Show(sb.ToString());

            //GetPropertyInfo(@"D:\Csharp_study\视频缓存区\5月工资明细.avi");
        }

        //测试提取属性信息
        private void TestButton_Click(object sender, EventArgs e)
        {
            ShellPropertyCollection props = new ShellPropertyCollection(@"D:\Csharp_study\RectanglePlug\_TestFile.jpg");
            string TypeName = props.Where(prop => prop.CanonicalName == "System.Title").First().FormatForDisplay(PropertyDescriptionFormatOptions.None);
            MessageBox.Show(TypeName);
        }

图片说明