Author Topic: A bit of advice please (Batch Printing via C# .NET w/ COM Interop AutoCAD 2011)  (Read 4298 times)

0 Members and 1 Guest are viewing this topic.

vegbruiser

  • Guest
I have an old batch printing program (written by someone else) that allows the user to print files in user-selected locations.

It will print Word, Excel, PDF and .dwg file formats, but is currently only working correctly with AutoCAD 2006. (Which went unsupported by Autodesk some time ago - and rightly so IMO)

I've tried updating it to work with AutoCAD 2011, but I keep getting a COMException error thus:

(See attached)

The odd thing is, whilst debugging, if this error occurs, I can let it sit there for a while and then hit F11 (to continue) and it carries on as if the error never occurred, which says to me that a simple pause before querying the
Code: [Select]
doc.Layouts.Item(i).Name object would allow me to skip around the error.

So I suppose my question is this:

Do I rewrite the application so that's run from Inside AutoCAD (the COM Interop for Excel, Word & Adobe cAcrobat should still work, right?) or do I try and fix the problem w/ the COM implementation as it stands?

Thanks,

Alex.

Bigguy121

  • Guest
look at "BACKGROUNDPLOT" setvar. change it to 0

vegbruiser

  • Guest
Thanks for the tip.

For reference, this post over on the AutoCAD Dev Blog covers exactly this problem:

http://adndevblog.typepad.com/autocad/2012/06/backgroundplot-system-variable.html

(I'm still debugging my code but will report back if this change is indeed successful :) )

vegbruiser

  • Guest
Right, the change suggested by Bigguy121 seems to have resolved the first issue I was having.

But it has presented another problem which occurs when attempting to open a file with the following code:

Code: [Select]
AcadDocument doc = dwgApp.Documents.Open(line,true);
Again, it seems as though the code needs to wait for a signal from AutoCAD before attempting the above line.

Wrapping the Documents.Open in a Try, Catch thusly seems to resolve the issue - can anyone explain to me what the hell is going on?:

Code: [Select]
AcadDocument doc;
Try
{
doc = dwgApp.Documents.Open(line,true);
}
Catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
doc = dwgApp.Documents.Open(line,true);
}

Edit: Wrapping the file open in a Try, Catch block works if the file is quite small/simple - if not, it still errors.  :x :x
« Last Edit: June 21, 2012, 09:47:04 AM by AlexF »

T.Willey

  • Needs a day job
  • Posts: 5251
Here is a batch plot routine I wrote awhile ago in C# ( only for plotting acad drawings ).  Maybe it will help you with your problems somehow.  I do not write much code anymore, so I'm not sure I can help beyond the code posted.

http://www.theswamp.org/index.php?topic=17348.0;all
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

vegbruiser

  • Guest
Hi all as per Teslaxx's request, here's my source code for this batch printing routine.

(Oddly, this does seem to be working as expected now - on my Dev. machine at least)

Thanks.

Bigguy121

  • Guest
make sure to lock your document. sample in vb.net

    'Transaction Block
    Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
    Dim acCurDb As Database = acDoc.Database
        Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
            Using acLckDoc As DocumentLock = acDoc.LockDocument()




                acTrans.Commit()
            End Using
        End Using

vegbruiser

  • Guest
Thanks for the tip, but I'm not sure this will work as I'm using COM to access AutoCAD..?

Locke

  • Guest
Thanks for the tip, but I'm not sure this will work as I'm using COM to access AutoCAD..?

Gah!  I wish I had been here to help when this was relevant.  For anyone still wondering about Batch-printing anything via interop, there's a general pattern that fits most scenarios:

- Instanciate or latch onto an AutoCAD session
- Netload your custom in-process assembly with fast in-process code for printing (or doing anything for that manner)
- Loop the drawings from the COM side so you can talk directly to your UI (progress update delegates come to mind), opening them one at a time from interop, and calling your named CommandMethod via send command (or registered ServiceComponent).
- Exit AutoCAD from COM
- Profit

A few things to note:
1.  Having a custom .arg profile for automation can really make a nice difference in speed and control here.

2.  COM is slow.  However understand where the speed matters.  Calling 'Open' on a drawing from COM vs managed in-process code is pretty much negligible, since the drawing having to load off the disk is the limiting factor.  Running any sort of DbObject manipulation, searching for data, or creating new objects is where you REALLY want to stay away from COM.

3.  In regards to printing, understand that (at least when I tested it in 2010) the in-process printing instanciates a separate session of AutoCAD to plot from.  (I would really love someone to chime in with more about this, specifically whether or not this is in our control).  There's a case to be made for batch-PDF plotting being faster this way, but I was never comfortable eating up the extra resources, and not having a direct hold on the new acad.exe instance.  During regular paper plotting, even COM printing calls aren't terrible in my opinion.  Stacking the print queue with 30 drawings in 10 seconds vs 60 seconds really doesn't matter unless your plotter can keep up with the speed the jobs get added to the queue. ** Generally  ** (not saying you shouldn't try to make things as quick and efficient whenever possible, but pick the right battles when you're writing code).

4.  You can cheat a little to get simple COM to in-process communication by setting up prompts inside your defined CommandMethod.  This way when you invoke SendCommand from COM, you can include your parameters in a single line:
(Command "MyCircle 0,0,0 5\n") // Or something... don't judge me  :-D
Anything that you can parse from a string is fair game.

5.  Avoid using Interop libraries.  Seriously.  In the context of all Office products and AutoCAD, there's really no need to ever use them.    Use reflection or dynamic members, and you've pretty much kicked version dependence in the face.  What I'll typically do is add in an Interop assembly when I'm not comfortable with the classes and methods,  write the code just like I'm leaving the interop libraries in.  When everything is working the way I've intended, I'll strip out the libraries and make the replacements.  When using .NET 4.0, this can literally be as little as 3-5 lines of code.  There are instances where the underlying COM classes/methods change from one release to the other, but you can deal with those on a case-by-case basis and never have to worry about maintaining multiple releases.