Condividi tramite


Installare un processore di stampa

Per installare un processore di stampa, un'applicazione di installazione deve chiamare la funzione AddPrintProcessor dello spooler. Per associare un processore di stampa a una coda di stampa, elencare il nome del file in un file INF in una voce PrintProcessor. Questa voce deve essere inclusa per ogni coda di stampa a cui deve essere associato il processore di stampa. Per altre informazioni, vedere File INF della stampante.

Quando un'applicazione di installazione chiama la funzione AddPrinter dello spooler , usando una struttura {PRINTER_INFO_2](/windows/win32/printdocs/printer-info-2) come argomento di input, specifica il nome del processore di stampa (ottenuto dal file INF) come membro della struttura.

Associazione di un processore di stampa a una coda di stampa installata da pnp

Se il gestore Plug and Play (PnP) rileva e installa una coda di stampa in un sistema che esegue Windows 2000 o Windows XP e se il file INF utilizzato per installare la coda di stampa contiene una voce PrintProcessor diversa dal processore di stampa windows predefinito, WinPrint, il processore di stampa non verrà associato alla coda di stampa. Tuttavia, verrà installato il processore di stampa.

Si noti che se si installa la coda di stampa utilizzando la procedura guidata Aggiungi stampante, il processore di stampa è associato correttamente alla coda di stampa.

Si noti anche che il gestore PnP in Microsoft Windows Server 2003 e versioni successive associa correttamente un processore di stampa alla coda di stampa.

Per associare il processore di stampa alla coda di stampa per le installazioni di Plug and Play in Windows 2000 e Windows XP, includere un caso PRINTER_EVENT_INITIALIZE nella funzione DrvPrinterEvent dell'interfaccia della stampante. Per Microsoft Windows Server 2003 e versioni successive, non è necessario aggiungere un PRINTER_EVENT_INITIALIZE caso nella funzione DrvPrinterEvent .

Nell'esempio di codice seguente il membro pPrintProcessor della struttura PRINTER_INFO_2 viene impostato sul nome del processore di stampa e quindi chiama la funzione SetPrinter per aggiornare le impostazioni della stampante. Si noti che il nome del processore di stampa in gszPrintProc deve corrispondere a quello nella voce PrintProcessor nel file INF.

BOOL
DrvPrinterEvent(
               LPWSTR  pPrinterName,
               INT     Event,
               DWORD   Flags,
               LPARAM  lParam
               )

{
  PRINTER_DEFAULTS  PrinterDef = {NULL, NULL, PRINTER_ALL_ACCESS};
  HANDLE            hPrinter;
  LPPRINTER_INFO_2  pInfo = NULL;
  DWORD             cbNeeded;
  TCHAR             gszPrintProc[] = TEXT("<Print processor name>");
  BOOL              bRet = TRUE;

  switch (Event)
  {
    case PRINTER_EVENT_INITIALIZE:
      if (OpenPrinter(pPrinterName, &hPrinter, &PrinterDef))
      {
        if ( !GetPrinter( hPrinter, 2, (LPBYTE) pInfo, 0, &cbNeeded ) &&
           (GetLastError() != ERROR_INSUFFICIENT_BUFFER) )
        {
          bRet = FALSE;
        }
        if (bRet == TRUE)
        {
          pInfo = (LPPRINTER_INFO_2) LocalAlloc(LPTR, cbNeeded);
          bRet = pInfo ? TRUE : FALSE;
        }
        if (bRet == TRUE)
        {
          if (GetPrinter(hPrinter, 2, (LPBYTE) pInfo, cbNeeded, &cbNeeded))
          {
            pInfo->pPrintProcessor = gszPrintProc;
            SetPrinter(hPrinter, 2, (LPBYTE) pInfo, 0);
          }
          else 
          {
            bRet = FALSE;
          }
          if (pInfo)
          {
            LocalFree(pInfo);
          }
        }
        ClosePrinter(hPrinter);
      }
      else  // OpenPrinter failed
      {
        bRet = FALSE;
      }
    break;
    // cases for other events

    default:
      break;
  }  // end switch
  return bRet;
}

Associazione di un processore di stampa a una coda di stampa durante l'aggiornamento del driver della stampante

Quando viene aggiornato un driver della stampante, il processore di stampa della coda di stampa aggiornata non viene modificato. Se il nuovo driver della stampante richiede un processore di stampa specifico, la funzione DrvUpgradePrinter della DLL dell'interfaccia della stampante deve impostare il membro pPrintProcessor della struttura PRINTER_INFO_2 sul nome del nuovo processore di stampa. Al termine, questa funzione chiama SetPrinter per aggiornare le impostazioni della stampante. Lo spooler chiama la funzione DrvUpgradePrinter una volta per ogni stampante, assicurando che tutte le stampanti che usano tale driver usino anche il processore di stampa richiesto. Nell'esempio di codice seguente vengono illustrati questi punti.

BOOL
DrvUpgradePrinter(
                 DWORD   Level,
                 LPBYTE  pDriverUpgradeInfo
                 )
{
  HANDLE                  hPrinter;
  PRINTER_DEFAULTS        PrinterDef = {NULL, NULL, PRINTER_ALL_ACCESS};
 PDRIVER_UPGRADE_INFO_2  pDUI2;
  LPPRINTER_INFO_2        pInfo = NULL;
 DWORD                   cbNeeded;
  TCHAR                   gszPrintProc[]   = TEXT("<Print processor name>");
  TCHAR                   gszPrintDriver[] = TEXT("<Printer driver name>");
  BOOL                    bRet = TRUE;

  if ((Level == 2)                                            &&
      (pDUI2 = (PDRIVER_UPGRADE_INFO_2)pDriverUpgradeInfo)    &&
      (OpenPrinter(pDUI2->pPrinterName, &hPrinter, &PrinterDef)))
  {
    if ( !GetPrinter( hPrinter, 2, (LPBYTE) pInfo, 0, &cbNeeded )  &&
         (GetLastError() != ERROR_INSUFFICIENT_BUFFER) )
    {
       bRet = FALSE;
    }
    if (bRet == TRUE)
    {
      pInfo = (LPPRINTER_INFO_2) LocalAlloc(LPTR, cbNeeded);
      bRet = pInfo ? TRUE : FALSE;
    }
    if (bRet == TRUE)
    {
      if (GetPrinter(hPrinter, 2, (LPBYTE) pInfo, cbNeeded, &cbNeeded))
      {
      //
      // This function is called for every printer queue that uses a driver
      // for which one or more files were updated. However, we only want to
      // update the printer queue's "driver" by a particular driver.
      //
      if ( !lstrcmpi(pInfo->pDriverName, gszPrintDriver) )
      {
        pInfo->pPrintProcessor =  gszPrintProc;
        SetPrinter(hPrinter, 2, (LPBYTE) pInfo, 0);
      }
    else  // GetPrinter 
    {
      bRet = FALSE;
    }
    if (pInfo)
    {
      LocalFree(pInfo);
    }
    ClosePrinter(hPrinter);
  }
  else  // Level != 2 or pDUI2 == NULL or OpenPrinter failed
  {
    bRet = FALSE;
  }
  return bRet;
}