如何使用C#关闭Autocad中的文件以保持acad.exe运行

本文关键字:acad 运行 exe 文件 何使用 关闭 Autocad | 更新日期: 2023-09-27 18:23:57

我使用的是visual studio 2010,我有一个.DWG文件,我想在autocad中打开它。到目前为止,我一直在使用这个。

Process p = new Process();
ProcessStartInfo s = new ProcessStartInfo("D:/Test File/" + fileName);
p.StartInfo = s;
p.Start();

但我想要的是关闭Autocad内部的文件,而不是关闭Autocad本身。(意味着atocad.exe应该保持运行)。

到目前为止,我已经使用了这个,但它关闭了acad.exe而不是文件。

foreach (Process Proc in Process.GetProcesses())
{
    if (Proc.ProcessName.Equals("acad"))
    {
        Proc.CloseMainWindow();
        Proc.Kill();
    }
}

如何使用C#关闭Autocad中的文件以保持acad.exe运行

从Autodesk站点获取Autocad.NET库(http://usa.autodesk.com/adsk/servlet/index?id=773204&siteID=123112)

然后您将能够使用ApplicationDocument类。它们将使您能够完全控制应用程序中的打开和关闭文档。

你可以找到许多关于这方面的文章,并可以提出进一步的问题。

AutoCAD确实有一个api。共有4个组件。两个用于进程中,两个用于COM。

进程中:acdbmgd.dllacmgd.dll

COMInterop:Autodesk.Autocad.Interop.dllAutodesk.Autocad.Interop.Common.dll

这是一种打开AutoCAD新实例或连接到AutoCAD现有运行实例的方法。

您需要将这些.dll加载到您的项目引用中。

using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
namespace YourNameSpace {
public class YourClass {
AcadApplication AcApp;
private const string progID = "AutoCAD.Application.18.2";// this is AutoCAD 2012 program id
private string profileName = "<<Unnamed Profile>>";
private const string acadPath = @"C:'Program Files'Autodesk'AutoCAD 2012 - English'acad.exe";
public void GetAcApp()
    {
        try
        {
            AcApp = (AcadApplication)Marshal.GetActiveObject(progID);
        } catch {
            try {
                var acadProcess = new Process();
                acadProcess.StartInfo.Arguments = string.Format("/nologo /p '"{0}'"", profileName);
                acadProcess.StartInfo.FileName = (@acadPath);
                acadProcess.Start();
                while(AcApp == null)
                {
                    try { AcApp = (AcadApplication)Marshal.GetActiveObject(progID); }
                    catch { }
                }
            } catch(COMException) {
                MessageBox.Show(String.Format("Cannot create object of type '"{0}'"",progID));
            }
        }
        try {
            int i = 0;
            var appState = AcApp.GetAcadState();
            while (!appState.IsQuiescent)
            {
                if(i == 120)
                {
                    Application.Exit();
                }
                // Wait .25s
                Thread.Sleep(250);
                i++;
            }
            if(AcApp != null){
                // set visibility
                AcApp.Visible = true;
            }
        } catch (COMException err) {
            if(err.ErrorCode.ToString() == "-2147417846"){
                Thread.Sleep(5000);
            }
        }
    }
    }
}

关闭它就像一样简单

Application.Exit();

并原谅代码。这太残忍了,这是我刚开始开发的第一个方法。。。

我怀疑您是否能够做到这一点,除非AutoCAD有一个API,您可以挂入并要求它为您关闭文件。

您的c#应用程序只能对进程(acad.exe)执行某些操作,它无法访问该进程的内部操作。

此外,除非进程没有响应,而且肯定不会在CloseMainWindow之后立即使用Kill。

CloseMainWindow是要求应用程序自行关闭的礼貌方式。杀死就像从插座里拔出电源线。你没有给它机会在它自己之后清理干净,然后干净地离开。

还有另一种可能性-只有当您的C#代码与AutoCAD进程在同一台机器上运行时,这才有效,并且不建议这样做,但是,如果您真的遇到了困难,并且准备忍受窗口切换的麻烦,您可以使用SendKeys命令将笔划发送到应用程序。

MSDN文章:http://msdn.microsoft.com/EN-US/library/ms171548(v=VS.110,d=hv.2).aspxhttp://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx

使用此功能,您可以发送按键来模拟使用菜单命令关闭文件的用户。

要执行文件的关闭,最好的方法是按照这个ObjectARX SDK for c#中的步骤,并用下面的代码更改下面的代码。

            [CommandMethod("CD", CommandFlags.Session)]
            static public void CloseDocuments()
            {
                DocumentCollection docs = Application.DocumentManager;
                foreach (Document doc in docs)
                {
                    // First cancel any running command
                    if (doc.CommandInProgress != "" &&
                        doc.CommandInProgress != "CD")
                    {
                        AcadDocument oDoc =
                          (AcadDocument)doc.AcadDocument;
                        oDoc.SendCommand("'x03'x03");
                    }
                    if (doc.IsReadOnly)
                    {
                        doc.CloseAndDiscard();
                    }
                    else
                    {
                        // Activate the document, so we can check DBMOD
                        if (docs.MdiActiveDocument != doc)
                        {
                            docs.MdiActiveDocument = doc;
                        }
                        int isModified =
                          System.Convert.ToInt32(
                            Application.GetSystemVariable("DBMOD")
                          );
                        // No need to save if not modified
                        if (isModified == 0)
                        {
                            doc.CloseAndDiscard();
                        }
                        else
                        {
                            // This may create documents in strange places
                            doc.CloseAndSave(doc.Name);
                        }
                    }
                }