views:

126

answers:

0

I maintain an application running on Windows that allows the user to specify that certain reports are always sent to a specific printer.

I am currently storing PRINTER_INFO_2::pPrinterName for each configured report into the registry. When the report is run, I use EnumPrinters() to locate the correct printer and pass the appropriate values to the reporting engine.

This works very well until users try to configure reports to print to terminal services redirected printers, since the printer names are no longer stable. On Windows 2008 the printer name becomes something like "LaserJet 1234 (redirected 42)"

What is the most reliable method for reselecting the correct printer? Note that a different user may also be connected and redirecting to an entirely different LaserJet1234, and I need to know which belongs to the current user.

Some code would probably be illustrative:

void SetupReportPrinter( Report& r, const QString& printer_name )
{
    if( printer_name != r.printerName() )
    {
        // Report printer does not match selected printer...
        DWORD bufsize = 0, count = 0;
        EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &bufsize, &count);
        BYTE* buf = new BYTE[ bufsize ];
        if( EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,
                    NULL, 2, buf, bufsize, &bufsize, &count) )
        {
            for(DWORD i = 0; i < count; ++i)
            {
                PRINTER_INFO_2* pinfo = &reinterpret_cast<PRINTER_INFO_2*>( buf )[i];
                if( printer_name == pinfo->pPrinterName )
                {
                    r.selectPrinter( pinfo->pDriverName, pinfo->pPrinterName, pinfo->pPortName );
                    break;
                }
            }
        }
        delete [] buf;
    }
}