Automate PDF printing from Revit

I'm writing a batch PDF printing add-in (C#) for Autodesk Revit (a 3D CAD program). It is important to notice that the Print command has to be given through Revit's own API and that it's not possible to convert a drawing or a document to PDF in another way. So my best way to go about this is to alter the settings of the active print job itself through the comwrapper.

I've read several topics dealing with printing automation, and as I understand it, the best way to do it is to get access to the printing queue of the PDFcreator, and change the profile settings of the next job to automatically save it to a filename and -path without confronting the user with the PDFcreator user interface. Is this correct? From a newb perspective, what would be the best approach, in terms of accessing the job profile and changing the settings? Would I do this before or after the job is submitted to the print queue?

As a shortcut, would it be easier to create a profile (programmatically) and set that for the specific print job?

Thanks in advance.

What I have now:

q = new Queue();
q.Initialize();
q.WaitForJobs(n, n * 5);

//telling Revit to print a number of sheets

for (int i = 0; i < q.Count; i++)
{
   PrintJob j = q.GetJobByIndex(i);

   //determining full file path as fileName 

   j.ConvertTo(fileName);
}

q.ReleaseCom();

What happens: my code idles for the duration of the queue wait time, after which I get the PDFCreator print window. It also doesn't reach my breakpoint inside the For loop. This tells me that either the pdf printer isn't using the queue I created in code, or that I'm reaching the loop before the queue is populated at all.

Hi,

generally this looks like the proper approach.
WaitForJobs will return true when all jobs have arrived in time, so you could check that before entering the for loop.
If the document is large, 5 seconds might not be enough for the spooling to complete.

Best regards

Robin

Thanks.
I'm still finetuning that number, and sometimes it takes 15 seconds for a big sheet to spool.
I think I narrowed down the cause to the fact that the queue isn't (fully) populated yet by the time I loop through it, which ofcourse is a problem when I'm releasing the Com while the queue is still being written to.

I know it's a bit of a newb question, but what's the best way to await this condition? I've tried an empty While loop While (!jobsReceived){} , but at a certain point I just had to kill the process because it was taking a really long time.

I think the best approach might be to just use a much larger timeout (e.g. n*60).
It is only the maximal amount of time to wait, if all jobs arrive earlier, the processing will continue at that point. For debugging you can just check if WaitForJobs returned true and through an exception if it didn't.

Thanks.
I get it to print at pretty decent performance now (awaiting queue after last print job was sent), but it's printing only two sheets of a sample size of 4. I'm awaiting the queue to return True, and then I'm looping through the jobs, which number is 4 on debugging. But it stops after the first 2.
After some more testing, it's only printing half the sheets in the queue...

EDIT: I think I got it fixed. I'm looping through the number of jobs in the queue, which decreases by 1 every time a job is completed. This should've been obvious to me. The iterator also increases. So they meet in the middle, and I'm looping through jobs quicker than through the filenames, which is also causing a mismatch between the file and the filename.

My new code:

Queue q = new Queue();
q.Initialize();

//Tell Revit to send files to printer

q.WaitForJob(60);

for (int i = 0; i < n; i++)
{
   while (q.Count == 0) Thread.Sleep(200);
   PrintJob j = q.NextJob;

   //Retrieve file name

   j.ConvertTo(fileName);
}

q.ReleaseCom();

This works for me. A job gets processed as soon as it enters the queue (or at most 0.2 seconds after). All in all a pretty straightforward process and I can see a lot of potential in this.

1 Like