93

I need to get the default printer name. I'll be using C# but I suspect this is more of a framework question and isn't language specific.

Kevin Gale
  • 4,350
  • 6
  • 30
  • 31

7 Answers7

153

The easiest way I found is to create a new PrinterSettings object. It starts with all default values, so you can check its Name property to get the name of the default printer.

PrinterSettings is in System.Drawing.dll in the namespace System.Drawing.Printing.

PrinterSettings settings = new PrinterSettings();
Console.WriteLine(settings.PrinterName);

Alternatively, you could maybe use the static PrinterSettings.InstalledPrinters method to get a list of all printer names, then set the PrinterName property and check the IsDefaultPrinter. I haven't tried this, but the documentation seems to suggest it won't work. Apparently IsDefaultPrinter is only true when PrinterName is not explicitly set.

OwenP
  • 24,950
  • 13
  • 65
  • 102
  • 6
    Maybe it is worth to mention that the strings returned from InstalledPrinters may have a different casing than the PrinterName property. For example this test failed on my System: Dim ps As New PrinterSettings Dim foundDefault As Boolean = False For Each printer As String In PrinterSettings.InstalledPrinters If printer = ps.PrinterName Then foundDefault = True End If Next Assert.IsTrue(foundDefault) – miasbeck May 09 '11 at 10:28
  • 1
    Here is the looping technique, which works for me. : foreach (string name in PrinterSettings.InstalledPrinters) { PrinterSettings ps = new PrinterSettings(); ps.PrinterName = name; if (ps.IsDefaultPrinter) return name; } return null; – BrokeMyLegBiking Mar 18 '13 at 21:08
  • 1
    Be advised that this methods does not work if you run your app as a windows service. I haven't figured out why. I'm running as a local service. – Rudy Hinojosa Apr 14 '17 at 13:26
  • @BrokeMyLegBiking That should not work [according to MSDN](https://msdn.microsoft.com/en-us/library/system.drawing.printing.printersettings.isdefaultprinter(v=vs.110).aspx): "IsDefaultPrinter always returns false when you explicitly set the PrinterName property to a string value other than null." – jnm2 Jul 20 '17 at 17:17
  • You can condense this to 'string pName = new PrinterSettings().PrinterName;' – PKanold Nov 19 '19 at 15:35
  • 1
    @Rudy Hinojosa maybe this has something to do with your issue? "Classes within the System.Printing namespace are **not supported for use within a Windows service or ASP.NET application or service**. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions."([MSDN docs](https://learn.microsoft.com/en-us/dotnet/api/system.printing?view=netframework-4.7.2)) – jarmanso7 Mar 19 '20 at 13:55
32

Another approach is using WMI (you'll need to add a reference to the System.Management assembly):

public static string GetDefaultPrinterName()
{
    var query = new ObjectQuery("SELECT * FROM Win32_Printer");
    var searcher = new ManagementObjectSearcher(query);

    foreach (ManagementObject mo in searcher.Get())
    {
        if (((bool?) mo["Default"]) ?? false)
        {
            return mo["Name"] as string;
        }
    }

    return null;
}
Nathan Baulch
  • 20,233
  • 5
  • 52
  • 56
  • 3
    Using the new PrinterSettings().PrinterName sometimes returns "Default printer is not set" as the printer name, even when the default printer HAS been set. The above WMI solution from Nathan Baulch worked for me in a situation like that. – Peter Jul 27 '12 at 07:21
  • This code requires a reference to System.Management and a using System.Management; – j2associates Jul 03 '22 at 21:16
13

If you just want the printer name no advantage at all. But WMI is capable of returning a whole bunch of other printer properties:

using System;
using System.Management;
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            ObjectQuery query = new ObjectQuery(
                "Select * From Win32_Printer " +
                "Where Default = True");

            ManagementObjectSearcher searcher =
                new ManagementObjectSearcher(query);

            foreach (ManagementObject mo in searcher.Get())
            {
                Console.WriteLine(mo["Name"] + "\n");

                foreach (PropertyData p in mo.Properties)
                {
                    Console.WriteLine(p.Name );
                }
            }
        }
    }
}

and not just printers. If you are interested in any kind of computer related data, chances are you can get it with WMI. WQL (the WMI version of SQL) is also one of its advantages.

11

I use always in this case the System.Printing.LocalPrintServer, which makes also possible to obtain whether the printer is local, network or fax.

string defaultPrinter;
using(var printServer = new LocalPrintServer()) {
  defaultPrinter = printServer.DefaultPrintQueue.FullName);
}

or using a static method GetDefaultPrintQueue

LocalPrintServer.GetDefaultPrintQueue().FullName
Alexander Zwitbaum
  • 4,776
  • 4
  • 48
  • 55
4

Try also this example

 PrinterSettings printerName = new PrinterSettings();

 string defaultPrinter;

 defaultPrinter = printerName.PrinterName;
Ramgy Borja
  • 2,330
  • 2
  • 19
  • 40
2

This should work:

using System.Drawing.Printing;

PrinterSettings settings = new PrinterSettings(); string defaultPrinterName = settings.PrinterName;

Tahir Rehman
  • 332
  • 2
  • 9
0
  • 1st create an instance of the PrintDialog object.
  • then call the print dialog object and leave the PrinterName blank. this will cause the windows object to return the defualt printer name
  • write this to a string and use it as the printer name when you call the print procedure

Code:

Try

    Dim _printDialog As New System.Windows.Forms.PrintDialog

    xPrinterName = _printDialog.PrinterSettings.PrinterName '= "set as Default printer"

Catch ex As Exception
    System.Windows.Forms.MessageBox.Show("could not printed Label.", "Print Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Joe McBride
  • 3,789
  • 2
  • 34
  • 38