mburakerbay
mburakerbay

Reputation: 63

How to get all printer name in windows service?

I want to get all printer name installed on computer and network. I used these function in below to get list of all printer. All these func. is working correctly in console and form application and i can get list of all printer but when i try to use these func. in windows service i can get only installed on the computer with out network. And also my service working under LocalSystem account.

Func 1:

        WinsPool.PrinterEnumFlags Flags = WinsPool.PrinterEnumFlags.PRINTER_ENUM_CONNECTIONS | WinsPool.PrinterEnumFlags.PRINTER_ENUM_LOCAL;
        const int ERROR_INSUFFICIENT_BUFFER = 122;
        uint cbNeeded = 0;
        uint cReturned = 0;
        if (WinsPool.EnumPrinters(Flags, null, 2, IntPtr.Zero, 0, ref cbNeeded, ref cReturned))
        {
            return null;
        }
        int lastWin32Error = Marshal.GetLastWin32Error();
        if (lastWin32Error == ERROR_INSUFFICIENT_BUFFER)
        {
            IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);
            if (WinsPool.EnumPrinters(Flags, null, 2, pAddr, cbNeeded, ref cbNeeded, ref cReturned))
            {
                WinsPool.PRINTER_INFO_2[] printerInfo2 = new WinsPool.PRINTER_INFO_2[cReturned];
                int offset = pAddr.ToInt32();
                Type type = typeof(WinsPool.PRINTER_INFO_2);
                int increment = Marshal.SizeOf(type);
                for (int i = 0; i < cReturned; i++)
                {
                    printerInfo2[i] = (WinsPool.PRINTER_INFO_2)Marshal.PtrToStructure(new IntPtr(offset), type);
                   string printerName =  printerInfo2[i].pPrinterName;
                    offset += increment;
                }
                Marshal.FreeHGlobal(pAddr);
            }
            lastWin32Error = Marshal.GetLastWin32Error();
        }

Func 2:

        foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
        {
            string printerName = printer;
        }

Func 3:

            ManagementObjectSearcher searcher = 
                new ManagementObjectSearcher("root\\CIMV2", 
                "SELECT * FROM Win32_Printer"); 

            foreach (ManagementObject queryObj in searcher.Get())
            {
               string printerName = queryObj["Name"].ToString();
            }

Upvotes: 1

Views: 2607

Answers (3)

Jo&#227;o Ferreira
Jo&#227;o Ferreira

Reputation: 68

I know this was years ago... but I had the same problem today and finally fixed it...

Go to your ServiceProcessInstaller properties and change on the misc tab, account to user.

After this, whenever u're installing the service you'll be prompted to enter a user add a password to your user first and login like this:

<machine_name>\<user_name>
<password>
<password_again>

Upvotes: 0

Alyafey
Alyafey

Reputation: 1453

Here is how to start :

public partial class Service : ServiceBase
{
    List<string> printers = new List<string>();
    public Service()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        getPrinters();
    }

    private void getPrinters()
    {
        foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
        {
            printers.Add(printer);
        }

    }

    static void Main()
    {
        (new Service()).OnStart(null); // allows easy debugging of OnStart()
    }

Upvotes: 1

Polyfun
Polyfun

Reputation: 9639

Printers are often installed to a specific Windows account, so they will only be visible if you log in as that account. For a Windows service that need access to printers, it is normal to run it as a named account for which the required printers are visible, i.e., do not run it as LocalSystem.

Upvotes: 3

Related Questions