Installer un processeur d’impression

Pour installer un processeur d’impression, une application d’installation doit appeler la fonction AddPrintProcessor du spouleur. Pour associer un processeur d’impression à une file d’attente d’impression, répertoriez son nom de fichier dans un fichier INF dans une entrée PrintProcessor. Cette entrée doit être incluse pour chaque file d’attente d’impression à laquelle le processeur d’impression doit être associé. Pour plus d’informations, consultez Fichiers INF d’imprimante.

Lorsqu’une application d’installation appelle la fonction AddPrinter du spouleur , en utilisant une structure {PRINTER_INFO_2](/windows/win32/printdocs/printer-info-2) comme argument d’entrée, elle spécifie le nom du processeur d’impression (obtenu à partir du fichier INF) en tant que membre de la structure.

Association d’un processeur d’impression à une file d’attente d’impression installée par pnp

Si le gestionnaire Plug-and-Play (PnP) détecte et installe une file d’attente d’impression sur un système exécutant Windows 2000 ou Windows XP, et si le fichier INF utilisé pour installer la file d’attente d’impression contient une entrée PrintProcessor autre que le processeur d’impression Windows par défaut, WinPrint, le processeur d’impression n’est pas associé à la file d’attente d’impression. Toutefois, le processeur d’impression sera installé.

Notez que si vous installez la file d’attente d’impression à l’aide de l’Assistant Ajouter une imprimante, le processeur d’impression est correctement associé à la file d’attente d’impression.

Notez également que le gestionnaire PnP dans Microsoft Windows Server 2003 et versions ultérieures associe correctement un processeur d’impression à la file d’attente d’impression.

Pour associer le processeur d’impression à la file d’attente d’impression pour Plug-and-Play installations sur Windows 2000 et Windows XP, incluez un cas PRINTER_EVENT_INITIALIZE dans la fonction DrvPrinterEvent de la DLL d’imprimante. Pour Microsoft Windows Server 2003 et versions ultérieures, il n’est pas nécessaire d’ajouter un cas de PRINTER_EVENT_INITIALIZE dans la fonction DrvPrinterEvent .

L’exemple de code suivant définit le membre pPrintProcessor de la structure PRINTER_INFO_2 sur le nom de votre processeur d’impression, puis appelle la fonction SetPrinter pour mettre à jour les paramètres de l’imprimante. Notez que le nom du processeur d’impression dans gszPrintProc doit être identique à celui de l’entrée PrintProcessor de votre fichier 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;
}

Association d’un processeur d’impression à une file d’attente d’impression pendant la mise à niveau du pilote d’imprimante

Lorsqu’un pilote d’imprimante est mis à jour, le processeur d’impression de la file d’attente d’impression mise à jour n’est pas modifié. Si le nouveau pilote d’imprimante nécessite un processeur d’impression particulier, la fonction DrvUpgradePrinter de la DLL d’imprimante doit définir le nom du nouveau processeur d’impression au membre pPrintProcessor de la structure PRINTER_INFO_2. Après cela, cette fonction appelle SetPrinter pour mettre à jour les paramètres de l’imprimante. Le spouleur appelle la fonction DrvUpgradePrinter une fois pour chaque imprimante, ce qui garantit que toutes les imprimantes utilisant ce pilote utilisent également le processeur d’impression requis. L’exemple de code suivant illustre ces points.

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