Aanmelden met Microsoft
Meld u aan of maak een account.
Hallo,
Selecteer een ander account.
U hebt meerdere accounts
Kies het account waarmee u zich wilt aanmelden.

INLEIDING

Wanneer een opslagapparaat aangesloten bij Windows, zelfs als slechts kort windows registerinformatie voor het apparaat maakt. Na verloop van tijd kan het register veel vermeldingen voor apparaten die nooit opnieuw worden gebruikt bevatten. In dit artikel wordt beschreven hoe deze gegevens uit het register verwijderen.

Het is de verantwoordelijkheid van de software die de verbinding tussen het opslagapparaat en Windows correct opschonen van de gegevens voor het apparaat tot stand brengt. Deze procedure is nodig omdat Windows niet mee als een apparaat voor gegevensopslag tijdelijk of definitief wordt verwijderd. Maar de software die u de verbinding meestal maakt is dit. Bijvoorbeeld als back-upsoftware logische eenheden (LUN) voor back-updoeleinden koppelen en vervolgens ontkoppelen van de LUN's, zou worden onder de verantwoordelijkheid van de back-upsoftware voor het opschonen van de LUN-informatie van Windows, omdat het hetzelfde opslagapparaat niet meer wordt opnieuw door Windows worden gebruikt.

Meer informatie

Wanneer een nieuw apparaat is verbonden met een computer, Windows records gegevens over het apparaat in het systeemregister. Voor de meeste apparaten enkel met deze procedure geen probleem. Echter, wanneer een opslagapparaat wordt aangeboden door een LUN via een Fibre channel of iSCSI, het apparaat kan nooit optreden opnieuw door de computer. Een apparaat kan bijvoorbeeld worden aangegeven door een serienummer of SCSI-pagina 0x80 en 0x83.

In dit geval bevat het register mogelijk posten voor apparaten die nooit opnieuw weergegeven. Niet alleen doet deze posten nemen ruimte in het register, wordt deze vermeldingen uiteindelijk operationele problemen kunnen veroorzaken. Bijvoorbeeld omdat de indexen voor Plug en Play-functionaliteit decimale waarden van vier cijfers gebruiken, treedt een probleem wanneer 10,001-apparaat is aangesloten.

U kunt oplossen door deze beperking in Plug en Play-functionaliteit, kunt u gegevens van een apparaat uit het register verwijderen wanneer het apparaat is een vaste schijf die niet meer aanwezig is. U kunt dit doen met behulp van het hulpprogramma Microsoft DevNodeClean .

Het bouwen voor Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 en Visual Studio 2005

Voor het opschonen van het register voor de klasse-GUID van de schijf in GUID_DEVCLASS_DISKDRIVE en schijf klasse-GUID voor de GUID_DEVCLASS_VOLUME, volg deze stappen.

Opmerking  Wij raden aan dat u het hulpprogramma DevNodeClean voor deze taak gebruiken. De volgende stappen en in het codevoorbeeld in stap 7 dienen alleen ter informatie.

  1. Roep de functie SetupDiGetClassDevs om de informatie voor de klasse die is gekoppeld aan de GUID te verkrijgen.

  2. Roep de functie SetupDiEnumDeviceInfo om informatie voor elk apparaat in de huidige klasse exemplaar te verkrijgen.

  3. Roep de functie CM_Get_DevNode_Status om te zien of de huidige gegevens van een apparaat een apparaat niet aanwezig vertegenwoordigt. Bepaalt of de functie status gelijk aan CR_NO_SUCH_DEVINST of CR_NO_SUCH_VALUE is.

  4. Eventueel voor een apparaat niet aanwezig, roept u de functie CM_Get_Device_ID de apparaatinstantie-ID te verkrijgen en de ID weergeven voordat u de gegevens verwijderen.

  5. Gebruik de informatie die u in stap 1 hebt gekregen en de informatie over het exemplaar dat u in stap 2 verkregen voor het apparaat niet aanwezig. Roep de functie SetupDiCallClassInstaller (DIF_REMOVE,...) om de informatie uit het register verwijderen.

  6. Wanneer alle apparaten in de huidige klasse zijn verwerkt, roept u de functie SetupDiDestroyDeviceInfoList om op te schonen.

Opmerking In sommige gevallen moet u wellicht het register schoon, niet alleen voor de GUID_DEVCLASS_DISKDRIVE en GUID_DEVCLASS_VOLUME schijf klasse-GUID's, maar ook voor de GUID_DEVCLASS_SCSIADAPTER en GUID_DEVCLASS_VOLUMESNAPSHOT schijf klasse-GUID's. Hiervoor moet u de definitie van de DiskClassesToClean in de volgende voorbeeldcode.

De volgende toepassing van de Win32-console is een voorbeeld van een toepassing die het opruimen van het register. Volg deze stappen voor het gebruik van deze toepassing.

Microsoft verstrekt programmeervoorbeelden uitsluitend ter illustratie, zonder expliciete of impliciete garantie. Dit omvat, maar is niet beperkt tot, de impliciete garanties van verkoopbaarheid of geschiktheid voor een bepaald doel. In dit artikel wordt ervan uitgegaan dat u bekend met de programmeertaal die wordt aangetoond en met de hulpprogramma's die worden gebruikt bent voor het maken van en naar procedures voor foutopsporing. Ondersteuningstechnici van Microsoft kunnen voor uitleg over de functionaliteit van een bepaalde procedure. Zij zal deze voorbeelden bieden extra functionaliteit of desgewenst uw specifieke vereisten echter niet wijzigen.

  1. In Microsoft Visual Studio 2005, klikt u in het menu bestand op Nieuw en klik vervolgens op Project.

  2. Vouw Visual C++en klik vervolgens op Win32.

  3. Klik op Win32 consoletoepassing, typ Schijfopruiming in het tekstvak naam en klik op OK.

  4. Klik op Voltooien in het dialoogvenster Wizard Win32-toepassing .

  5. Vouw Bronbestandenin Solution Explorer met de rechtermuisknop op Cleanup.cppen klikt u vervolgens op Programmacode weergeven.

  6. Zoek de volgende code:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. De code die u hebt gevonden in stap 6 met de volgende code vervangen.

    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. Klik in het menu Foutopsporing en klik op Foutopsporing Start.

Het bouwen voor Windows Server 2012 en Visual Studio 2012

Ga als volgt te werk om te maken voor Windows Server 2012 en Microsoft Visual Studio 2012.

Opmerking  Wij raden aan dat u het hulpprogramma DevNodeClean voor deze taak gebruiken. De volgende stappen en in het codevoorbeeld in stap 7 dienen alleen ter informatie.

  1. In Microsoft Visual Studio 2012, klik op Nieuw in het menu bestand en klik vervolgens op Project.

  2. Klik in het dialoogvenster Nieuw Project Typ Schijfopruiming in het veld naam en dubbelklik vervolgens op Win32-Project.

  3. Klik op volgendein de Wizard Win32-toepassing.

  4. Schakel Consoletoepassingonder type toepassingen klik op Voltooien.

  5. Vouw Bronbestandenin Solution Explorer met de rechtermuisknop op Cleanup.cppen klikt u vervolgens op Programmacode weergeven.

  6. Zoek de volgende code:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. De code die u hebt gevonden in stap 6 met de volgende code vervangen.

    //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 de Solution Explorer met de rechtermuisknop op het opruimenen klik vervolgens op Eigenschappen.

  9. Vouw de Configuratie-eigenschappen, Linkeruitbreiden en klik op invoer.

  10. Extra afhankelijkhedente selecteren, klikt u op de pijl-omlaag en selecteer vervolgens bewerken.

  11. In het dialoogvenster Extra afhankelijkheden , type setupapi.lib en cfgmgr32.lib.

  12. Klik tweemaal op OK.

  13. Compileer het project.

Meer hulp nodig?

Meer opties?

Verken abonnementsvoordelen, blader door trainingscursussen, leer hoe u uw apparaat kunt beveiligen en meer.

Community's helpen u vragen te stellen en te beantwoorden, feedback te geven en te leren van experts met uitgebreide kennis.

Was deze informatie nuttig?

Hoe tevreden bent u met de taalkwaliteit?
Wat heeft uw ervaring beïnvloed?
Als u op Verzenden klikt, wordt uw feedback gebruikt om producten en services van Microsoft te verbeteren. Uw IT-beheerder kan deze gegevens verzamelen. Privacyverklaring.

Hartelijk dank voor uw feedback.

×