Come rimuovere le informazioni del Registro di sistema per i dispositivi che non verranno mai utilizzati nuovamente in un computer che esegue Windows Server 2003 o versione successiva

Traduzione articoli Traduzione articoli
Identificativo articolo: 934234 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

In questa pagina

INTRODUZIONE

In un computer che esegue Windows Server 2003 o versione successiva di Windows, una periferica di archiviazione connessa tramite un canale a fibra ottica o tramite il protocollo iSCSI pu˛ essere collegata solo per un breve periodo. Quando Ŕ connesso un dispositivo di archiviazione, Windows crea informazioni del Registro di sistema per il dispositivo. Nel tempo, il Registro di sistema pu˛ contenere molti movimenti per i dispositivi che non verranno mai utilizzati nuovamente. In questo articolo viene descritto come rimuovere queste informazioni dal Registro di sistema.

Informazioni

Quando un nuovo dispositivo Ŕ connesso a un computer, Windows registra informazioni su dispositivo nel Registro di sistema. Per la maggior parte dei dispositivi, questa procedura non costituisce un problema. Tuttavia, dopo che una periferica di archiviazione viene presentata da un numero di unitÓ logica (LUN) tramite un canale a fibra ottica o iSCSI, il dispositivo non potrebbe mai verificarsi nuovamente dal computer. Ad esempio, un dispositivo pu˛ essere identificato da un numero seriale o dalle pagine SCSI 0x80 e 0x83.

In questo caso, il Registro di sistema pu˛ contenere voci per i dispositivi che non venga nuovamente visualizzato. Non solo eseguire queste voci occupino spazio nel Registro di sistema, queste voci Ŕ possono che problemi operativi. Ad esempio, poichÚ gli indici per la funzionalitÓ Plug and Play utilizzano i valori di quattro cifre decimali, un problema pu˛ verificarsi quando Ŕ connesso il dispositivo 10,001.

Per risolvere questa limitazione della funzionalitÓ Plug and Play, Ŕ possibile rimuovere le informazioni sul dispositivo dal Registro di sistema quando il dispositivo Ŕ un'unitÓ disco rigido che non Ŕ pi¨ presente. Tale scopo, Ŕ possibile utilizzare il Microsoft DevNodeClean utilitÓ.

La generazione per Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 e Visual Studio 2005

Per pulire il Registro di sistema per il GUID della classe GUID_DEVCLASS_DISKDRIVE disco e per la GUID_DEVCLASS_VOLUME classe GUID del disco, attenersi alla seguente procedura.

Nota.Si consiglia di utilizzare il DevNodeCleanutilitÓ per questa attivitÓ. Le seguenti operazioni e il codice di esempio nel passaggio 7 vengono forniti solo a scopo informativo.
  1. Chiamare la funzione SetupDiGetClassDevs per ottenere informazioni per la classe Ŕ associata il GUID.
  2. Chiamare la funzione SetupDiEnumDeviceInfo per ottenere informazioni sull'istanza per ogni dispositivo nella classe corrente.
  3. Chiamare la funzione CM_Get_DevNode_Status per vedere se le informazioni sulla periferica corrente rappresenta un dispositivo assente. Determinare se lo stato della funzione Ŕ uguale a CR_NO_SUCH_DEVINST o a CR_NO_SUCH_VALUE.
  4. Facoltativamente, per un dispositivo assente, Ŕ possibile chiamare la funzione CM_Get_Device_ID per ottenere l'ID istanza periferica e per visualizzare l'ID prima di rimuovere le informazioni.
  5. Per il dispositivo assente, utilizzare le informazioni di classe ottenuto nel passaggio 1 e le informazioni sull'istanza ottenuta al passaggio 2. Chiamare la funzione SetupDiCallClassInstaller (DIF_REMOVE,...) per rimuovere le informazioni dal Registro di sistema.
  6. Durante la gestione di tutti i dispositivi della classe corrente, chiamare la funzione SetupDiDestroyDeviceInfoList per pulire.
Nota. In alcuni scenari, potrebbe essere necessario pulire il Registro di sistema non solo per la GUID_DEVCLASS_DISKDRIVE e GUID_DEVCLASS_VOLUME del disco GUID di classe ma anche per la GUID_DEVCLASS_SCSIADAPTER e GUID_DEVCLASS_VOLUMESNAPSHOT del disco GUID di classe. A tale scopo, Ŕ necessario modificare la definizione di DiskClassesToClean nell'esempio di codice riportato di seguito.

Nell'applicazione console Win32 Ŕ un esempio di un'applicazione che pulisce il Registro di sistema. Per utilizzare questa applicazione, attenersi alla seguente procedura.

Microsoft fornisce esempi di programmazione puramente a scopo illustrativo, senza alcuna garanzia espressa o esplicita. Questo include, ma non Ŕ limitato a, le garanzie implicite di commerciabilitÓ o idoneitÓ per uno scopo particolare. In questo articolo si presuppone che si abbia familiaritÓ con il linguaggio di programmazione in questione e con gli strumenti utilizzati per creare ed eseguire il debug di procedure. I tecnici del supporto tecnico Microsoft possono spiegare la funzionalitÓ di una particolare procedura. Tuttavia, essi non modificheranno questi esempi per fornire funzionalitÓ aggiuntive o creare procedure atte a soddisfare specifiche esigenze.
  1. In Microsoft Visual Studio 2005, scegliere Nuovo dal menu File , quindi progetto.
  2. Espandere Visual C++e quindi fare clic su Win32.
  3. Fare clic su Applicazione Console Win32, tipo Pulitura nel testo del nome , quindi OK.
  4. Fare clic su Fine nella finestra di dialogo Creazione guidata applicazione Win32 .
  5. In Esplora soluzioni, espandere I file di origine, destro del mouse su Cleanup.cppe quindi scegliere Visualizza codice.
  6. Individuare il codice riportato di seguito:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Sostituire il codice individuato nel passaggio 6 con il codice riportato di seguito.
    /**************************************************************************************************/     
    /*                                                                                                */     
    /* Copyright (c) 2007 Microsoft Corporation.  All Rights Reserved                                 */     
    /*                                                                                                */     
    /**************************************************************************************************/     
    
    #pragma warning( disable : 4201 ) // nonstandard extension used : nameless strut/union
    
    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <tchar.h>
    #include <setupapi.h>
    #include <cfgmgr32.h>
    #include <initguid.h>
    #include <devguid.h>
    
    #define SIZECHARS(x) (sizeof((x))/sizeof(TCHAR))
    #define arraysize(p) (sizeof(p)/sizeof((p)[0]))
    
    CONST GUID *DiskClassesToClean[2] = {
        &GUID_DEVCLASS_DISKDRIVE,
        &GUID_DEVCLASS_VOLUME
    };
    
    /**************************************************************************************************/
    /*                                                                                                */
    /* The user must be member of Administrator group and must have backup and restore permissions         */
    /* (SE_BACKUP_NAME and SE_RESTORE_NAME). No check for these is performed in this example.              */
    /*                                                                                                */
    /**************************************************************************************************/
    int
    __cdecl
    main(
         IN int    ArgC,
         IN char * pArgV[]
        )
    {
        HDEVINFO DeviceInfoSet;
        SP_DEVINFO_DATA DeviceInfoData;
        ULONG DevicesRemoved = 0,
              i,
              MemberIndex,
              Status, 
              Problem,
              ulClassesToCleanIdx;
        BOOL bDoRemove = TRUE;
        CONFIGRET cr;
        TCHAR DeviceInstanceId[MAX_DEVICE_ID_LEN];
        OSVERSIONINFO osvi;
        const GUID ** ClassesToClean;
    
        //
        // Parse parameters.
        //
        for (i = 1; i < (ULONG)ArgC; i++) {
            //
            // Check for help.
            //
            if ( (lstrcmpi(pArgV[i], TEXT("-?")) == 0) ||
                    (lstrcmpi(pArgV[i], TEXT("/?")) == 0) ){
    
                printf("\nCleanUp will remove phantom storage device nodes from this machine.\n\n");
                printf("Usage:  CleanUp \n");
                printf("\twhere /n displays but does not remove the phantom devnodes.\n");
                printf("\nBackup and Restore privileges are required to run this utility.\n");
                return 0;
            }
    
            //
            // Check for -n, which means just list the devices that we would remove.
            //
            if ( (lstrcmpi(pArgV[i], TEXT("-n")) == 0) ||
                 (lstrcmpi(pArgV[i], TEXT("/n")) == 0) ) {
                bDoRemove = FALSE;
            }
        }
    
        //
        // Run only on Windows XP/2003 (version 5.1) or later.
        //
    
        ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    
        if (!GetVersionEx(&osvi)) {
            printf("CleanUp:  Unable to verify Windows version, exiting...\n");
            return -1;
        }
    
        if ((osvi.dwMajorVersion == 5) &&
            ((osvi.dwMinorVersion == 1) || (osvi.dwMinorVersion == 2))) {
        }
        else if (osvi.dwMajorVersion>=6) {
        }
        else
        {
            printf("CleanUp:  This utility is  designed to run on Windows XP/2003 and later\n");
            return -1;
        }
    
        ClassesToClean = DiskClassesToClean;
        ulClassesToCleanIdx = arraysize(DiskClassesToClean);
    
        for (i=0; (i<ulClassesToCleanIdx) && (bDoRemove); i++) {
    
            DeviceInfoSet = SetupDiGetClassDevs(ClassesToClean[i],
                                                NULL,
                                                NULL,
                                                0
                                                );
    
            if (INVALID_HANDLE_VALUE!=DeviceInfoSet) {
    
                DeviceInfoData.cbSize = sizeof(DeviceInfoData);
                MemberIndex = 0;
    
                while (SetupDiEnumDeviceInfo(DeviceInfoSet,
                                             MemberIndex++,
                                             &DeviceInfoData
                                             )) {
    
                    //
                    // Determine whether this device is a phantom.
                    //
                    cr = CM_Get_DevNode_Status(&Status,
                                               &Problem,
                                               DeviceInfoData.DevInst,
                                               0
                                               );
    
                    if ((cr == CR_NO_SUCH_DEVINST) ||
                        (cr == CR_NO_SUCH_VALUE)) {
                        //
                        // This is a phantom. Now get the DeviceInstanceId so we
                        // can display this as output, then delete the phantom if requested.
                        //
                        if (CM_Get_Device_ID(DeviceInfoData.DevInst,
                                             DeviceInstanceId,
                                             SIZECHARS(DeviceInstanceId),
                                             0) == CR_SUCCESS) {
    
                            if (bDoRemove) {
                                printf("DevNodePhantomCleaner:  %s will be removed.\n",
                                       DeviceInstanceId);
    
                                //
                                // Call DIF_REMOVE to remove the device's hardware
                                // and software registry keys.
                                //
                                if (SetupDiCallClassInstaller(DIF_REMOVE,
                                                              DeviceInfoSet,
                                                              &DeviceInfoData
                                                              )) {
                                    DevicesRemoved++;
                                } else {
                                    printf("CleanUp:  Error 0x%X removing phantom\n",
                                           GetLastError);
                                }
                            } else {
                                printf("CleanUp:  %s would have been removed.\n",
                                       DeviceInstanceId);
                            }
                        }
                    }
                }
    
                SetupDiDestroyDeviceInfoList(DeviceInfoSet);
            }
        }
    
        return DevicesRemoved;
    }
  8. Scegliere dal menu Debug , quindi Avviare il debug.

La generazione per Windows Server 2012 e Visual Studio 2012

Alla compilazione per Windows Server 2012 e Microsoft Visual Studio 2012, attenersi alla seguente procedura.

Nota.Si consiglia di utilizzare ilDevNodeCleanutilitÓ per questa attivitÓ. Le seguenti operazioni e il codice di esempio nel passaggio 7 vengono forniti solo a scopo informativo.
  1. In Microsoft Visual Studio 2012, scegliere Nuovo dal menu File , quindi progetto.
  2. Nella finestra di dialogo Nuovo progetto , digitare Pulitura il nome del campo e quindi fare doppio clic su Progetto Win32.
  3. Nella creazione guidata applicazione Win32, fare clic su Avanti.
  4. In tipo di applicazione, fare clic per selezionare <b00> </b00>applicazione Console, quindi scegliere Fine.
  5. In Esplora soluzioni, espandere I file di origine, destro del mouse su Cleanup.cppe quindi scegliere Visualizza codice.
  6. Individuare il codice riportato di seguito:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Sostituire il codice individuato nel passaggio 6 con il codice riportato di seguito.
    //DevPhantomClnr.cpp : Defines the entry point for the console application.
    // 
     
    #include "stdafx.h"
    
    /**************************************************************************************************/     
    /*                                                                                                */     
    /* Copyright (c) 2007 Microsoft Corporation.  All Rights Reserved                                 */     
    /*                                                                                                */     
    /**************************************************************************************************/     
    
    #pragma warning( disable : 4201 ) // nonstandard extension used : nameless strut/union
    
    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <tchar.h>
    #include <setupapi.h>
    #include <cfgmgr32.h>
    #include <initguid.h>
    #include <devguid.h>
    
    #define SIZECHARS(x) (sizeof((x))/sizeof(TCHAR))
    #define arraysize(p) (sizeof(p)/sizeof((p)[0]))
    
    CONST GUID *DiskClassesToClean[2] = {
        &GUID_DEVCLASS_DISKDRIVE,
        &GUID_DEVCLASS_VOLUME
    };
    
    /**************************************************************************************************/
    /*                                                                                                */
    /* The user must be member of Administrator group and must have backup and restore permissions         */
    /* (SE_BACKUP_NAME and SE_RESTORE_NAME). No check for these is performed in this example.              */
    /*                                                                                                */
    /**************************************************************************************************/
    int
    __cdecl
    main(
         IN int    ArgC,
         IN LPCWSTR pArgV[]
        )
    {
        HDEVINFO DeviceInfoSet;
        SP_DEVINFO_DATA DeviceInfoData;
        ULONG DevicesRemoved = 0,
              i,
              MemberIndex,
              Status, 
              Problem,
              ulClassesToCleanIdx;
        BOOL bDoRemove = TRUE;
        CONFIGRET cr;
        TCHAR DeviceInstanceId[MAX_DEVICE_ID_LEN];
        OSVERSIONINFO osvi;
        const GUID ** ClassesToClean;
    
        //
        // Parse parameters.
        //
        for (i = 1; i < (ULONG)ArgC; i++) {
            //
            // Check for help.
            //
            if ( (lstrcmpi(pArgV[i], L"-?") == 0) ||
                    (lstrcmpi(pArgV[i], L"/?") == 0) ){
    
                printf("\nDevNodePhantomCleaner will remove phantom storage device nodes from this machine.\n\n");
                printf("Usage:  nDevNodePhantomCleaner \n");
                printf("\tWhere /n displays but does not remove the phantom devnodes.\n");
                printf("\nBackup and Restore privileges are required to run this utility.\n");
                return 0;
            }
    
            //
            // Check for -n, which means just list the devices that we would remove.
            //
            if ( (lstrcmpi(pArgV[i], L"-n") == 0) ||
                 (lstrcmpi(pArgV[i], L"/n") == 0) ) {
                bDoRemove = FALSE;
            }
        }
    
        //
        // Run only on Windows XP/2003 (version 5.1) or later.
        //
    
        ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    
        if (!GetVersionEx(&osvi)) {
            printf("DevNodePhantomCleaner:  Unable to verify Windows version, exiting...\n");
            return -1;
        }
    
        if ((osvi.dwMajorVersion == 5) &&
            ((osvi.dwMinorVersion == 1) || (osvi.dwMinorVersion == 2))) {
        
        // 5.1 || 5.2
    
        }
    
        else if (osvi.dwMajorVersion>=6) {
        
        //Nothing special on 6.x
    
        }
    
        else
        {
            printf("DevNodePhantomCleaner:  This utility is  designed to run on Windows XP/2003 and later\n");
            return -1;
        }
    
        ClassesToClean = DiskClassesToClean;
        ulClassesToCleanIdx = arraysize(DiskClassesToClean);
    
        for (i=0; (i<ulClassesToCleanIdx) && (bDoRemove); i++) {
    
            DeviceInfoSet = SetupDiGetClassDevs(ClassesToClean[i],
                                                NULL,
                                                NULL,
                                                0
                                                );
    
            if (INVALID_HANDLE_VALUE!=DeviceInfoSet) {
    
                DeviceInfoData.cbSize = sizeof(DeviceInfoData);
                MemberIndex = 0;
    
                while (SetupDiEnumDeviceInfo(DeviceInfoSet,
                                             MemberIndex++,
                                             &DeviceInfoData
                                             )) {
    
                    //
                    // Determine whether this device is a phantom.
                    //
                    cr = CM_Get_DevNode_Status(&Status,
                                               &Problem,
                                               DeviceInfoData.DevInst,
                                               0
                                               );
    
                    if ((cr == CR_NO_SUCH_DEVINST) ||
                        (cr == CR_NO_SUCH_VALUE)) {
                        //
                        // This is a phantom. Now get the DeviceInstanceId so we
                        // can display this as output, then delete the phantom if requested.
                        //
                        if (CM_Get_Device_ID(DeviceInfoData.DevInst,
                                             DeviceInstanceId,
                                             SIZECHARS(DeviceInstanceId),
                                             0) == CR_SUCCESS) {
    
                            if (bDoRemove) {
                                printf("DevNodePhantomCleaner:  %ws will be removed.\n",
                                       DeviceInstanceId);
    
                                //
                                // Call DIF_REMOVE to remove the device's hardware
                                // and software registry keys.
                                //
                                if (SetupDiCallClassInstaller(DIF_REMOVE,
                                                              DeviceInfoSet,
                                                              &DeviceInfoData
                                                              )) {
                                    DevicesRemoved++;
                                } else {
                                    printf("DevNodePhantomCleaner:  Error 0x%x removing phantom\n",
                                           GetLastError());
                                }
                            } else {
                                printf("DevNodePhantomCleaner:  %ws would have been removed.\n",
                                       DeviceInstanceId);
                            }
                        }
                    }
                }
    
                SetupDiDestroyDeviceInfoList(DeviceInfoSet);
            }
        }
    
        return DevicesRemoved;
    }
  8. In Esplora soluzioni, destro puliturae quindi scegliere proprietÓ.
  9. Espandere ProprietÓ di configurazione, espandere il Linkere quindi fare clic su Input.
  10. Selezionare Dipendenze aggiuntive, fare clic sulla freccia verso il basso e fare clic su Modifica.
  11. Nella finestra di dialogo Dipendenze aggiuntive , tipo setupapi.lib e CfgMgr32. lib.
  12. Fare clic su OK due volte.
  13. Compilare il progetto.

ProprietÓ

Identificativo articolo: 934234 - Ultima modifica: domenica 13 luglio 2014 - Revisione: 4.0
Le informazioni in questo articolo si applicano a:
  • Microsoft Windows Server 2003, Standard Edition (32-bit x86)
  • Microsoft Windows Server 2003, Enterprise Edition (32-bit x86)
  • Microsoft Windows Server 2003, Datacenter Edition (32-bit x86)
  • Microsoft Windows Server 2003, Enterprise x64 Edition
  • Microsoft Windows Server 2003, Datacenter x64 Edition
  • Microsoft Windows Server 2003, Standard x64 Edition
  • Microsoft Windows Server 2003, Enterprise Edition for Itanium-based Systems
  • Microsoft Windows Server 2003, Datacenter Edition for Itanium-Based Systems
  • Microsoft Windows Server 2003 R2 Standard Edition (32-bit x86)
  • Microsoft Windows Server 2003 R2 Enterprise Edition (32-Bit x86)
  • Microsoft Windows Server 2003 R2 Datacenter Edition (32-Bit x86)
  • Microsoft Windows Server 2003 R2 Datacenter x64 Edition
  • Microsoft Windows Server 2003 R2 Enterprise x64 Edition
  • Microsoft Windows Server 2003 R2 Standard x64 Edition
  • Microsoft Windows Storage Server 2003 R2 x64 Enterprise
  • Microsoft Windows Storage Server 2003 R2 x64 Standard
  • Windows Server 2008 Datacenter
  • Windows Server 2008 Datacenter without Hyper-V
  • Windows Server 2008 Enterprise
  • Windows Server 2008 Enterprise without Hyper-V
  • Windows Server 2008 for Itanium-Based Systems
  • Windows Server 2008 Standard
  • Windows Server 2008 Standard without Hyper-V
  • Windows Server 2008 R2 Datacenter
  • Windows Server 2008 R2 Enterprise
  • Windows Server 2008 R2 Standard
  • Windows Server 2012 Standard
  • Windows Server 2012 Datacenter
Chiavi:á
kboem kbcode kbinfo kbhowto kbmt KB934234 KbMtit
Traduzione automatica articoli
IMPORTANTE: il presente articolo Ŕ stato tradotto tramite un software di traduzione automatica di Microsoft ed eventualmente revisionato dalla community Microsoft tramite la tecnologia CTF (Community Translation Framework) o da un traduttore professionista. Microsoft offre articoli tradotti manualmente e altri tradotti automaticamente e rivisti dalla community con l?obiettivo di consentire all'utente di accedere a tutti gli articoli della Knowledge Base nella propria lingua. Tuttavia, un articolo tradotto automaticamente, anche se rivisto dalla community, non sempre Ŕ perfetto. Potrebbe contenere errori di vocabolario, di sintassi o di grammatica. Microsoft declina ogni responsabilitÓ per imprecisioni, errori o danni causati da una traduzione sbagliata o dal relativo utilizzo da parte dei clienti. Microsoft aggiorna frequentemente il software e gli strumenti di traduzione automatica per continuare a migliorare la qualitÓ della traduzione.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 934234
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com