当试图使用C#编写的插件打印多个文件时,AutoCAD只能处理一个文件.NET.如何解决

本文关键字:文件 解决 处理 何解决 NET 一个 AutoCAD 打印 插件 | 更新日期: 2023-09-27 17:53:41

大家好!

我写了这个代码:

// (C) Copyright 2013 by  
//
using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.PlottingServices;
using AutoCAD;
// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(AutoCAD_CSharp_plug_in2.MyCommands))]
namespace AutoCAD_CSharp_plug_in2
{
// This class is instantiated by AutoCAD for each document when
// a command is called by the user the first time in the context
// of a given document. In other words, non static data in this class
// is implicitly per-document!
public class MyCommands
{
    static String[] arquivos = new String[] 
    {
        "C:/Users/igor.okuyama/Desktop/IS-PRS-0355-2047-0453_0_001.dxf",
        "C:/Users/igor.okuyama/Desktop/IS-PRS-0355-2047-0453_0_002.dxf"
    };
    static int count = arquivos.Length;
    static String arq = arquivos[count - 1];
    void MdiActiveDocument_CommandEnded(object sender, CommandEventArgs e)
    {
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("'n count:" + count.ToString() + "  " + e.GlobalCommandName + "'n");
        if (e.GlobalCommandName == "CONVERSOR")
        {
            //((AcadDocument)Application.DocumentManager.MdiActiveDocument.GetAcadDocument()).SendCommand("OPENFILE ");
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("'n terminei conversor: " + arq + "'n");
            Application.DocumentManager.MdiActiveDocument.SendStringToExecute("OPENFILE'n", true, false, true);
        }
        else if (e.GlobalCommandName == "OPENFILE")
        {
            //((AcadDocument)Application.DocumentManager.MdiActiveDocument.GetAcadDocument()).SendCommand("PLOTTOPDF ");
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("'n terminei openfile: " + arq + "'n");
            Application.DocumentManager.MdiActiveDocument.SendStringToExecute("PLOTTOPDF'n", true, false, true);
        }
        else if (e.GlobalCommandName == "PLOTTOPDF")
        {
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("'n terminei plottopdf: " + arq + "'n");
            //((AcadDocument)Application.DocumentManager.MdiActiveDocument.GetAcadDocument()).SendCommand("CLOSEFILE ");
            Application.DocumentManager.MdiActiveDocument.SendStringToExecute("CLOSEFILE'n", true, false, true);
        }
        else if (e.GlobalCommandName == "CLOSEFILE")
        {
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("'n terminei closefile: " + arq + "'n");
            count--;
            if (count > 0)
            {
                arq = arquivos[count - 1];
                //((AcadDocument)Application.DocumentManager.MdiActiveDocument.GetAcadDocument()).SendCommand("CONVERSOR ");
                Application.DocumentManager.MdiActiveDocument.SendStringToExecute("CONVERSOR'n", true, false, true);
            }
        }
    }

    [CommandMethod("OPENFILE", CommandFlags.Session)]
    public void OpenFile()
    {
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("OPENFILE ACIONADO. Arq: "+arq);
        Document doc = Application.DocumentManager.Open(arq);
        if (!doc.IsActive)
        {
            AcadDocument aDoc = (AcadDocument)doc.GetAcadDocument();
            aDoc.Activate();
        }
        //Application.DocumentManager.MdiActiveDocument.CommandEnded -= new CommandEventHandler(MdiActiveDocument_CommandEnded);
        //Application.DocumentManager.MdiActiveDocument.CommandEnded += new CommandEventHandler(MdiActiveDocument_CommandEnded);
    }
    [CommandMethod("CLOSEFILE", CommandFlags.Session)]
    public void CloseFile()
    {
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("CLOSEFILE ACIONADO. Arq: " + arq);
        Application.DocumentManager.MdiActiveDocument.CloseAndDiscard();
        //Application.DocumentManager.MdiActiveDocument.CommandEnded -= new CommandEventHandler(MdiActiveDocument_CommandEnded);
        //Application.DocumentManager.MdiActiveDocument.CommandEnded += new CommandEventHandler(MdiActiveDocument_CommandEnded);
    }
    [CommandMethod("PLOTTOPDF", CommandFlags.Session)]
    public void PlotToPDF()
    {
        short bgPlot = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
        //set the BACKGROUNDPLOT = 0 temporarily.
        Application.SetSystemVariable("BACKGROUNDPLOT", 0);
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("PLOTFILE ACIONADO. Arq: " + arq);
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("'n + Um plot simples. " + "'n");
        Document doc =
          Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;
        Database db = doc.Database;
        Transaction tr =
          db.TransactionManager.StartTransaction();
        using (tr)
        {
            // We'll be plotting the current layout
            BlockTableRecord btr = CreateBlockTableRecord(db, tr);
            Layout lo = CreateLayout(tr, btr);
            PlotInfo pi = ConfigurePlotInfo(btr);
            PlotSettings ps = CreatePlotSettings(lo);
            CreatePlotSettings(ps);
            LinkPlotInfoToPlotSettings(pi, ps);
            // A PlotEngine does the actual plotting
            // (can also create one for Preview)
            if (PlotFactory.ProcessPlotState ==
                ProcessPlotState.NotPlotting)
            {
                PlotEngine pe =
                  PlotFactory.CreatePublishEngine();
                using (pe)
                {
                    // Create a Progress Dialog to provide info
                    // and allow thej user to cancel
                    PlotProgressDialog ppd =
                      new PlotProgressDialog(false, 1, true);
                    using (ppd)
                    {
                        ppd.set_PlotMsgString(
                          PlotMessageIndex.DialogTitle,
                          "Custom Plot Progress"
                        );
                        ppd.set_PlotMsgString(
                          PlotMessageIndex.CancelJobButtonMessage,
                          "Cancel Job"
                        );
                        ppd.set_PlotMsgString(
                          PlotMessageIndex.CancelSheetButtonMessage,
                          "Cancel Sheet"
                        );
                        ppd.set_PlotMsgString(
                          PlotMessageIndex.SheetSetProgressCaption,
                          "Sheet Set Progress"
                        );
                        ppd.set_PlotMsgString(
                          PlotMessageIndex.SheetProgressCaption,
                          "Sheet Progress"
                        );
                        ppd.LowerPlotProgressRange = 0;
                        ppd.UpperPlotProgressRange = 100;
                        ppd.PlotProgressPos = 0;
                        // Let's start the plot, at last
                        ppd.OnBeginPlot();
                        ppd.IsVisible = true;
                        pe.BeginPlot(ppd, null);
                        // We'll be plotting a single document
                        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(doc.Name);
                        AcadDocument ppp = (AcadDocument)doc.GetAcadDocument(); //ou GetAcadDocument()
                        String nome_arq = ppp.Name;
                        nome_arq = nome_arq.Remove(nome_arq.Length - 4, 4);
                        pe.BeginDocument(
                              pi,
                              doc.Name,
                              null,
                              1,
                              true, // Let's plot to file
                              "c:''" + nome_arq
                            );
                            // Which contains a single sheet
                            ppd.OnBeginSheet();
                            ppd.LowerSheetProgressRange = 0;
                            ppd.UpperSheetProgressRange = 100;
                            ppd.SheetProgressPos = 0;
                            PlotPageInfo ppi = new PlotPageInfo();
                            pe.BeginPage(
                              ppi,
                              pi,
                              true,
                              null
                            );
                            pe.BeginGenerateGraphics(null);
                            pe.EndGenerateGraphics(null);
                            // Finish the sheet
                            pe.EndPage(null);
                            ppd.SheetProgressPos = 100;
                            ppd.OnEndSheet();
                            // Finish the document
                            pe.EndDocument(null);

                        // And finish the plot
                        ppd.PlotProgressPos = 100;
                        ppd.OnEndPlot();
                        pe.EndPlot(null);
                    }
                }
            }
            else
            {
                ed.WriteMessage(
                  "'nAnother plot is in progress."
                );
            }
        }

    }
    private static void LinkPlotInfoToPlotSettings(PlotInfo pi, PlotSettings ps)
    {
        // We need to link the PlotInfo to the
        // PlotSettings and then validate it
        pi.OverrideSettings = ps;
        PlotInfoValidator piv =
          new PlotInfoValidator();
        piv.MediaMatchingPolicy =
          MatchingPolicy.MatchEnabled;
        piv.Validate(pi);
    }
    private static void CreatePlotSettings(PlotSettings ps)
    {
        // The PlotSettingsValidator helps
        // create a valid PlotSettings object
        PlotSettingsValidator psv =
          PlotSettingsValidator.Current;
        // We'll plot the extents, centered and
        // scaled to fit
        psv.SetPlotType(
          ps,
          Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
        );
        psv.SetUseStandardScale(ps, true);
        psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
        psv.SetPlotCentered(ps, true);
        // We'll use the standard DWF PC3, as
        // for today we're just plotting to file
        psv.SetPlotConfigurationName(
          ps,
          "DWG To PDF.pc3",
          "ANSI_A_(8.50_x_11.00_Inches)"
        );
    }
    private static PlotSettings CreatePlotSettings(Layout lo)
    {
        // We need a PlotSettings object
        // based on the layout settings
        // which we then customize
        PlotSettings ps =
          new PlotSettings(lo.ModelType);
        ps.CopyFrom(lo);
        return ps;
    }
    private static PlotInfo ConfigurePlotInfo(BlockTableRecord btr)
    {
        // We need a PlotInfo object
        // linked to the layout
        PlotInfo pi = new PlotInfo();
        pi.Layout = btr.LayoutId;
        return pi;
    }
    private static Layout CreateLayout(Transaction tr, BlockTableRecord btr)
    {
        Layout lo =
          (Layout)tr.GetObject(
            btr.LayoutId,
            OpenMode.ForRead
          );
        return lo;
    }
    private static BlockTableRecord CreateBlockTableRecord(Database db, Transaction tr)
    {
        BlockTableRecord btr =
          (BlockTableRecord)tr.GetObject(
            db.CurrentSpaceId,
            OpenMode.ForRead
          );
        return btr;
    }

    [CommandMethod("CONVERSOR", CommandFlags.Session)]
    public void Conversor()
    {
        //Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
        //PromptStringOptions pso = new PromptStringOptions("");
        //pso.AllowSpaces = true;
        //PromptResult res = ed.GetString("'nEnterName:");
        //diretorio = res.StringResult;
        //Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("diretorio" + diretorio);
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("CONVERSOR ACIONADO. Arq: " + arq);
        Application.DocumentManager.MdiActiveDocument.CommandEnded += new CommandEventHandler(MdiActiveDocument_CommandEnded);
    }
}
}

正如您在这里看到的,它是一个有四个状态的状态机:CONVERSOR、OPEN、PLOTTOPDF和CLOSE。我读取磁盘中的N个文件,并在状态中保持循环,直到没有要处理的mroe文件为止。我希望所有的dxfs文件都能转换成pdf。当我只为一个文件运行这个程序时,它可以正常工作。问题是:

想象一下,我在第一个文件中经过CONVERSOR->OPEN->PLOTTOPDF->CLOSE。AutoCAD打开文件,切换活动文档,我无法进入关闭状态,然后我的机器状态停止在PLOTTOPDF状态。(即使是第一个文件也没有关闭,而是正确地转换为pdf(。有人能帮忙吗?我认为问题在于,当我打开一个新文件时,激活的文档会发生更改,AutoCAD在查看命令是否完成时会迷失方向。

当试图使用C#编写的插件打印多个文件时,AutoCAD只能处理一个文件.NET.如何解决

布局必须是最新的才能打印。所以你必须打电话给:

Application.DocumentManager.MdiActiveDocument = doc;
LayoutManager.Current.CurrentLayout = layoutName;

否则,方法CreateLayout的名称是错误的。你不是在创建一个布局,你只是得到了它。

我不明白你为什么要使用COM来获取文档的名称。

AcadDocument ppp = (AcadDocument)doc.GetAcadDocument();
String nome_arq = ppp.Name;
nome_arq = nome_arq.Remove(nome_arq.Length - 4, 4);

可替换为:

nome_arq = System.IO.Path.GetFileNameWithoutExtension(doc.Name);