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

Posted

技术标签:

【中文标题】如何使用 C# 关闭 Autocad 中的文件以保持 acad.exe 运行?【英文标题】:How to close a file in Autocad using C# keeping acad.exe running? 【发布时间】:2013-07-18 11:33:41 【问题描述】:

我正在使用 Visual Studio 2010,并且我有一个想要在 Autocad 中打开的 .DWG 文件。到现在我都用过这个。

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();
    

【问题讨论】:

【参考方案1】:

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

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

您可以找到很多关于此的文章,并且可以提出更多问题。

【讨论】:

【参考方案2】:

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

处理中: acdbmgd.dll acmgd.dll

COM互操作: Autodesk.Autocad.Interop.dll Autodesk.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();

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

【讨论】:

我正在处理它,它只是打开文件,出现一个无休止的异常“WindowsFormsApplication1.exe 中发生'System.InvalidCastException' 类型的第一次机会异常” 特雷摩尔是完全正确的。 COMInterop 接口完成了这项工作。请务必使用正确的平台 dll(win-32 或 x64)【参考方案3】:

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

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

【讨论】:

任何代码都会非常有帮助,因为我在过去几个小时内一直在尝试处理它,但一切都徒劳无功。谢谢 ...几分钟的搜索让我找到了这个,这看起来是个不错的起点:docs.autodesk.com/ACD/2011/ENU/filesMDG/… 我不认为你可以做很多事情。您可以立即重新启动该过程,以便为下一个文件做好准备。【参考方案4】:

此外,您不应该使用 Kill,除非进程变得无响应,当然不能在 CloseMainWindow 之后立即使用。

CloseMainWindow 是要求应用程序自行关闭的礼貌方式。杀死就像从插座中拔出电源线。您没有给它机会自行清理并干净退出。

【讨论】:

【参考方案5】:

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

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

使用它,您可以发送击键来模拟用户使用菜单命令关闭文件。

【讨论】:

它就像魔术一样工作,不需要做太多.. 只需输入一行就可以了 谢谢。 :-):-):-):-):-) 并且该行是 SendKeys.SendWait("^F4");【参考方案6】:

要关闭文件,最好的方法是按照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);
                        
                    
                

【讨论】:

检查答案并尝试一下,它无疑是一个更好的选择,我最终使用了它。

以上是关于如何使用 C# 关闭 Autocad 中的文件以保持 acad.exe 运行?的主要内容,如果未能解决你的问题,请参考以下文章

C#语言对AutoCAD二次开发

求助。。。C#打开dwg文件问题

C# 中的开源 cad 绘图(dwg)库 [关闭]

如何通过 .NET API 打开 AutoCAD 2015

基于C#实现DXF文件读取显示

读取 .DXF 文件 [关闭]