Logg på med Microsoft
Logg på, eller opprett en konto.
Hei,
Velg en annen konto.
Du har flere kontoer
Velg kontoen du vil logge på med.

INTRODUKSJON

Når en lagringsenhet som er koblet til Windows, selv om bare en kort stund, oppretter windows registerinformasjonen for enheten. Registret kan inneholde mange poster for enheter som aldri vil bli brukt på nytt over tid. Denne artikkelen beskriver hvordan du fjerner denne informasjonen fra systemregistret.

Det er ansvaret til programvaren som etablerer forbindelsen mellom lagringsenhet og Windows skal rydde opp informasjonen for enheten. Denne prosessen er nødvendig fordi Windows ikke vet når en lagringsenhet fjernes midlertidig eller permanent. Men programvaren som etablerer forbindelsen vanligvis vet dette. For eksempel hvis programvare for sikkerhetskopiering er montering logisk enhet tall (LUN) for sikkerhetsformål og deretter demontering av LUN-er, vil det være ansvarlig for programvare for sikkerhetskopiering til å rydde opp LUN-informasjon fra Windows, fordi den samme lagringsenheten vises ikke lenger brukes på nytt av Windows.

Hvis du vil ha mer informasjon

Når en ny enhet er koblet til en datamaskin, Windows registrerer informasjon om enheten i systemregistret. For de fleste enheter utgjør ikke dette et problem. Men etter at en lagringsenhet som presenteres av en LUN via en fiberkanal eller iSCSI, kan enheten aldri oppstå på nytt av datamaskinen. En enhet kan for eksempel identifiseres ved et serienummer eller SCSI-sider 0x80 og 0x83.

I så fall kan registret inneholder oppføringer for enheter som ikke kan vises på nytt. Ikke bare gjør disse oppføringene opptar plass i registret, disse oppføringene kan til slutt føre til operasjonelle problemer. Hvis du for eksempel fordi indeksene for Plug and Play-funksjonalitet bruke firesifrede desimalverdier, kan problemer oppstå når 10,001-enheten er koblet.

Hvis du vil løse denne begrensningen i Plug and Play-funksjonalitet, kan du vil fjerne enhetsinformasjon fra registret når enheten er en harddisk som ikke lenger finnes. Du kan gjøre dette ved hjelp av verktøyet Microsoft DevNodeClean .

Hvordan å lage programmer for Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 og Visual Studio 2005

Følg disse trinnene for å rense registeret for GUID_DEVCLASS_DISKDRIVE disk klasse-GUIDEN og disk klasse-GUID for GUID_DEVCLASS_VOLUME.

Obs!  Vi anbefaler at du bruker verktøyet DevNodeClean for denne aktiviteten. De følgende trinnene og kodeeksemplet i trinn 7 tilbys bare for informasjonsformål.

  1. Kall SetupDiGetClassDevs -funksjonen for å hente informasjon for klassen som er knyttet til GUIDEN.

  2. Kall SetupDiEnumDeviceInfo -funksjonen for å få informasjon om forekomst for hver enhet i gjeldende klasse.

  3. Kall CM_Get_DevNode_Status -funksjonen for å se om informasjon om gjeldende enhet representerer en enhet som er borte. Avgjør om Funksjonsstatus er lik CR_NO_SUCH_DEVINST eller CR_NO_SUCH_VALUE.

  4. Hvis du vil, for en-enhet kalle funksjonen CM_Get_Device_ID skaffer forekomst-ID for enheten og vise IDen før du fjerner informasjonen.

  5. For enheten ikke vises, kan du bruke Klasseinformasjonen som du fikk i trinn 1 og forekomst-informasjonen som du fikk i trinn 2. Kall funksjonen SetupDiCallClassInstaller (DIF_REMOVE,...) for å fjerne informasjon fra registret.

  6. Når alle enhetene i gjeldende klasse er håndtert, kall SetupDiDestroyDeviceInfoList -funksjonen til å rydde opp i.

Obs! I noen scenarier kan har du til å rense registeret ikke bare for GUID_DEVCLASS_DISKDRIVE og GUID_DEVCLASS_VOLUME disk klasse GUIDer, men også for GUID_DEVCLASS_SCSIADAPTER og GUID_DEVCLASS_VOLUMESNAPSHOT klasse GUIDer på disken. Hvis du vil gjøre dette, må du endre definisjonen av DiskClassesToClean i følgende eksempelkode.

Følgende program for Win32-konsollen er et eksempel på et program som rydder registeret. Følg disse trinnene for å bruke dette programmet.

Microsoft bruker ment som eksempler, uten garanti, verken direkte eller indirekte. Dette inkluderer, men er ikke begrenset til, eventuelle stilltiende garantier om salgbarhet eller anvendelighet for særskilte formål. Denne artikkelen forutsetter at du er kjent med programmeringsspråket som anvendes, og verktøyene som brukes til å opprette og feilsøke prosedyrer. Microsofts kundestøtteteknikere kan hjelpe deg med å forklare funksjonaliteten til en bestemt prosedyre. De endrer imidlertid ikke disse eksemplene for å lage forbedret funksjonalitet eller lage prosedyrer som dekker dine spesifikke behov.

  1. I Microsoft Visual Studio 2005, klikker du Nyfil -menyen, og klikk deretter prosjektet.

  2. Utvid Visual C++, og klikk deretter Win32.

  3. Klikk Win32 Console Application, Skriv Diskopprydding i navn -tekstboksen, og klikk deretter OK.

  4. Klikk Fullfør i dialogboksen Veiviser for Win32-program .

  5. Utvid Kildefilenei Solution Explorer, høyreklikk Cleanup.cpp, og deretter Visingskode.

  6. Finn følgende kode:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. Erstatte koden som du fant i trinn 6 med følgende kode.

    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. Klikk feilsøking -menyen, og klikk deretter Start feilsøking.

Hvordan du bygger for Windows Server 2012 og Visual Studio 2012

Følg disse trinnene for å bygge for Windows Server 2012 og Microsoft Visual Studio 2012.

Obs!  Vi anbefaler at du bruker verktøyet DevNodeClean for denne aktiviteten. De følgende trinnene og kodeeksemplet i trinn 7 tilbys bare for informasjonsformål.

  1. I Microsoft Visual Studio 2012, klikker du Nyfil -menyen, og klikk deretter prosjektet.

  2. Skriv inn Opprydding i navn -feltet i dialogboksen Nytt prosjekt , og dobbeltklikk deretter Win32-prosjekt.

  3. Klikk Nestei veiviseren for Win32-program.

  4. Klikk for å velge Konsollprogramunder programtypen, og klikk deretter Fullfør.

  5. Utvid Kildefilenei Solution Explorer, høyreklikk Cleanup.cpp, og deretter Visingskode.

  6. Finn følgende kode:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. Erstatte koden som du fant i trinn 6 med følgende kode.

    //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. I Solution Explorer, høyreklikk Opprydding.

  9. Utvid Konfigurasjonsegenskaper, utvide Linker, og klikk deretter inndata.

  10. Velg Flere avhengigheter, klikker du pil ned, og velg deretter Rediger.

  11. I dialogboksen Flere avhengigheter , type setupapi.lib og cfgmgr32.lib.

  12. Klikk OK to ganger.

  13. Bygg prosjektet.

Trenger du mer hjelp?

Vil du ha flere alternativer?

Utforsk abonnementsfordeler, bla gjennom opplæringskurs, finn ut hvordan du sikrer enheten og mer.

Fellesskap hjelper deg med å stille og svare på spørsmål, gi tilbakemelding og høre fra eksperter med stor kunnskap.

Var denne informasjonen nyttig?

Hvor fornøyd er du med språkkvaliteten?
Hva påvirket opplevelsen din?
Når du trykker på Send inn, blir tilbakemeldingen brukt til å forbedre Microsoft-produkter og -tjenester. IT-administratoren kan samle inn disse dataene. Personvernerklæring.

Takk for tilbakemeldingen!

×