javaprintingjnaprint-spooler-apispooler

JNA - Get multiples OpenPrinter


I need a kind of help!

I have to get all information of a PrintJob (the last one). The problems is: My company's computers have more then one Printer per PC. So I need to monitor more than one printer at the Spooler level. I already tried so many logics and the last one was that:

Winspool.PRINTER_INFO_2[] printerInfo2 = WinspoolUtil.getPrinterInfo2();

    if (printerInfo2.length == 0)
        System.out.println( "Sem impressoas" );

    String[] printerNames = new String[printerInfo2.length];


    System.out.println();

    int arrayIndex = 0;
    for (Winspool.PRINTER_INFO_2 aPrinterInfo2 : printerInfo2) {
        printerNames[arrayIndex] = aPrinterInfo2.pPrinterName;

        //if (aPrinterInfo2.pPrinterName.startsWith( "\\" )) {
        //printerNames[arrayIndex] = aPrinterInfo2.pPrinterName.substring( 17 );
        //}
        arrayIndex++;
    }
    //endregion


    HANDLEByReference handleByReference = new HANDLEByReference();
    boolean[] printersOpened = new boolean[printerNames.length];
    arrayIndex = 0;
    for (String printerName : printerNames) {
        printersOpened[arrayIndex] = Winspool.INSTANCE.OpenPrinter( printerName, handleByReference, null );

        if (!printersOpened[arrayIndex]) {
            getLastError();
        }
        arrayIndex++;
    }

And i access the Printer:

WinNT.HANDLE chgObject = Winspool.INSTANCE.FindFirstPrinterChangeNotification( handleByReference.getValue(),
            Winspool.PRINTER_CHANGE_JOB, 0, null );

    if (chgObject != null) {
        while (true) {
            Kernel32.INSTANCE.WaitForSingleObject( chgObject, 1000 );
            WinDef.DWORDByReference pdwChange = new WinDef.DWORDByReference();
            boolean fcnreturn = Winspool.INSTANCE.FindNextPrinterChangeNotification( chgObject, pdwChange,
                    null, null );

            if (fcnreturn) {
                Winspool.JOB_INFO_1[] jobInfo1 = WinspoolUtil.getJobInfo1( handleByReference );

                for (Winspool.JOB_INFO_1 aJobInfo1 : jobInfo1) {
                    System.out.println( "-----------xx-----------" );
                    System.out.println( aJobInfo1.pDocument );
                    System.out.println( aJobInfo1.pPrinterName );
                    System.out.println( "-----------xx-----------" );
                }
                break;
            }
        }
    }

But I can only get the last instantiated printer ... If there was any way, via JNA, to capture which printer the user selected, I still have not found it.

So I ask: how can I monitor the spooler without relying on the printer?


Solution

  • You need to use EnumPrinters to get all printer names and monitor them all for changes.