Al momento sei offline in attesa che la connessione Internet venga ristabilita

Recupero e impostazione della stampante predefinita in Windows

Il supporto per Windows XP è terminato

Il supporto Microsoft per Windows XP è terminato l Ulteriori informazioni su come continuare a essere protetti.

Sommario
È possibile recuperare o impostare la stampante predefinita utilizzando vari metodi, a seconda della versione di Windows in uso.
Informazioni
Con Windows NT 4.0 e versioni precedenti non è possibile utilizzare:
  • Il metodo SetPrinter o il metodo SetDefaultPrinter per impostare la stampante predefinita.
  • Il metodo EnumPrinters o il metodo GetDefaultPrinter per rilevare la stampante predefinita.
Con Windows NT 4.0 è possibile utilizzare:
  • Il metodo GetProfileString per rilevare la stampante predefinita.
  • Il metodo WriteProfileString per impostare la stampante predefinita.
Il valore DEVICE rilevato o impostato contiene tre elementi separati da virgole, come indicato di seguito:
      nome stampante,nome driver,porta				
Ad esempio:
      Stampante,HPPCL5MS,lpt1:				
Tenere presente quanto segue:
  • Quando si utilizza questo metodo è necessario specificare una porta, un driver e una stampante validi. In caso contrario, non si verificheranno errori nelle API e ciò potrebbe provocare che altri programmi impostino di nuovo la stampante sulla stampante valida precedente o che si crei confusione.

    Per recuperare il nome della stampante, del driver e della porta di tutte le stampanti disponibili utilizzare l'API EnumPrinters.
  • In Windows NT viene eseguito il mapping della maggior parte dei riferimenti ai file con estensione ini nel Registro di sistema. Di conseguenza, i metodi GetProfileString e WriteProfileString funzionano ancora come se venissero eseguiti in Windows a 16 bit (Microsoft Windows e Windows per Workgroups).
  • Dopo aver impostato la stampante predefinita con i metodi GetPrinter, GetDefaultPrinter o WriteProfileString notificare a tutti gli altri programmi aperti la modifica trasmettendo il messaggio WM_SETTINGCHANGE. Solo i programmi che supportano questo messaggio riconosceranno la modifica.

    WM_SETTINGCHANGE e WM_WININICHANGE sono uguali. Utilizzare WM_SETTINGCHANGE per programmi Win32.

Codice di esempio

Il codice di esempio seguente illustra come recuperare la stampante predefinita (DPGetDefaultPrinter) e impostare la stampante predefinita (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				
In alcuni casi il codice potrebbe non funzionare correttamente:
  • Se non si include la chiamata SendMessageTimeout nessun altro programma riconoscerà la modifica fin quando non verrà riavviato il programma.
  • Se un programma a 32 bit differente non supporta il messaggio WM_SETTINGCHANGE l'altro programma non riconoscerà che la stampante predefinita è stata modificata. È necessario chiudere e riavviare il programma per forzarlo a riconoscere la modifica.
  • MAXBUFFERSIZE è troppo piccolo per contenere la stringa seguente:
    nomestampante,nomeporta,nomedriver					
  • Quando si utilizza l'API WriteProfileString da questo codice di esempio, che è necessario utilizzare solo per Windows NT 4.0 e versioni precedenti, occorre tenere presente che è stato recuperato il nome della porta passato a WriteProfileString utilizzando l'API a 32 bit GetPrinter.

    Sebbene questo nome porta sia valido, i programmi a 16 bit non sono in grado di leggerlo e potrebbero verificarsi dei problemi. Se si utilizza questo metodo con Windows NT 4.0 e versioni precedenti e i programmi a 16 bit devono riconoscere il nuovo nome della porta sarà necessario utilizzare l'alias a 16 bit del nome della porta (NE0x), dove x è un numero. È possibile trovare il mapping tra i nomi di porta a 32 bit e gli alias a 16 bit corrispondenti nel Registro di sistema.
Riferimenti
Per ulteriori informazioni, fare clic sui numeri degli articoli della Microsoft Knowledge Base riportati di seguito:
266767 HOW TO: Impostare la stampante come stampante di sistema predefinita
140560 HOW TO: Impostare la stampante predefinita a livello di programmazione in Windows 95, Windows 98 o Windows ME
Proprietà

ID articolo: 246772 - Ultima revisione: 06/15/2007 17:27:00 - Revisione: 2.3

  • Microsoft Platform Software Development Kit-edizione gennaio 2000
  • Microsoft Windows XP Professional
  • the operating system: Microsoft Windows XP 64-Bit Edition
  • kbhowto kbprint kbgdi kbdswgdi2003swept KB246772
Feedback