Drucker-Status ermitteln
-
Guten Morgen,
ich wollte den Status der Drucker ermitteln, dazu habe ich folgenden Code geschrieben:
int GetPrinterInfo (wchar_t *str_printerName, HWND status, HWND location, HWND comment) { if (str_printerName == NULL) return EPSERR_NULLPOINTER; HANDLE printer; DEVMODE devMode = {0}; PRINTER_DEFAULTS printerDefaults = {0, &devMode, PRINTER_ACCESS_USE}; // or PRINTER_ALL_ACCESS OpenPrinter (str_printerName, &printer, &printerDefaults); LPPRINTER_INFO_2 printerInfo = NULL; DWORD neededBytes = 0, usedBytes = 0; if (GetPrinter (printer, 2, (LPBYTE) NULL, 0, &neededBytes) == 0) { if (GetLastError () == ERROR_INSUFFICIENT_BUFFER) { printerInfo = (LPPRINTER_INFO_2) malloc (neededBytes); if (GetPrinter (printer, 2, (LPBYTE) printerInfo, neededBytes, &usedBytes) == 0) return EPSERR_FAILEDTORETRIEVEINFO; SetWindowText (status, L"-"); if (printerInfo->Status & PRINTER_STATUS_BUSY) SetWindowText (status, L"Beschäftigt"); if (printerInfo->Status & PRINTER_STATUS_DOOR_OPEN) SetWindowText (status, L"Druckerklappe offen"); if (printerInfo->Status & PRINTER_STATUS_ERROR) SetWindowText (status, L"Fehler!"); if (printerInfo->Status & PRINTER_STATUS_NO_TONER) SetWindowText (status, L"Toner/Patrone leer"); [...] if (printerInfo->Status & PRINTER_STATUS_PROCESSING) SetWindowText (status, L"Nicht bereit"); if (printerInfo->Status & PRINTER_STATUS_USER_INTERVENTION) SetWindowText (status, L"Nicht bereit"); if (printerInfo->Status & PRINTER_STATUS_WAITING) SetWindowText (status, L"Nicht bereit"); SetWindowText (location, printerInfo->pLocation); SetWindowText (comment, printerInfo->pComment); free (printerInfo); } } ClosePrinter (printer); return EPSERR_NOERROR; }
Den Ort und Kommentar bekomme ich auch, allerdings ist printerInfo->Status immer 0. Liegt der Fehler auf meiner Seite oder ist winspool.drv/GetPrinter einfach nicht in der Lage, den Status zu ermitteln? Das die Einzelabfrage der Status(se) gerade nicht sinnvoll ist, ist mir bewusst. Allerdings bleibt das "-" eh stehen, so dass das gerade irrelevant ist. Habe das auch erfolglos mit verschiedenen Druckern probiert (verbundene, nicht verbundene, Netzwerkdrucker, etc.).
Ich hoffe, dass ich einfach zu blöd bin.
-
Zusatz: Kennt jemand eine andere Möglichkeit, mit der der echte Drucker-Status verwendet werden kann und bei der man eben nicht vom Windows-internen Spooling abhängig ist? Irgendwie schafft es Windows ja immerhin, wenigstens anzuzeigen, ob ein Drucker gerade angeschlossen ist oder nicht (wenn nicht, wird er unter Win 7 unter "Geräte und Drucker" ausgegraut angezeigt). Das würde eigentlich schon reichen.
-
Das ist der richtige Weg. Bei mir wird auch der Status korrekt ermittelt und angezeigt (Offline, Ready etc.)
Allerdings verwende ich oft EnumPrinters mit der PRIONTER_INFO_2.
-
Sehr eigenartig, wie ich finde. Bei mir ist und bleibt der Status auf 0 und springt auf keine Bitprüfung an (habe es nochmal mit EnumPrinters und PRINTER_INFO_2 getestet) ...
Hast du u.U. einen Ausschnitt von deinem Code, der genau dieses Abfrage macht oder einen Tipp, wo der Fehler dann liegt? Schaue ich mir andere Software an, erscheint der Status auch immer gleich. Egal ob angeschlossen oder nicht, bei PDF24 steht bspw. immer "Bereit". Daher bin ich davon ausgegangen, dass der "Fehler" darin liegt, dass die WinAPI von Haus aus nur auf das Spooling zurückgreifen kann und gar nicht ohne Druckjob an den Drucker kommt. Aber jedes mal einen Druckjob zu senden nur um herauszufinden, ob der Drucker off- oder online ist, finde ich sehr hässlich und meine ersten versuche lieferten auch nur mittelmäßige Erfolge (aber immerhin einen unwichtigen Status).
-
Was sol ich da schicken. Das ist ein Plain Aufruf von EnumPrinters
DWORD dwNeeded = 0;
DWORD dwReturned = 0;
DWORD i = 0;
LPPRINTER_INFO_2 pPrinters = NULL;
::EnumPrinters(PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL | PRINTER_ENUM_NETWORK, NULL, 2, NULL, 0, &dwNeeded, &dwReturned);
if (dwNeeded > 0)
{
LPBYTE pPrinterEnum = new BYTE[dwNeeded];if (!::EnumPrinters(PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL | PRINTER_ENUM_NETWORK, NULL, 2, pPrinterEnum, dwNeeded, &dwNeeded, &dwReturned))
{
delete [] pPrinterEnum;
pPrinterEnum = NULL;
}pPrinters = (LPPRINTER_INFO_2)pPrinterEnum;
}
-
Getestet mit gleichem Ergebnis. Status bleibt 0, keine Bitprüfung springt an. Auch Administratorrechte helfen im Übrigen nichts. Aber danke für den Code.