Printing API and printManager.PrintToFileName setting

Printing API and printManager.PrintToFileName setting

sobon.konrad
Advocate Advocate
7,623 Views
15 Replies
Message 1 of 16

Printing API and printManager.PrintToFileName setting

sobon.konrad
Advocate
Advocate

It seems like for an unexplained reason Revit doesn't print to a specified file name/location. When I set my PrintToFileName and then SubmitPrint() it prints to a different location then specified. It prints to last location that I used for printing when I printed via User Interface. 

Also, what is more confusing is that when I navigate to Print UI i can see the desired path setting as well as when I actually fire my printing via API and the Adobe process window shows up, it also has the correct path in the window, YET IT STILL PRINTS TO A DIFFERENT LOCATION. what am i doing wrong? 

 

#Copyright(c) 2015, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

#The inputs to this node will be stored as a list in the IN variable.
dataEnteringNode = IN

sheets = IN[0]
pRange = IN[1]
combined = IN[2]
printerName = IN[3]
printSetting = IN[4]
filePath = IN[5]
runIt = IN[6]

message = "Success"
if runIt:
	viewSheets = []
	for i in sheets:
		viewSheets.append(UnwrapElement(i))
	
	viewSet = ViewSet()
	if isinstance(sheets, list):
		for i in sheets:
			viewSheet = UnwrapElement(i)
			viewSet.Insert(viewSheet)
	else:
		viewSheet = UnwrapElement(sheets)
		viewSet.Insert(viewSheet)
	
	printManager = doc.PrintManager
	printManager.PrintRange = pRange
	printManager.Apply()
	viewSheetSetting = printManager.ViewSheetSetting
	viewSheetSetting.CurrentViewSheetSet.Views = viewSet
	
	printManager.SelectNewPrintDriver(printerName)
	printManager.Apply()
	if printManager.IsVirtual == VirtualPrinterType.AdobePDF:
		printManager.CombinedFile = combined
		printManager.Apply()
		printManager.PrintToFile = True
		printManager.Apply()
	else:
		printManager.CombinedFile = combined
		printManager.Apply()
		printManager.PrintToFile = False
		printManager.Apply()
	
	printManager.PrintToFileName = filePath
	printManager.Apply()
	

	ps = FilteredElementCollector(doc).OfClass(PrintSetting)
	for i in ps:
		if i.Name == printSetting:
			newPrintSetting = i
	try:
		printSetup = printManager.PrintSetup
		printSetup.CurrentPrintSetting = newPrintSetting
		printManager.Apply()
	except:
		pass
			
	# Start Transaction
	doc = DocumentManager.Instance.CurrentDBDocument
	TransactionManager.Instance.EnsureInTransaction(doc)
	
	viewSheetSetting.SaveAs("tempSetName")
	printManager.Apply()
	printManager.SubmitPrint()
	viewSheetSetting.Delete()
	
	# End Transaction
	TransactionManager.Instance.TransactionTaskDone()
else:
	message = "Set RunIt to True"

#Assign your output to the OUT variable
OUT = printManager.CombinedFile
0 Likes
Accepted solutions (1)
7,624 Views
15 Replies
Replies (15)
Message 2 of 16

Anonymous
Not applicable

Can't help much but  I was having issues with the print to file name a few weeks back and it was due to combined was false and it whenprinting to seperate files wouldn't allow me set the print to file name. Doesnt explain setting it back to what your printmanager setting were though.

0 Likes
Message 3 of 16

augusto.goncalves
Alumni
Alumni
Accepted solution
In this case was actually a problem with the print driver.
Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
0 Likes
Message 4 of 16

sobon.konrad
Advocate
Advocate

Auguston,

 

Like I said in our email exchange it wasnt so much a problem with a printer driver - because it is doing what its supposed to do - rather that a print settings established in Revit get overriden by the printer default settings. 

In my particular case I was using Adobe PDF printer and had it set to NOT PROMPT FOR FILE NAME and I had chosen a default print location. What happens is that this setting will supress a window coming up for every sheet but it will also use the location specified in the printer preferences to save the prints to instead of one specified in printManager.PrintToFileName() method. I was just getting confused about this for like one second. 

 

Thanks! 

Message 5 of 16

augusto.goncalves
Alumni
Alumni
Thanks for clarifying 🙂
Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
0 Likes
Message 6 of 16

Anonymous
Not applicable

Hey Konrad,

 

Is it possible to override the print driver settings, without a dialog popping up? I want to automatically choose the locations, rather than clicking it in the file system each time.

 

Thanks!

 

- Jed

Message 7 of 16

c_hanschen
Advocate
Advocate

Can it be, that the filename stored in PrintManager.PrintToFileName is not send to the PDF printer with the Path included?

It looks to me, that only the FileName (Without the path) is forwarded to the (PDF) printer.

 

Like @sobon.konradsaid:

"In my particular case I was using Adobe PDF printer and had it set to NOT PROMPT FOR FILE NAME and I had chosen a default print location"

So you had overridden the path in the PDF printer driver??? That's not a solution, that's a workaround.

 

I had tried different PDF printer drivers, all able to save to default location with correct filename, but none to the path specified in Revit API by PrintManager.PrintToFileName.

Message from BioPDF when trying to save without prompting AND without default location:

Er is een fout opgetreden!

Error -2147024809: Het pad kan niet uit een lege tekenreeks of alleen spaties bestaan.

Source: mscorlib

Because it is in Dutch, I will translate: The Path can't be empty or contain only spaces

 

Did anyone succeeded to save to correct FileName AND Folder using "PrintManager.PrintToFileName"..??

Can you please tell me the name of the PDF Printer Driver?

 

Many thanks,

Chris Hanschen

The Netherlands

0 Likes
Message 8 of 16

FRFR1426
Collaborator
Collaborator

I had tried different PDF printer drivers, all able to save to default location with correct filename, but none to the path specified in Revit API by PrintManager.PrintToFileName.

PDFCreator can do that. You have to choose the Automatic mode, put <InputFilename> in File name and <InputFilePath> in Folder.

Maxence DELANNOY
Manager
Add-ins development for Autodesk software products
http://wiip.fr
0 Likes
Message 9 of 16

Anonymous
Not applicable

Hi All,

 

  I have the same problem with Bluebeam PDF and I cannot fix the issue. The PrintToFileName can change the file name, but I could not change the path at all. it would be appreciated if you help me.

 

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.UI.Selection;
using System.Windows.Forms;

namespace MyRevitCommands
{
    [TransactionAttribute(TransactionMode.Manual)]
    public class PublishMngr : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //Get UIDocument and Document
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            List<Element> AllSheets = new List<Element>();

            ElementFilter elefilter = new ElementClassFilter(typeof(ViewSheet));

            FilteredElementCollector collector = new FilteredElementCollector(doc)
                .WhereElementIsNotElementType()
                .WherePasses(elefilter);
            try
            {
                using (Transaction trans = new Transaction(doc, "Publish Manager Settings"))
                {
                    trans.Start();

                    foreach (Element ele in collector)
                    {
                        AllSheets.Add(ele);
                    }
                    int Count = 1;
                                        
                    //Check for path
                    String path = "C:\\Users\\Desktop\\TestPrint\\AskedPath\\";

                    foreach (ViewSheet sheet in AllSheets)
                    {
                        if (sheet.SheetNumber.ToString() == "C01")
                        {

                            PrintManager PrintM = doc.PrintManager;
                            string shtprtflenm = path + sheet.SheetNumber.ToString() + "Mike" + Count.ToString() + ".pdf";
                            PrintM.PrintRange = PrintRange.Select;


                            PrintM.PrintToFileName = shtprtflenm;                            
                            PrintM.CombinedFile = true;
                            PrintM.PrintToFile = true;
                            PrintM.Apply();                   

                            
                            Autodesk.Revit.DB.View sheetv = sheet as Autodesk.Revit.DB.View;

                            PrintM.SubmitPrint(sheetv); //This is the CDC Project Issue path for some reason

                            String assemblyPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + ".pdf";
                            //System.IO.Directory.Move(assemblyPath, @"C:\Users\Public\private");

                            Count++;
                        }

                    }

                    trans.Commit();
                }
                return Result.Succeeded;
            }
            catch (Exception e)
            {
                message = e.Message;
                return Result.Failed;
            }
        }
    }
}
0 Likes
Message 10 of 16

Moustafa_K
Collaborator
Collaborator

Hi,

AFAIK, you need to save the print settings... see below as an example

PrintManager pm = m_doc.PrintManager;
string myset="myprintersettings";
			var filprnset = new FilteredElementCollector(m_doc).OfClass(typeof(PrintSetting)).Cast<PrintSetting>().ToList();
			var prnsets = filprnset.Where(o => o.Name == myset).FirstOrDefault();
pm.SelectNewPrintDriver(ucapp.mv.Selected_Printer.Name);

			//when setting the new printer, the PrintManager object is changed internally. so it is required to obtain a new PrintManager:
			
			pm = m_doc.PrintManager;
			pm.PrintRange = Autodesk.Revit.DB.PrintRange.Current;
			pm.PrintToFile = true;
			pm.CombinedFile = true;
			pm.PrintToFileName = FilePath; //type your file path here
			pm.PrintSetup.CurrentPrintSetting.PrintParameters.ZoomType = ZoomType.Zoom;
			pm.PrintSetup.CurrentPrintSetting.PrintParameters.Zoom = 100;
			pm.PrintSetup.CurrentPrintSetting.PrintParameters.PageOrientation = PageOrientationType.Landscape;
			pm.PrintSetup.CurrentPrintSetting.PrintParameters.PaperPlacement = PaperPlacementType.Center;
			pm.PrintSetup.CurrentPrintSetting.PrintParameters.HiddenLineViews = HiddenLineViewsType.VectorProcessing;
			 //now you need to save the settings.
//for some reasons I was not able to use the Save method, not sure it is a bug or something in my code. but I didn't care as the setting is always set via Code. So typically, I delete myset and save it again.
			using (Transaction t = new Transaction(m_doc, "Save Printer Settings"))
			{
				t.Start();

				try
				{
					if (prnsets != null)
					{
						m_doc.Delete(prnsets.Id);
						m_doc.Regenerate();
					}
					pm.PrintSetup.SaveAs(myset);
				}
				catch (Exception ex)
				{
					//"Error saving Print Settings"
					return false;
				}
				pm.Apply();
				t.Commit();
			}

			return true;
		}

hope this helps

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes
Message 11 of 16

Anonymous
Not applicable

Hi,

 

  Many thanks for your reply. I tried this one but the variable's value will be false. I think the problem is the printer itself that it might not have that option. The only solution will be just to fix that target folder in the Bluebeam PDF and move the created PDF file to the path that we need. Thanks again for your time.

 

Best Regards

 

 

0 Likes
Message 12 of 16

Sean_Page
Collaborator
Collaborator

The only way I have found to make this work is to modify at run time the registry keys associated with the Bluebeam printer. The only problem is that the PrintManager.SubmitPrint() exists outside of the idling event handler and I have been searching for a solution to set the value back when ALL sheets have been printed. pyRevit had a "button" on their toolbar for this, but it would sure be handy to set it back when done. (Hint: if anyone has a solution I would love to hear it!)

 

 

string bbRoot = @"Software\Bluebeam Software\2018\Brewery\V45\Printer Driver\";
string prints = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "RDG_Prints");
SetKeyValue(bbRoot, "SaveAsFolder", prints);

internal bool SetKeyValue(string root, string key, string value)
{
try
{
RegistryKey bbKey = Registry.CurrentUser.OpenSubKey(root, true);
bbKey.SetValue(key, value);
bbKey.Close();
return true;
}
catch
{
MessageBox.Show("Unable to Set Key", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}

 

 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 13 of 16

Moustafa_K
Collaborator
Collaborator

well, how about, running FileSystemWatch event for instance, where if the files that are supposed to be created exists then change back the registry keys.

but is it possible to change the registry keys while you are not admin. I am facing some scenarios like this at my office, due to privileges 😞

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
Message 14 of 16

Sean_Page
Collaborator
Collaborator

Thanks for the reply, as I was sitting here thinking about this after I had randomly stumbled upon this post this morning and I realized the PrintManager.SubmitPrint() returned a bool so a really simple reverse counter did the trick to count down until its done, and then I just set the keys back.

 

This could be an issue, but fortunately at the moment I our users have admin rights to their machines so not too much of a hassle... for now.

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 15 of 16

Moustafa_K
Collaborator
Collaborator

"PrintManager.SubmitPrint() returned a boolgood catch. thanks for sharing this.

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes
Message 16 of 16

MuirEng
Collaborator
Collaborator

Hello, I realize this is an old conversation but it seemed best to reply rather than starting something new.

I'm looking into writing a tool that quick prints the revit file as a PDF using the project name and latest revision information as a basis for the filename.  The stumbling block appears to be passing this information to the print driver for fully automatic operation. This conversation indicates that: 

  • With Bluebeam it appears necessary to edit registry entries on the fly, but this will problematic for users without administrative access.
  • With PDF995 it appears necessary to edit the .ini file on the fly to pass in the file name/path.
  • PDF Creator has an automatic mode that supports passing in the file name.

It seems that the best approach might be for all users who want to use this tool to set up PDF Creator as an alternative PDF driver, and then code the plug in to work with it?

I'd appreciate a bit of guidance here before I sink too much time into this, thanks. 


Brian Muir, P.Eng, Muir Engineering
0 Likes