Как получить и задать принтер по умолчанию в Windows

Поддержка Windows XP завершена

8 апреля 2014 г. корпорация Майкрософт прекратила поддержку Windows XP. Это повлияло на обновления программного обеспечения и параметры безопасности. Узнайте, что это значит для вас и какие меры по безопасности можно предпринять.

ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.

Эта статья на английском языке:246772
Внимание
В данной статье относится к Windows 2000. Поддержка Windows 2000 заканчивается на 13 июля 2010 г. В Центр решений-технической поддержки Windows 2000 является отправной точкой для планирования стратегии перехода от Windows 2000. Для получения дополнительных сведений см. Политики поддержи продуктов Майкрософт.
Эта статья помещена в архив. Она предлагается "как есть" и обновляться не будет.
Аннотация
Можно извлечь или задать принтер по умолчанию с помощью различных методов, в зависимости от версии Windows, можно использовать.
Дополнительная информация
С Windows NT 4.0 (и более ранние версии), не удается Использование:
  • Либо SetPrinter -или- SetDefaultPrinter Чтобы установить принтер по умолчанию.
  • Либо EnumPrinters -или- GetDefaultPrinter Чтобы получить принтер по умолчанию.
В Windows NT 4.0, можно Использование:
  • GetProfileString Чтобы получить принтер по умолчанию.
  • WriteProfileString Чтобы установить принтер по умолчанию.
Получить или задать значение УСТРОЙСТВА состоит из трех элементов, разделенных запятыми, как показано ниже:
      printer name,driver name,port				
Например:
      My Printer,HPPCL5MS,lpt1:				
Обратите внимание на следующее:
  • При использовании этого метода необходимо задать допустимый принтера, драйвера и порта. Если этого не сделать, будет API-интерфейсы не Сбой и может вызвать другие программы, чтобы снова установить принтер предыдущих действительный принтер или прийти в замешательство.

    Для получения имени принтера, имя драйвера и имя порта всех принтеров, используйте EnumPrinters API-ИНТЕРФЕЙС.
  • Windows NT сопоставляет большинство ссылок на файлы .ini в реестр. В результате GetProfileString и WriteProfileString по-прежнему работать, как если бы они были запущены в 16-разрядной версии Windows (Microsoft Windows и Windows для рабочих групп).
  • После установки принтера по умолчанию, либо с GetPrinter, GetDefaultPrinter, или WriteProfileString, уведомлять другие открытые программы изменения путем рассылки сообщений WM _ SETTINGCHANGE. Только программы, которые обрабатывают сообщения распознать изменения.

    WM _ SETTINGCHANGE и WM_WININICHANGE одинаковы; для приложений Win32 с помощью WM _ SETTINGCHANGE.

Пример кода

В следующем примере кода показано, как извлечь (принтер по умолчаниюDPGetDefaultPrinter) и значение (по умолчанию принтераDPSetDefaultPrinter).
// You are explicitly linking to GetDefaultPrinter because linking // implicitly on Windows 95/98 or NT4 results in a runtime error.// This block specifies which text version you explicitly link to.#ifdef UNICODE  #define GETDEFAULTPRINTER "GetDefaultPrinterW"#else  #define GETDEFAULTPRINTER "GetDefaultPrinterA"#endif// Size of internal buffer used to hold "printername,drivername,portname"// string. You may have to increase this for huge strings.#define MAXBUFFERSIZE 250/*----------------------------------------------------------------*/ /* DPGetDefaultPrinter                                            */ /*                                                                */ /* Parameters:                                                    */ /*   pPrinterName: Buffer alloc'd by caller to hold printer name. */ /*   pdwBufferSize: On input, ptr to size of pPrinterName.        */ /*          On output, min required size of pPrinterName.         */ /*                                                                */ /* NOTE: You must include enough space for the NULL terminator!   */ /*                                                                */ /* Returns: TRUE for success, FALSE for failure.                  */ /*----------------------------------------------------------------*/ BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize){  BOOL bFlag;  OSVERSIONINFO osv;  TCHAR cBuffer[MAXBUFFERSIZE];  PRINTER_INFO_2 *ppi2 = NULL;  DWORD dwNeeded = 0;  DWORD dwReturned = 0;  HMODULE hWinSpool = NULL;  PROC fnGetDefaultPrinter = NULL;    // What version of Windows are you running?  osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  GetVersionEx(&osv);    // If Windows 95 or 98, use EnumPrinters.  if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)  {    // The first EnumPrinters() tells you how big our buffer must    // be to hold ALL of PRINTER_INFO_2. Note that this will    // typically return FALSE. This only means that the buffer (the 4th    // parameter) was not filled in. You do not want it filled in here.    SetLastError(0);    bFlag = EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, NULL, 0, &dwNeeded, &dwReturned);    {      if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))        return FALSE;    }        // Allocate enough space for PRINTER_INFO_2.    ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);    if (!ppi2)      return FALSE;        // The second EnumPrinters() will fill in all the current information.    bFlag = EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded, &dwReturned);    if (!bFlag)    {      GlobalFree(ppi2);      return FALSE;    }        // If specified buffer is too small, set required size and fail.    if ((DWORD)lstrlen(ppi2->pPrinterName) >= *pdwBufferSize)    {      *pdwBufferSize = (DWORD)lstrlen(ppi2->pPrinterName) + 1;      GlobalFree(ppi2);      return FALSE;    }        // Copy printer name into passed-in buffer.    lstrcpy(pPrinterName, ppi2->pPrinterName);        // Set buffer size parameter to minimum required buffer size.    *pdwBufferSize = (DWORD)lstrlen(ppi2->pPrinterName) + 1;  }    // If Windows NT, use the GetDefaultPrinter API for Windows 2000,  // or GetProfileString for version 4.0 and earlier.  else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)  {    if (osv.dwMajorVersion >= 5) // Windows 2000 or later (use explicit call)    {      hWinSpool = LoadLibrary("winspool.drv");      if (!hWinSpool)        return FALSE;      fnGetDefaultPrinter = GetProcAddress(hWinSpool, GETDEFAULTPRINTER);      if (!fnGetDefaultPrinter)      {        FreeLibrary(hWinSpool);        return FALSE;      }      bFlag = fnGetDefaultPrinter(pPrinterName, pdwBufferSize);        FreeLibrary(hWinSpool);      if (!bFlag)        return FALSE;    }        else // NT4.0 or earlier    {      // Retrieve the default string from Win.ini (the registry).      // String will be in form "printername,drivername,portname".      if (GetProfileString("windows", "device", ",,,", cBuffer, MAXBUFFERSIZE) <= 0)        return FALSE;            // Printer name precedes first "," character.      strtok(cBuffer, ",");            // If specified buffer is too small, set required size and fail.      if ((DWORD)lstrlen(cBuffer) >= *pdwBufferSize)      {        *pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;        return FALSE;      }            // Copy printer name into passed-in buffer.      lstrcpy(pPrinterName, cBuffer);            // Set buffer size parameter to minimum required buffer size.      *pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;    }  }    // Clean up.  if (ppi2)    GlobalFree(ppi2);    return TRUE;}#undef MAXBUFFERSIZE#undef GETDEFAULTPRINTER// You are explicitly linking to SetDefaultPrinter because implicitly// linking on Windows 95/98 or NT4 results in a runtime error.// This block specifies which text version you explicitly link to.#ifdef UNICODE  #define SETDEFAULTPRINTER "SetDefaultPrinterW"#else  #define SETDEFAULTPRINTER "SetDefaultPrinterA"#endif/*-----------------------------------------------------------------*/ /* DPSetDefaultPrinter                                             */ /*                                                                 */ /* Parameters:                                                     */ /*   pPrinterName: Valid name of existing printer to make default. */ /*                                                                 */ /* Returns: TRUE for success, FALSE for failure.                   */ /*-----------------------------------------------------------------*/ BOOL DPSetDefaultPrinter(LPTSTR pPrinterName){  BOOL bFlag;  OSVERSIONINFO osv;  DWORD dwNeeded = 0;  HANDLE hPrinter = NULL;  PRINTER_INFO_2 *ppi2 = NULL;  LPTSTR pBuffer = NULL;  LONG lResult;  HMODULE hWinSpool = NULL;  PROC fnSetDefaultPrinter = NULL;    // What version of Windows are you running?  osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  GetVersionEx(&osv);    if (!pPrinterName)    return FALSE;    // If Windows 95 or 98, use SetPrinter.  if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)  {    // Open this printer so you can get information about it.    bFlag = OpenPrinter(pPrinterName, &hPrinter, NULL);    if (!bFlag || !hPrinter)      return FALSE;        // The first GetPrinter() tells you how big our buffer must    // be to hold ALL of PRINTER_INFO_2. Note that this will    // typically return FALSE. This only means that the buffer (the 3rd    // parameter) was not filled in. You do not want it filled in here.    SetLastError(0);    bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);    if (!bFlag)    {      if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))      {        ClosePrinter(hPrinter);        return FALSE;      }    }        // Allocate enough space for PRINTER_INFO_2.    ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);    if (!ppi2)    {      ClosePrinter(hPrinter);      return FALSE;    }        // The second GetPrinter() will fill in all the current information    // so that all you have to do is modify what you are interested in.    bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);    if (!bFlag)    {      ClosePrinter(hPrinter);      GlobalFree(ppi2);      return FALSE;    }        // Set default printer attribute for this printer.    ppi2->Attributes |= PRINTER_ATTRIBUTE_DEFAULT;    bFlag = SetPrinter(hPrinter, 2, (LPBYTE)ppi2, 0);    if (!bFlag)    {      ClosePrinter(hPrinter);      GlobalFree(ppi2);      return FALSE;    }        // Tell all open programs that this change occurred.     // Allow each program 1 second to handle this message.    lResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0L,      (LPARAM)(LPCTSTR)"windows", SMTO_NORMAL, 1000, NULL);  }    // If Windows NT, use the SetDefaultPrinter API for Windows 2000,  // or WriteProfileString for version 4.0 and earlier.  else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)  {    if (osv.dwMajorVersion >= 5) // Windows 2000 or later (use explicit call)    {      hWinSpool = LoadLibrary("winspool.drv");      if (!hWinSpool)        return FALSE;      fnSetDefaultPrinter = GetProcAddress(hWinSpool, SETDEFAULTPRINTER);      if (!fnSetDefaultPrinter)      {        FreeLibrary(hWinSpool);        return FALSE;      }      bFlag = fnSetDefaultPrinter(pPrinterName);      FreeLibrary(hWinSpool);      if (!bFlag)        return FALSE;    }    else // NT4.0 or earlier    {      // Open this printer so you can get information about it.      bFlag = OpenPrinter(pPrinterName, &hPrinter, NULL);      if (!bFlag || !hPrinter)        return FALSE;            // The first GetPrinter() tells you how big our buffer must      // be to hold ALL of PRINTER_INFO_2. Note that this will      // typically return FALSE. This only means that the buffer (the 3rd      // parameter) was not filled in. You do not want it filled in here.      SetLastError(0);      bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);      if (!bFlag)      {        if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))        {          ClosePrinter(hPrinter);          return FALSE;        }      }            // Allocate enough space for PRINTER_INFO_2.      ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);      if (!ppi2)      {        ClosePrinter(hPrinter);        return FALSE;      }            // The second GetPrinter() fills in all the current<BR/>      // information.      bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);      if ((!bFlag) || (!ppi2->pDriverName) || (!ppi2->pPortName))      {        ClosePrinter(hPrinter);        GlobalFree(ppi2);        return FALSE;      }            // Allocate buffer big enough for concatenated string.      // String will be in form "printername,drivername,portname".      pBuffer = (LPTSTR)GlobalAlloc(GPTR,        lstrlen(pPrinterName) +        lstrlen(ppi2->pDriverName) +        lstrlen(ppi2->pPortName) + 3);      if (!pBuffer)      {        ClosePrinter(hPrinter);        GlobalFree(ppi2);        return FALSE;      }            // Build string in form "printername,drivername,portname".      lstrcpy(pBuffer, pPrinterName);  lstrcat(pBuffer, ",");      lstrcat(pBuffer, ppi2->pDriverName);  lstrcat(pBuffer, ",");      lstrcat(pBuffer, ppi2->pPortName);            // Set the default printer in Win.ini and registry.      bFlag = WriteProfileString("windows", "device", pBuffer);      if (!bFlag)      {        ClosePrinter(hPrinter);        GlobalFree(ppi2);        GlobalFree(pBuffer);        return FALSE;      }    }        // Tell all open programs that this change occurred.     // Allow each app 1 second to handle this message.    lResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0L, 0L,      SMTO_NORMAL, 1000, NULL);  }    // Clean up.  if (hPrinter)    ClosePrinter(hPrinter);  if (ppi2)    GlobalFree(ppi2);  if (pBuffer)    GlobalFree(pBuffer);    return TRUE;}#undef SETDEFAULTPRINTER				
Не работать в некоторых случаях появляется код:
  • Если вы пропустите SendMessageTimeout вызов, никакая другая программа распознает изменение только после перезапуска программы.
  • Если другой 32-разрядной программы не обрабатывает сообщение WM _ SETTINGCHANGE, другие программы не распознают изменился принтер по умолчанию. Необходимо выйти и перезапустить программу принудительно распознать изменения.
  • MAXBUFFERSIZE слишком мал для хранения следующей строки:
    printername,portname,drivername					
  • При использовании WriteProfileString API из этого образца кода (который следует использовать только для Windows NT 4.0 и более ранних версий), следует помнить, что извлечь имя порта, который передается в WriteProfileString с помощью 32-разрядного API GetPrinter.

    Несмотря на то, что это имя порта является допустимым, 16-разрядные программы не может прочитать его и могут возникнуть проблемы. Если этот метод используется в Windows NT (4.0 и более ранних версий) и 16-разрядных приложений необходимо ознакомиться с новым именем порта, необходимо использовать псевдоним 16-разрядные (имя портаNE0xгде x — номер). Сопоставление имен 32-битный порт и их псевдонимы 16-разрядные можно найти в реестре.
Ссылки
Для получения дополнительных сведений щелкните следующий номер статьи базы знаний Майкрософт:
266767 Методические УКАЗАНИЯ: Которого принтер является системный принтер по умолчанию
140560 Методические УКАЗАНИЯ: Установите принтер по умолчанию программными средствами в Windows 95, Windows 98 или Windows Me

Внимание! Эта статья переведена автоматически

Свойства

Номер статьи: 246772 — последний просмотр: 12/05/2015 17:37:17 — редакция: 4.0

Microsoft Windows XP Professional, операционная система Microsoft Windows 2000 Server

  • kbnosurvey kbarchive kbdswgdi2003swept kbgdi kbhowto kbprint kbmt KB246772 KbMtru
Отзывы и предложения