Compartilhar via


Instalar um processador de impressão

Para instalar um processador de impressão, um aplicativo de instalação deve chamar a função AddPrintProcessor do spooler. Para associar um processador de impressão a uma fila de impressão, liste seu nome de arquivo em um arquivo INF em uma entrada printProcessor. Essa entrada deve ser incluída para cada fila de impressão à qual o processador de impressão deve ser associado. Para obter mais informações, consulte Arquivos INF da impressora.

Quando um aplicativo de instalação chama a função AddPrinter do spooler , usando uma estrutura {PRINTER_INFO_2](/windows/win32/printdocs/printer-info-2) como um argumento de entrada, ele especifica o nome do processador de impressão (obtido do arquivo INF) como um membro da estrutura.

Associando um processador de impressão a uma fila de impressão instalada por pnp

Se o gerenciador de Plug and Play (PnP) detectar e instalar uma fila de impressão em um sistema que executa o Windows 2000 ou o Windows XP e se o arquivo INF usado para instalar a fila de impressão contiver uma entrada printProcessor diferente do processador de impressão padrão do Windows, WinPrint, o processador de impressão não será associado à fila de impressão. No entanto, o processador de impressão será instalado.

Observe que, se você instalar a fila de impressão usando o assistente Adicionar Impressora, o processador de impressão estará corretamente associado à fila de impressão.

Observe também que o gerenciador PnP no Microsoft Windows Server 2003 e posterior associa corretamente um processador de impressão à fila de impressão.

Para associar o processador de impressão à fila de impressão para instalações Plug and Play no Windows 2000 e no Windows XP, inclua um caso de PRINTER_EVENT_INITIALIZE na função DrvPrinterEvent da interface da impressora. Para o Microsoft Windows Server 2003 e posterior, não é necessário adicionar um caso de PRINTER_EVENT_INITIALIZE na função DrvPrinterEvent .

O exemplo de código a seguir define o membro pPrintProcessor da estrutura PRINTER_INFO_2 como o nome do processador de impressão e, em seguida, chama a função SetPrinter para atualizar as configurações da impressora. Observe que o nome do processador de impressão em gszPrintProc deve ser o mesmo que na entrada PrintProcessor no arquivo 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;
}

Associar um processador de impressão a uma fila de impressão durante a atualização do driver de impressora

Quando um driver de impressora é atualizado, o processador de impressão da fila de impressão atualizada não é alterado. Se o novo driver de impressora exigir um processador de impressão específico, a função DrvUpgradePrinter da interface da impressora deverá definir o membro pPrintProcessor da estrutura PRINTER_INFO_2 como o nome do novo processador de impressão. Depois que isso ocorrer, essa função chamará SetPrinter para atualizar as configurações da impressora. O spooler chama a função DrvUpgradePrinter uma vez para cada impressora, o que garante que todas as impressoras que usam esse driver também usem o processador de impressão necessário. O exemplo de código a seguir demonstra esses pontos.

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;
}