Modifying a printers default settings from C# - c#

Here's my situation:
I'm developing a C# add-in for a 3rd party program
This program (Revit) uses its own printing methods and exposes them through its API
I am writing a printing utility that uses these methods to print to various locations, including a PDF printer
I'm using PDF995 as a printer and modifying its .ini file to automate it.
Basically I'm calling the print method in the API which prints the active drawing to a specified printer.
My problem is that on PDF995, if you go to printing preferences in Windows the orientation is by default set to 'portrait'. I need landscape. These settings seem to override anything I set in the Revit API, so I need a way of changing the windows settings.
I've tried this code:
PrintDocument printDocument = new PrintDocument();
printDocument.PrinterSettings.PrinterName = "PDF995";
printDocument.DefaultPageSettings.Landscape = true;
before calling the print function in the API, but it makes no difference. I can't see a way to edit the pdf995 ini to set these settings either. It's a windows setting that I need to override.
I've seen some C++ code on the net I can call to do things with printers but can't find an example of changing the default settings.
Can anyone point me in the right direction?

I've had good success using these components:
http://www.merrioncomputing.com/Download/PrintQueueWatch/index.htm
http://printqueuewatch.codeplex.com/Wiki/View.aspx?title=Home
This collection makes available all sorts of useful printing options. It's mainly focused on monitoring a print queue, but from memory there are options available to change printer settings and job properties.

I think many of the settings from a use of Autodesk.Revit.DB.PrintManager are "placeholders", but that if the printer is controlling these settings, the value ported to it by Revit is ignored. I have tried setting .PrintToFileName with a full path, but making a PDF in BlueBeam still sends the file to MyDocuments, from where I have to copy it. Have you tried copying your PDF995 to PDF995X (for example) and modifying it to have a default of Landscape (while PDF995 retains the default of Portrait)? I have used this method in the past when a printer insists on using stored defaults instead of those requested.

Related

Printer spooler api number of copies

I really could use some help, this is a question that alot of people are asking on the internet. I have different setups, tried different ways of testing, it's very frustrating.
First setup:
local printers
local running code
print from pdf or notepad: SUCCES (number of copies are 2)
print from word: FAILED (numberof copies is 1)
Second setup:
local printers that are shared
local running code
print from other computer to shared printers
number of copies isalways 1
Sowhat is everyone missing? What happens that some fields are missing while the printer still should know what to print? What does word that also happen when you print from another computer? Can someone tell me why somethings in windows are so terrible? Everythingshould pass the spooler, sowhy isthedata wrong?
Kinds regards!
A printer prints sheets and pages, so copies is converted to pages at some stage.
The notification data you get depends on both the application that is printing and the system and driver components handling the spooling and rendering. In my experience the data cannot be relied on, and the best data is obtained by parsing the spool file. This may or may not contain the number of copies.
Word has had the "copies problem" for a long time. There was a patch to supposedly fix this, but another opinion is that it's because it uses an unusual way of printing. I'll quote some of the link contents here:
With the infamous Word Copy Count bug… the dmCopies filed is 1 in the
SHD. The correct value is found in the DEVMODE record in the SPL file
(if it's an EMF spool).
The only other way i found was to monitor the PrintedPages field of
the JOB_INFO_2 structure, when the job has been sent to the printer,
and see if it is a multiple of TotalPages.
[...]
What happens is not a Word bug, but a Windows bug. Word calls startDoc
always with copies set to 1. After that calls DocumentProperties and
makes the change in dmCopies and calls ResetDC to make the update. It
is a strange way of printing but not wrong. The problem is that the
shd file and printer_info is not updated with this information, just
keeps the Devmode info set on the StartDoc call.
But the call to the ResetDC generating a new DevMode is kept on the
SPL file. You can get that info too if you hook DocumentProperties
API calls.
Thank you for the answer. Is there a way of catching the document properties when they change?
The JOB_INFO_2 structure does have the same total_pages as pages_printed. So that is not a solution.
The SPL File does contain the QTY for the printer i tested on which is correct. BUT we tested on a lot of printers and we see the QTY is not Always set. So not a 100% solution. But already a good fallback.
So if i can catch the document properties without calling the SPL file that would be wonderful because i guess that's where everything is correct. Isn't it?

PrintTicket scopes (default, user, job, document, page etc)

I'm completing the construction of a webservice that builds and prints out XPS documents sending them to various print queues on various print servers. The webservice runs in 2 modes depending on site deployment. The first is using the app pool identity account as the print user, the second mode uses user impersonation for "follow me" type printers, so that the user is registered against the print job. This all works fine.
I have to target particular trays on the printqueues and set various other parameters for each job, so I've generated printickets adding the tray namespace to the xml and this also appears to work.
My concern is this (and is where I need some hand holding), because I'm doing all this STA threaded server side, say Bob running as Bob prints 200 documents of a mix (A4, A5, envelope) and the tickets switch off say duplexing on the printer and my app pool identity account is running say 20 printing threads with multiple documents of various target trays with various parameters at once, am I going to get any issues or am I going to knacker the default printer queue settings?
According to MS, MergeAndValidatePrintTicket can be scoped at various levels (I'll settle for job level) but I just wonder if anyone with experience of this scenario can validate this as true and if there any gotchas out there, because this whole .Net printing malarkey seems to be riddled with them.
'lil tip for anyone doing this. If your target printers are simple with say only 3 trays of different sizes, just set the media size (ISOA4 or whatever) in the ticket and set the input bin to unknown and the printer will work it out. Unfortunately, the printers I'm targeting have about 7 bins, so I have to target the exact tray.
Thanks for reading.
Edited to show solution
Jon...this is the relevant section...
PrintTicket ptclone = pqTarget.UserPrintTicket*.Clone();* <--remove Clone()
//my method below for specifying the tray to use for the job and other settings. poj is my printJob class
PrintTicket pt = GetPrintTicketForJob(ptclone, poj.trayMediaSize, poj.trayNameSpace, poj.trayUri);
ValidationResult vr= pqTarget.MergeAndValidatePrintTicket(ptclone, pt, PrintTicketScope.JobScope);
pqTarget.UserPrintTicket = vr.ValidatedPrintTicket; <--remove this
//pqTarget.Commit() // the print server in localPrintServer mode didn't like that under user impersonation
PrintSystemJobInfo pj = pqTarget.AddJob(poj.id, poj.fileName, false) <--don't do this
I tried using the .Net 4.5 overload that has the print ticket in it, but the server in localPrintServer mode didn't understand the method even though the server has .Net 4.5 on it and which was...
PrintSystemJobInfo pj = pqTarget.AddJob(poj.id.ToString(), poj.fileName, false, vr.ValidatedPrintTicket) <--do this instead .Net 4.5 and it all works
Everything works fine with the following exceptions....
1) on the mfds which are controlled by 3rd party software and use user impersonation, the default duplex setting stays active for the first document printed, after that, it's fine. It works OK for the Lexmarks (app pool idenity used). Trays are properly assigned on both types as are the other settings.
2) Dates and numbers (which are inserted as strings into the documents) and appear OK in the XPS viewer get reformatted as san serif even if the paragraph they are in is in say Times New Roman which is baffling.
Can you spot any screw ups?
regards
Neil

Mechanics of printing

I am changing default print settings using winspool.drv before printing. Do the altered default printing settings get embedded with the print job when it is printed? Or are they saved somewhere else? If I change a setting, what happens when the print job is sent to the printer? What information goes with the print job? Am I even asking the right questions? I am batch printing a lot of files and changing settings between pages in each job.
Edit:
My understanding is this:
I make changes to default printer settings
Print document, default printer settings are embedded in spool file and sent to printer
Printer prints using spool file
Is my understanding is correct? Do I need to wait until the print job is over before changing the printer settings?
Changing default settings for a simple task is usually a no-go and should never be done. If your program crashes or does something wrong, the user's settings are lost, which might even get pretty expensive considering high quality print settings, photo paper, etc.
You should change the settings per job using the provided API (if possible) to only affect the current/to be printed document.
Once the print job is done/spooled (i.e. it's only waiting for the printer to start or getting online), updated settings no longer affect the document.

Windows 7 taskbar - jumplist, jumplistlink and jumplistitem

I am using the Windows API Code Pack for Microsoft .NET Framework to try out of some of the new UI features of the Win7 taskbar. I am coding in C#.
I have a question regarding jumplists. All of the sample code provided assumes that the entries on the jump list are used to call out to run a particular application or open a document, e.g. a text document in a MRU list or run mspaint.exe.
I would like to implement some items which allow me to set state in my own application (i.e. the app which is interacting with the taskbar). MSN Messenger does this, for example, when you can set your status (Busy, Offline etc.).
Try as I might, I cannot create a JUmpListItem or JumpListLink to behave in this way - it treats them as applications or documents.
Does anyone have any samples of how to create an item which raises an event in the same application that created it? I am sure it is simple but I am being very daft.
Many thanks for your help.
I believe what you'd want to do is to call your application with a special set of flags (i.e. launch the executable with certain arguments). At application start up, you'd check to see what flags are set, then send a message to the main instance of the application and then exit out of the new instance.
Using the TaskBarDemo, to open an item created by your application would have to be referenced, ie if your program created a PDF file you would do this:
jumpList.AddUserTasks(new JumpListLink(Path.Combine(systemFolder, "C:\\Program Files\\Adobe\\Reader 9.0\\Reader\\AcroRD32.exe"), "Open Adobe Reader")
{
IconReference = new IconReference(Path.Combine(systemFolder, "C:\\Program Files\\Adobe\\Reader 9.0\\Reader\\AcroRD32.exe"), 0)
});
Otherwise you would have to ensure that your application registered file associations, for recent or frequent items.
I had a few problems with jumplists with the API Pack, i now use VS 2010 Beta 2 and let shell handle the jumplists.
Hope this is helpfull.
These tasks are some sort of IShellLink. Then, you should call ICustomDestinationList's AddUserTasks. Look up samples in Windows 7 Training Kit.

C# PrintDialog.PrinterSettings.CanDuplex Reports Wrongly

I'm trying to setup some code to print to different trays on a photo copier depending on what the document is (different sizes, paper colours...). It is one particular type of copier so I am not too worried about the code working in other scenarios. I still want to show the print dialog, just with the settings having better defaults for each document.
I have managed to setup the majority of what I want using properties in
PrintDialog.PrinterSettings.
However on trying to set the duplexing using
PrintDialog.PrinterSettings.Duplex = System.Drawing.Printing.Duplex.Vertical;
It fails, remaining the same as it was before. If I check if duplex is supported using
PrintDialog.PrinterSettings.CanDuplex;
It returns false which is not the case I can change it on the dialog and it prints fine. Has anyone else had this problem? Is there a work around? Perhaps something involving COM (please be gentle not used interop code much)
It's a Gestetner 2212 copier and I believe the print server is a Windows Server 2008 machine.
Edit:
I found this link
http://bytes.com/topic/c-sharp/answers/238860-using-setprinter-c-set-duplex-option-print-prefs
Which seems to be a similar problem it seems to be some kind of problem related to using a networked printer and trying to set duplex. However the link doesn't post the solution it was emailed to them (I hate it when people do that). Anyone know how I can set the duplexing using COM interop code.
Seems network printers duplex property cannot be set in .NET code easily, even when it says it has changed the property it doesn't output correctly. There is a way to do it using com interop but it still requires modifying security levels for the printer so is more hassle than it is worth.
Try implementing a handler for the PrintPage event with following code:
if (e.PageSettings.PrinterSettings.IsValid && e.PageSettings.PrinterSettings.CanDuplex)
e.PageSettings.PrinterSettings.Duplex = System.Drawing.Printing.Duplex.Vertical;
Tried it with a HP Laserjet M3035. It didn't show in the PrintDialog window but printed the document in duplex anyway.

Categories