如何擷取並在 Windows 中設定預設印表機

Windows XP 支援已結束

Microsoft 於 2014 年 4 月 8 日結束對 Windows XP 的支援。此變更已影響您的軟體更新和安全性選項。 瞭解這對您的意義為何且如何持續受保護。

重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。

按一下這裡查看此文章的英文版本:246772
注意事項
這份文件適用於 Windows 2000。Windows 2000 支援的結束 2010 7 月 13,Windows 2000 End-of-Support Solution Center 是規劃您的遷移策略,從 Windows 2000 的起點。如需詳細資訊請參閱 Microsoft Support Lifecycle Policy]。
本文已封存。本文係以「現狀」提供且不會再更新。
結論
您可以從中擷取或使用不同的方法視您使用的 Windows 版本設定預設印表機。
其他相關資訊
使用與 Windows NT 4.0 (和較早版本) 不能
  • 不論是 SetPrinterSetDefaultPrinter 來設定預設印表機。
  • 可能是 EnumPrintersGetDefaultPrinter 取得預設印表機。
使用 Windows NT 4.0 您 可以 使用:
  • 取得預設印表機 GetProfileString
  • 若要設定預設印表機 WriteProfileString
DEVICE 值,取得或設定包含之間以逗號 (,) 來分隔,如下所示的三個項目:
      printer name,driver name,port				
例如:
      My Printer,HPPCL5MS,lpt1:				
請注意下列:
  • 當您使用這個方法時,您必須指定有效的印表機、 驅動程式和連接埠。如果您沒有這樣做,API 將 會失敗,可能會導致其他程式將印表機設回前一個有效的印表機或成為相混淆。

    若要擷取印表機名稱]、 [驅動程式名稱] 及 [所有可用印表機的連接埠名稱使用 EnumPrinters API。
  • Windows NT 將對應登錄的大部分.ini 檔案參考。如此一來 GetProfileStringWriteProfileString 仍可運作如同它們 16 位元 Windows (Microsoft Windows 和工作群組的 Windows) 下執行。
  • 設定了預設的印表機與 GetPrinterGetDefaultPrinterWriteProfileString 後以廣播 WM_SETTINGCHANGE 訊息通知變更的所有其他開啟的程式。僅處理此訊息的程式能識別變更。

    WM_SETTINGCHANGE 和 WM_WININICHANGE 是相同 ; WM_SETTINGCHANGE 用於 Win32 程式。

範例程式碼

下列範例程式碼示範如何擷取預設印表機 (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 位元別名之間的對應。
参考
如需詳細資訊按一下面的文件編號,檢視 「 Microsoft 知識庫 」 中 「 文件:
266767HOWTO: 設定哪些印表機是系統預設印表機
140560HOWTO: 設定預設印表機以程式設計方式在 Windows 95、 Windows 98 或 Windows Me 中

警告:本文為自動翻譯

內容

文章識別碼:246772 - 最後檢閱時間:12/05/2015 17:37:20 - 修訂: 2.6

Microsoft Platform Software Development Kit-January 2000 Edition, Microsoft Windows XP Professional, the operating system: Microsoft Windows XP 64-Bit Edition, Microsoft Windows 2000 Server

  • kbnosurvey kbarchive kbmt kbdswgdi2003swept kbgdi kbhowto kbprint KB246772 KbMtzh
意見反應