Frage

Ich habe eine DLL geschrieben, die unsere netowork Drucker überwacht. Der Drucker ist mit dem Server über eine USB-Kabel verbunden ist. Wenn ich etwas direkt vom Server zu drucken, werden Informationen über Seiten richtig gesendet / gedruckt, aber wenn ich etwas von einem der Client-Computer drucken Sie es zeigt nur seine IP, gesendet / gedruckt ist immer 0.

Ich nehme an, dies ein Manko des winspooler API ist, meine Frage ist, gibt es eine Möglichkeit, um es?

Hier ist der Code, für das, was ihren Wert:

typedef struct PRINTERMONITOR_API tagPRINTJOBINFO
{
    // name of the machine that printed
    char *machineName;
    // name of the document
    char *document;
    // total pages actually *printed*
    DWORD totalPages;
    // number of pages sent to the printer
    DWORD printed;
    // private: state of the printJob
    BOOL  done;
} printJobInfo_t;

//-------------------------------------------------------
// Function called when the print job event finishes
//-------------------------------------------------------
typedef void (*Callback)(printJobInfo_t *);

//-------------------------------------------------------
// Printer Monitor class
//-------------------------------------------------------
class PrinterMonitor
{
private:

    //-------------------------------------------------------
    // Handle to the printer.
    //-------------------------------------------------------
    HANDLE                  m_hPrinter;

    //-------------------------------------------------------
    // Handle to the notify object being set when print event
    // occurs.
    //-------------------------------------------------------
    HANDLE                  m_hNotify;

    //-------------------------------------------------------
    // Handle of our worker thread.
    //-------------------------------------------------------
    HANDLE                  m_hThread;

    //-------------------------------------------------------
    // Holds PRINTER_CHANGE_XXX_XXX information about current
    // event.
    //-------------------------------------------------------
    DWORD                   m_dwChanged;

    //-------------------------------------------------------
    // ID of the worker thread.
    //-------------------------------------------------------
    DWORD                   m_dwThreadId;

    //-------------------------------------------------------
    // Name of the printer.
    //-------------------------------------------------------
    char                    *m_pszPrinterName;

    //-------------------------------------------------------
    // Printer event snooping options.
    //-------------------------------------------------------
    PRINTER_NOTIFY_OPTIONS  *m_pOptions;

    //-------------------------------------------------------
    // Output of the event function.
    //-------------------------------------------------------
    PRINTER_NOTIFY_INFO     *m_pOutPut; 

    //-------------------------------------------------------
    // Shall we go away?
    //-------------------------------------------------------
    BOOL                    m_fExit;

public:
    //-------------------------------------------------------
    // Callback function called when the event fires.
    //-------------------------------------------------------
    Callback                m_fpCallback;

    //-------------------------------------------------------
    // Constructor
    // - name of the printer
    // - callback function
    //-------------------------------------------------------
    PrinterMonitor(char *printerName, Callback callback)
    {
        memset(this, 0, sizeof(PrinterMonitor)); // zero me
        m_fpCallback        = callback;
        m_pszPrinterName    = new char[strlen(printerName)];
        strcpy(m_pszPrinterName, printerName);
        m_pOptions          = new PRINTER_NOTIFY_OPTIONS;
        m_hThread           = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PrinterMonitor::StartMonitoring, this, CREATE_SUSPENDED, &m_dwThreadId);
    }

    //-------------------------------------------------------
    // Stop the worker thread and delete some shit
    //-------------------------------------------------------
    ~PrinterMonitor()
    {
        StopMonitor();
        delete(m_pOptions);
        delete[](m_pszPrinterName);
    }

    //-------------------------------------------------------
    // Run the monitor in a seperate thread
    //-------------------------------------------------------
    void RunMonitor()
    {
        ResumeThread(m_hThread);
    }

    //-------------------------------------------------------
    // Stop the monitor, noes.
    //-------------------------------------------------------
    void StopMonitor()
    {
        m_fExit = true;
    }

    //-------------------------------------------------------
    // Checks if this object is a valid monitor
    //-------------------------------------------------------
    BOOL CheckMonitor()
    {
        if(OpenPrinter(this->m_pszPrinterName, &this->m_hPrinter, NULL))
        {
            if(this->m_hPrinter != INVALID_HANDLE_VALUE)
            {
                ClosePrinter(this->m_hPrinter);
                return true;
            }
        }

        return false;
    }

private:
    //-------------------------------------------------------
    // The worker thread proc
    //-------------------------------------------------------
    static void WINAPI StartMonitoring(void *thisPtr)
    {

        PrinterMonitor* pThis = reinterpret_cast<PrinterMonitor*>(thisPtr);

        if(OpenPrinter(pThis->m_pszPrinterName, &pThis->m_hPrinter, NULL))
        {
            WORD wJobFields[5];
            wJobFields[0]           = JOB_NOTIFY_FIELD_STATUS;
            wJobFields[1]           = JOB_NOTIFY_FIELD_MACHINE_NAME;
            wJobFields[2]           = JOB_NOTIFY_FIELD_TOTAL_PAGES;
            wJobFields[3]           = JOB_NOTIFY_FIELD_PAGES_PRINTED;
            wJobFields[4]           = JOB_NOTIFY_FIELD_DOCUMENT;

            PRINTER_NOTIFY_OPTIONS_TYPE rOptions[1];
            rOptions[0].Type    = JOB_NOTIFY_TYPE;
            rOptions[0].pFields = &wJobFields[0];
            rOptions[0].Count   = 5;

            pThis->m_pOptions->Count    = 1;
            pThis->m_pOptions->Version  = 2;
            pThis->m_pOptions->pTypes   = rOptions;
            pThis->m_pOptions->Flags    = PRINTER_NOTIFY_OPTIONS_REFRESH;

            if((pThis->m_hNotify = 
                FindFirstPrinterChangeNotification(pThis->m_hPrinter, 0, 0, pThis->m_pOptions)) != INVALID_HANDLE_VALUE)
            {
                while(pThis->m_hNotify != INVALID_HANDLE_VALUE && !pThis->m_fExit)
                {
                    if(WaitForSingleObject(pThis->m_hNotify, 10) == WAIT_OBJECT_0)
                    {
                        FindNextPrinterChangeNotification(pThis->m_hNotify, &pThis->m_dwChanged, (LPVOID)pThis->m_pOptions, (LPVOID*)&pThis->m_pOutPut);

                        printJobInfo_t info = {0};
                        for (unsigned int i=0; i < pThis->m_pOutPut->Count; i++)
                        {
                            PRINTER_NOTIFY_INFO_DATA data = pThis->m_pOutPut->aData[i];

                            if(data.Type == JOB_NOTIFY_TYPE)
                            {
                                switch(data.Field
                                {
                                    case JOB_NOTIFY_FIELD_PAGES_PRINTED:
                                        {
                                            info.printed = data.NotifyData.adwData[0];
                                        }
                                        break;

                                    case JOB_NOTIFY_FIELD_MACHINE_NAME:
                                        {
                                            LPSTR name = (LPSTR) data.NotifyData.Data.pBuf;
                                            unsigned int length = strlen(name); 
                                            info.machineName = new char[length];
                                            strcpy(info.machineName, name);                                         
                                        }
                                        break;

                                    case JOB_NOTIFY_FIELD_TOTAL_PAGES:
                                        {
                                            info.totalPages = data.NotifyData.adwData[0];
                                        }
                                        break;

                                    case JOB_NOTIFY_FIELD_DOCUMENT:
                                        {
                                            LPSTR document = (LPSTR) data.NotifyData.Data.pBuf;
                                            unsigned int length = strlen(document);
                                            info.document = new char[length];
                                            strcpy(info.document, document);                                            
                                        }
                                        break;

                                    case JOB_NOTIFY_FIELD_STATUS:
                                        {
                                            if(data.NotifyData.adwData[0] & JOB_STATUS_PRINTED)
                                            {
                                                info.done = true;
                                            }
                                        }
                                        break;
                                }
                            }
                        }

                        if(info.done)
                        {
                            pThis->m_fpCallback(&info);

                            delete[](info.document);
                            delete[](info.machineName);
                        }
                    }
                }

                if(pThis->m_hPrinter != INVALID_HANDLE_VALUE)
                    ClosePrinter(pThis->m_hPrinter);

                if(pThis->m_hNotify != INVALID_HANDLE_VALUE)
                    FindClosePrinterChangeNotification(pThis->m_hNotify);

            }
        }
    }
};
War es hilfreich?

Lösung

Haben Sie es. Der Netzwerkdrucker sendet nur grundlegende Informationen, wenn es wurde von Windows automatisch hinzugefügt.

Das Hinzufügen der Drucker manuell das Problem behoben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top