1

I am writing an application to check if a network printer from a print server is connected to a remote machine, but having trouble with the remote part... I'm using System.Printing and passing in the remote hostname/IP address through the 'compID' variable. The problem I'm having is that the code always returns the networked printers on my LOCAL machine rather than the remote machine:

EnumeratedPrintQueueTypes[] compEnumerationFlags = { EnumeratedPrintQueueTypes.Connections };

PrintServer compPrinters = new PrintServer("\\\\" + compID);
PrintQueueCollection printQueuesOnComputer = compPrinters.GetPrintQueues(compEnumerationFlags);

List<string> compPrinterList = new List<string>();

foreach (PrintQueue printer in printQueuesOnComputer)
    {
        compPrinterList.Add(printer.Name);
    }

string csv = string.Join("\n", compPrinterList.ToArray());
Microsoft.VisualBasic.Interaction.MsgBox(csv);

Forgive the messy bit at the end there, but it's just a quick and dirty way for me to see what the results are for the moment.

The strange thing is that if I change the 'compID' variable to our actual print server and change the flags from "Connections' to 'Shared', then the code successfully returns all the shared printers from our print server.

All this is running as an admin on our domain, so that should hopefully not be an issue here. Is there something simple I'm overlooking or is there some sort of restriction on the types of machines I can connect to with PrintServer?

cmode
  • 11
  • 1
  • 5
  • Where do you setup compID? – TheKingDave May 03 '13 at 12:55
  • From a textbox earlier on. But even if I hardcode an IP Address/Hostname in "PrintServer compPrinters = new PrintServer("\\\\xxx.xxx.xxx.xxx");" - then I get exactly the same problem – cmode May 03 '13 at 12:59
  • Then is must be the flags ? You said :The strange thing is that if I change the 'compID' variable to our actual print server and change the flags from "Connections' to 'Shared', then the code successfully returns all the shared printers from our print server. So it is either the compID or the flags that is causing it ? – TheKingDave May 03 '13 at 13:01
  • Sorry for the confusion. It looks like it's the flags causing this. With `compID` set to our actual print server and the flags set to `EnumeratedPrintQueueTypes.Connections`, I get the connected printers on my local machine. But setting the flags to `EnumeratedPrintQueueTypes.Shared`, I get all the shared printers on the print server. Do you know if the Connections flag always default back to a local machine? – cmode May 03 '13 at 13:10
  • try EnumeratedPrintQueueTypes.Connections, EnumeratedPrintQueueTypes.Shared ? If not then you problably need to check if compID is a local then pass the appropriate flag. – TheKingDave May 03 '13 at 13:31
  • This should help you get if it is a localhost: http://www.csharp-examples.net/local-ip/ – TheKingDave May 03 '13 at 13:32
  • Well I'm trying to check a remote PC so that means `compID` will never be a localhost... – cmode May 03 '13 at 13:56
  • Putting it simply: with `compID` set to a remote PC, and the flags set to either `Shared` or `Local`, then I can get the printers of that type from that machine. It's only when I set the flags to `Connections` that it reverts back to my local machine – cmode May 03 '13 at 13:57
  • I wonder if this: http://stackoverflow.com/questions/4018378/how-to-get-system-printing-printserver-getprintqueues-to-return-the-print-queue will help you ... – TheKingDave May 03 '13 at 15:06

1 Answers1

0

So I have a workaround which seems to do the job well enough after a bit of testing. The printers would have been connected to the machine at somepoint using rundll32 printui.dll,PrintUIEntry /ga /c\\%computername% /n\\%printserver%\%printername%

In the application I've imported printui.dll:

[DllImport("printui.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern void PrintUIEntryW(IntPtr hwnd, IntPtr hinst, string lpszCmdLine, int nCmdShow);

Then later I use the /ge flag on the remote machine to list all per-machine connections, output that to a temp text file, then check to see if the printer name is contained in the text file:

PrintUIEntryW(IntPtr.Zero, IntPtr.Zero, "/c \\\\" + compID + " /ge /q /f c:\\temp\\printers.txt", 0);

string file = File.ReadAllText("c:\\temp\\printers.txt");
if (file.Contains(printerID))
{
    exist = true;
}
File.Delete("c:\\temp\\printers.txt");

I'm aware this probably isn't the best way to go about it, but it seems to work in the environment I operate in, so I'm providing this as an answer.

cmode
  • 11
  • 1
  • 5