Làm thế nào để lấy lại và thiết lập máy in mặc định trong Windows

Hỗ trợ cho Windows XP đã kết thúc

Microsoft đã kết thúc hỗ trợ dành cho Windows XP vào ngày 8 tháng 4 năm 2014. Thay đổi này đã ảnh hưởng đến các bản cập nhật phần mềm và tùy chọn bảo mật của bạn. Tìm hiểu ý nghĩa của điều này với bạn và cách thực hiện để luôn được bảo vệ.

QUAN TRỌNG: Bài viết này được dịch bằng phần mềm dịch máy của Microsoft chứ không phải do con người dịch. Microsoft cung cấp các bài viết do con người dịch và cả các bài viết do máy dịch để bạn có thể truy cập vào tất cả các bài viết trong Cơ sở Kiến thức của chúng tôi bằng ngôn ngữ của bạn. Tuy nhiên, bài viết do máy dịch không phải lúc nào cũng hoàn hảo. Loại bài viết này có thể chứa các sai sót về từ vựng, cú pháp hoặc ngữ pháp, giống như một người nước ngoài có thể mắc sai sót khi nói ngôn ngữ của bạn. Microsoft không chịu trách nhiệm về bất kỳ sự thiếu chính xác, sai sót hoặc thiệt hại nào do việc dịch sai nội dung hoặc do hoạt động sử dụng của khách hàng gây ra. Microsoft cũng thường xuyên cập nhật phần mềm dịch máy này.

Nhấp chuột vào đây để xem bản tiếng Anh của bài viết này:246772
Chú ý
Bài viết này áp dụng cho Windows 2000. Hỗ trợ cho Windows 2000 kết thúc vào ngày 13 tháng 7 năm 2010. Các Trung tâm giải pháp kết thúc hỗ trợ Windows 2000 là một điểm khởi đầu để lập kế hoạch chiến lược của bạn di chuyển từ Windows 2000. Để biết thêm thông tin xem các Chính sách vòng đời hỗ trợ của Microsoft.
Bài viết này đã được lưu trữ. Bài viết được cung cấp "nguyên trạng" và sẽ không còn được cập nhật nữa.
TÓM TẮT
Bạn có thể truy xuất hoặc thiết lập máy in mặc định bằng cách sử dụng phương pháp khác nhau, tùy thuộc vào phiên bản của Windows mà bạn sử dụng.
THÔNG TIN THÊM
Với Windows NT 4.0 (và các phiên bản trước đó), bạn không thể sử dụng:
  • Một trong hai SetPrinter hoặc SetDefaultPrinter để thiết lập máy in mặc định.
  • Một trong hai EnumPrinters hoặc GetDefaultPrinter để có được máy in mặc định.
Với Windows NT 4.0, bạn có thể sử dụng:
  • GetProfileString để có được máy in mặc định.
  • WriteProfileString để thiết lập máy in mặc định.
Giá trị thiết bị mà bạn nhận được, hoặc thiết lập chứa ba yếu tố đó được phân cách bằng dấu phẩy, như sau:
      printer name,driver name,port				
Ví dụ:
      My Printer,HPPCL5MS,lpt1:				
Lưu ý sau đây:
  • Khi bạn sử dụng phương pháp này, bạn phải xác định một máy in hợp lệ, trình điều khiển, và cổng. Nếu bạn không làm như thế, các API sẽ không thất bại và có thể gây ra các chương trình khác để thiết lập máy in quay lại máy in hợp lệ trước hoặc trở nên bối rối.

    Để lấy lại tên máy in, tên trình điều khiển và tên cổng của tất cả máy in có sẵn, sử dụng các EnumPrinters API.
  • Windows NT đồ hầu hết rules.ini tập tài liệu tham khảo để đăng ký. Do đó, GetProfileStringWriteProfileString vẫn hoạt động như nếu họ đã chạy dưới Windows 16-bit (Microsoft Windows và Windows cho nhóm làm việc).
  • Sau khi bạn thiết lập máy in mặc định với một trong hai GetPrinter, GetDefaultPrinter, hoặc WriteProfileString, thông báo cho tất cả các chương trình mở cửa của sự thay đổi của phát thanh truyền hình tin nhắn WM_SETTINGCHANGE. Chỉ những chương trình xử lý thông điệp này nhận ra sự thay đổi.

    WM_SETTINGCHANGE và WM_WININICHANGE đều giống nhau; sử dụng WM_SETTINGCHANGE cho Win32 các chương trình.

Mẫu mã

Mẫu mã sau đây cho thấy làm thế nào để lấy lại (máy in mặc địnhDPGetDefaultPrinter) và thiết lập máy in mặc định (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				
Mã dường như không làm việc trong một số trường hợp:
  • Nếu bạn bỏ ra các SendMessageTimeout cuộc gọi, không có chương trình khác công nhận sự thay đổi cho đến khi bạn khởi động lại chương trình.
  • Nếu một chương trình 32-bit khác không xử lý thư WM_SETTINGCHANGE, chương trình khác không nhận ra rằng máy in mặc định đã được thay đổi. Bạn phải thoát và khởi động lại chương trình để ép buộc nó để nhận ra sự thay đổi.
  • MAXBUFFERSIZE là quá nhỏ để chứa chuỗi sau đây:
    printername,portname,drivername					
  • Khi bạn sử dụng các WriteProfileString API từ mẫu mã này (mà bạn phải chỉ sử dụng cho Windows NT 4.0 và phiên bản trước đó), hãy nhớ rằng bạn lấy tên cổng được thông qua WriteProfileString bằng cách sử dụng API 32-bit GetPrinter.

    Mặc dù tên cổng này là hợp lệ, chương trình 16-bit không thể đọc nó và có thể gặp vấn đề. Nếu bạn sử dụng phương pháp này với Windows NT (Phiên bản 4.0 và trước đó) và chương trình 16-bit cần phải hiểu tên cổng mới, bạn phải sử dụng bí danh 16-bit cho cổng tên)NE0xtrong đó x là số một). Bạn có thể tìm thấy ánh xạ giữa 32-bit cảng tên và biệt hiệu 16-bit của họ trong sổ đăng ký.
THAM KHẢO
Để biết thêm chi tiết, bấm vào những con số bài viết dưới đây để xem các bài viết trong cơ sở kiến thức Microsoft:
266767 HOWTO: Đặt mà máy in là máy in mặc định hệ thống
140560 HOWTO: Đặt máy in mặc định lập trình trong Windows 95, Windows 98, hoặc Windows Me

Cảnh báo: Bài viết này được dịch tự động

Thuộc tính

ID Bài viết: 246772 - Xem lại Lần cuối: 12/05/2015 17:37:19 - Bản sửa đổi: 2.0

Microsoft Windows XP Professional, Microsoft Windows 2000 Server

  • kbnosurvey kbarchive kbdswgdi2003swept kbgdi kbhowto kbprint kbmt KB246772 KbMtvi
Phản hồi