Find a printer's default duplexing option

1.5k Views Asked by At

For a given print document's PrintSettings the Duplex value might be (and are likely to be) set to Duplex.Default.

How can I find out whether that means the chosen printer will or will not print in duplex or not?

How can I find the default values for an installed printer's supported behaviours?

3

There are 3 best solutions below

0
On
0
On

Short answer? You don't. Regardless of what the various settings say, the actual printer may be set to always duplex the print jobs.

I'm not entirely sure how you plan on merging the documents together, but it sounds like you may be able to simply count pages and optionally insert a blank page between documents to ensure that every new document starts on an odd page.

It's a much larger change, but if you are open to moving to an XPS workflow, there is a page level ticket item called PageForceFrontSide that will guarantee that documents aren't mistakenly stuck together.

0
On

I'm not sure you can get at the default for a given printer. You can get at the actual current values, though, if you're creative. You're going to have to get at the DEVMODE structure if you want to ensure you have the correct information, though. This is not a simple operation and will require some fancy-pants Win32 fu. This is adapted from a couple of sources but worked on my (admittedly spotty) tests.

[DllImport("kernel32.dll")]
static extern bool GlobalFree(IntPtr hMem);

[DllImport("kernel32.dll")]
public static extern IntPtr GlobalLock(IntPtr handle);

[DllImport("kernel32.dll")]
public static extern IntPtr GlobalUnlock(IntPtr handle);

private static short IsPrinterDuplex(string PrinterName)
{
    IntPtr hDevMode;                        // handle to the DEVMODE
    IntPtr pDevMode;                        // pointer to the DEVMODE
    DEVMODE devMode;                        // the actual DEVMODE structure

    PrintDocument pd = new PrintDocument();
    StandardPrintController controller = new StandardPrintController();
    pd.PrintController = controller;

    pd.PrinterSettings.PrinterName = PrinterName;

    // Get a handle to a DEVMODE for the default printer settings
    hDevMode = pd.PrinterSettings.GetHdevmode();

    // Obtain a lock on the handle and get an actual pointer so Windows won't
    // move it around while we're futzing with it
    pDevMode = GlobalLock(hDevMode);

    // Marshal the memory at that pointer into our P/Invoke version of DEVMODE
    devMode = (DEVMODE)Marshal.PtrToStructure(pDevMode, typeof(DEVMODE));

    short duplex = devMode.dmDuplex;

    // Unlock the handle, we're done futzing around with memory
    GlobalUnlock(hDevMode);

    // And to boot, we don't need that DEVMODE anymore, either
    GlobalFree(hDevMode);

    return duplex;
}

I used the DEVMODE structure definition from pinvoke.net. Note that the charset defined on pinvoke.net may need some tweaking according to comments on the original link by B0bi (namely, setting CharSet = CharSet.Unicode in the StructLayoutAttriute on DEVMODE). You'll also need the DM enum. And don't forget to add using System.Runtime.InteropServices;

You should be able to narrow down from here what variations you're getting in your printer setup.