views:

174

answers:

3

Is there a API or registry key which I can use from applications (native, Java or .Net) to check if the currently logged on user has configured a default printer?

Update: Many thanks for the answers so far! According to the KB article http://support.microsoft.com/kb/156212, the registry entry (read/write) is only documented up to Windows 2000. Is there a Win API method in newer versions for native access?

+3  A: 

In .NET this code works for me:

public static string DefaultPrinterName()
{
  string functionReturnValue = null;
  System.Drawing.Printing.PrinterSettings oPS 
    = new System.Drawing.Printing.PrinterSettings();

  try
  {
    functionReturnValue = oPS.PrinterName;
  }
  catch (System.Exception ex)
  {
    functionReturnValue = "";
  }
  finally
  {
    oPS = null;
  }
  return functionReturnValue;
}

From: http://in.answers.yahoo.com/question/index?qid=20070920032312AAsSaPx

Turek
Is `oPS = null` really required?
mjustin
No its not i think - I copied the code from the link without changing it (only to compile and check if it works)
Turek
+3  A: 

There is a Java API to get the default printer:

PrintService defaultPrinter = PrintServiceLookup.lookupDefaultPrintService();

It returns null if there is no default Printer or Service. That can be used as a test.


Old answer

The information can be found in the registry. You can't access the registry with plain Java, but there are JNDI solutions around for this problem. So basically you have to test, if a certain key exists in the registry. And, as a bonus, if you've come so far, you should even be able to get the name of the default printer :)

Further Reading:

Andreas_D
Downvote because there are perfectly fine APIs to determine this information without resorting to unsupported registry hacks (the information in the KB article claims support only up to Windows 2000).
Larry Osterman
@Larry - perfectly fine API in Java? Please, feel free to give an example. I like to learn something new.
Andreas_D
OP asked for .net or native as options. And I would hope that Java has printing APIs, doesn't it?
Larry Osterman
@Larry - thanks for the remarks - I've looked into Java and it looks like there Java support for detecting a default printer. Changed my answer.
Andreas_D
Very cool, removing my downvote.
Larry Osterman
+3  A: 

There is a function in the unmanaged Print Spooler API winspool.drv. You can call the GetDefaultPrinter function to return the name of the default printer.

This is the P/Invoke signature for the unmanaged function:

[DllImport("winspool.drv", CharSet=CharSet.Auto, SetLastError=true)]
private static extern bool GetDefaultPrinter(
    StringBuilder buffer,
    ref int bufferSize);

Use this function to determine whether a default printer is set:

    public static bool IsDefaultPrinterAssigned()
    {
        //initialise size at 0, used to determine size of the buffer
        int size = 0;

        //for first call provide a null StringBuilder and 0 size to determine buffer size
        //return value will be false, as the call actually fails internally setting the size to the size of the buffer
        GetDefaultPrinter(null, ref size);

        if (size != 0)
        {
            //default printer set
            return true;
        }

        return false;
    }

Use this function to return the default printer name, returns empty string if default is not set:

    public static string GetDefaultPrinterName()
    {
        //initialise size at 0, used to determine size of the buffer
        int size = 0;

        //for first call provide a null StringBuilder and 0 size to determine buffer size
        //return value will be false, as the call actually fails internally setting the size to the size of the buffer
        GetDefaultPrinter(null, ref size);

        if (size == 0)
        {
            //no default printer set
            return "";
        }

        StringBuilder printerNameStringBuilder = new StringBuilder(size);

        bool success = GetDefaultPrinter(printerNameStringBuilder, ref size);

        if (!success)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        return printerNameStringBuilder.ToString();
    }

Full code to test in a Console Application:

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;

namespace DefaultPrinter
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(IsDefaultPrinterAssigned());
            Console.WriteLine(GetDefaultPrinterName());
            Console.ReadLine();
        }

        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool GetDefaultPrinter(
            StringBuilder buffer,
            ref int bufferSize);

        public static bool IsDefaultPrinterAssigned()
        {
            //initialise size at 0, used to determine size of the buffer
            int size = 0;

            //for first call provide a null StringBuilder to and 0 size to determine buffer size
            //return value will be false, as the call actually fails internally setting the size to the size of the buffer
            GetDefaultPrinter(null, ref size);

            if (size != 0)
            {
                //default printer set
                return true;
            }

            return false;
        }

        public static string GetDefaultPrinterName()
        {
            //initialise size at 0, used to determine size of the buffer
            int size = 0;

            //for first call provide a null StringBuilder to and 0 size to determine buffer size
            //return value will be false, as the call actually fails internally setting the size to the size of the buffer
            GetDefaultPrinter(null, ref size);

            if (size == 0)
            {
                //no default printer set
                return "";
            }

            StringBuilder printerNameStringBuilder = new StringBuilder(size);

            bool success = GetDefaultPrinter(printerNameStringBuilder, ref size);

            if (!success)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return printerNameStringBuilder.ToString();
        }
    }
}
fletcher