当试图使用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在查看命令是否完成时会迷失方向。
布局必须是最新的才能打印。所以你必须打电话给:
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);