Freigeben über


Installieren eines Druckprozessors

Um einen Druckprozessor zu installieren, muss eine Installationsanwendung die AddPrintProcessor-Funktion des Spoolers aufrufen. Um einen Druckprozessor einer Druckwarteschlange zuzuordnen, listen Sie dessen Dateinamen in einer INF-Datei in einem PrintProcessor-Eintrag auf. Dieser Eintrag muss für jede Druckwarteschlange enthalten sein, der der Druckprozessor zugeordnet werden soll. Weitere Informationen finden Sie unter Drucker-INF-Dateien.

Wenn eine Installationsanwendung die AddPrinter-Funktion des Spoolers mit einer {PRINTER_INFO_2](/windows/win32/printdocs/printer-info-2)-Struktur als Eingabeargument aufruft, gibt sie den Druckprozessornamen (aus der INF-Datei abgerufen) als Strukturelement an.

Zuordnen eines Druckprozessors zu einer pnp-installierten Druckwarteschlange

Wenn der PnP-Manager (Plug & Play) eine Druckwarteschlange auf einem System mit Windows 2000 oder Windows XP erkennt und installiert, und wenn die zum Installieren der Druckwarteschlange verwendete INF-Datei einen anderen PrintProcessor-Eintrag als den Windows-Standarddruckprozessor WinPrint enthält, wird der Druckprozessor nicht der Druckwarteschlange zugeordnet. Der Druckprozessor wird jedoch installiert.

Beachten Sie, dass der Druckprozessor ordnungsgemäß der Druckwarteschlange zugeordnet ist, wenn Sie die Druckwarteschlange mithilfe des Assistenten zum Hinzufügen des Druckers installieren.

Beachten Sie außerdem, dass der PnP-Manager in Microsoft Windows Server 2003 und höher einen Druckprozessor ordnungsgemäß mit der Druckwarteschlange verknüpft.

Um den Druckprozessor der Druckwarteschlange für Plug & Play Installationen unter Windows 2000 und Windows XP zuzuordnen, fügen Sie einen PRINTER_EVENT_INITIALIZE Fall in die DrvPrinterEvent-Funktion der Druckerschnittstellen-DLL ein. Für Microsoft Windows Server 2003 und höher ist es nicht erforderlich, einen PRINTER_EVENT_INITIALIZE Fall in der DrvPrinterEvent-Funktion hinzuzufügen.

Im folgenden Codebeispiel wird das pPrintProcessor-Element der PRINTER_INFO_2-Struktur auf den Namen Ihres Druckprozessors festgelegt, und dann wird die SetPrinter-Funktion aufgerufen, um die Einstellungen des Druckers zu aktualisieren. Beachten Sie, dass der Name des Druckprozessors in gszPrintProc mit dem Namen im PrintProcessor-Eintrag in Ihrer INF-Datei identisch sein muss.

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

Zuordnen eines Druckprozessors zu einer Druckwarteschlange während des Druckertreiberupgrades

Wenn ein Druckertreiber aktualisiert wird, wird der Druckprozessor der aktualisierten Druckwarteschlange nicht geändert. Wenn der neue Druckertreiber einen bestimmten Druckprozessor erfordert, muss die DrvUpgradePrinter-Funktion der Druckerschnittstellen-DLL den pPrintProcessor-Member der PRINTER_INFO_2 Struktur auf den Namen des neuen Druckprozessors festlegen. Danach ruft diese Funktion SetPrinter auf, um die Einstellungen des Druckers zu aktualisieren. Der Spooler ruft die DrvUpgradePrinter-Funktion einmal für jeden Drucker auf, wodurch sichergestellt wird, dass alle Drucker, die diesen Treiber verwenden, auch den erforderlichen Druckprozessor verwenden. Im folgenden Codebeispiel werden diese Punkte veranschaulicht.

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