Ta bort registerinformationen för enheter som aldrig kommer att användas igen

Gäller för: 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)

Introduktion


När en lagringsenhet är ansluten till Windows, även om endast en kort windows skapar registerinformation för enheten. Registret över tiden, kan den innehålla många transaktioner för enheter som aldrig kommer att användas igen. Den här artikeln beskrivs hur du tar bort denna information från systemregistret.
Det åligger programvara som upprättar anslutningen mellan lagringsenhet och rensa korrekt information för enheten i Windows. Detta är nödvändigt eftersom Windows inte vet när en lagringsenhet tas bort tillfälligt eller permanent. Men känner programvara som upprättar anslutningen normalt detta. Till exempel om säkerhetskopieringsprogram montera logiska enhetsnummer (LUN) för säkerhetskopiering och demontera LUN, skulle det vara ansvar säkerhetskopieringsprogram för att rensa LUN-information från Windows, eftersom samma lagringsenhet kommer inte längre användas igen i Windows.

Mer Information


När en ny enhet ansluts till en dator, Windows registrerar information om enheten i systemregistret. För de flesta enheter utgör proceduren inte ett problem. Men när en lagringsenhet presenteras av LUN via en fiber channel eller iSCSI, kan enheten aldrig uppstå igen av datorn. Till exempel kan en enhet identifieras genom ett serienummer eller 0x80 och 0x83 SCSI-sidor.

I den här situationen kan registret innehåller poster för enheter som aldrig visas igen. Inte bara dessa transaktioner som upptar utrymme i registret, posterna så småningom kan orsaka funktionsproblem. Till exempel eftersom index för Plug and Play-funktioner använder fyrsiffriga decimalvärden, kan ett problem uppstå när 10,001-enheten är ansluten.

Lös den här begränsningen i Plug and Play-funktion, kanske du vill ta bort enhetsinformation från registret när enheten är en hårddisk som inte längre finns. Du kan göra detta med hjälp av verktyget Microsoft DevNodeClean .

Hur du skapar för Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 och Visual Studio 2005

Följ dessa steg om du vill rensa i registret för GUID_DEVCLASS_DISKDRIVE disk klass-GUID och disk klass-GUID för GUID_DEVCLASS_VOLUME.

Obs!  Vi rekommenderar att du använder verktyget DevNodeClean för aktiviteten. Följande steg och kodexempel i steg 7 tillhandahålls endast i informationssyfte.

  1. Anropa funktionen SetupDiGetClassDevs för att få information om klassen som är associerad med GUID.
  2. Anropa funktionen SetupDiEnumDeviceInfo kunde du hämtar instansinformation för varje enhet i den aktuella klassen.
  3. Anropa funktionen CM_Get_DevNode_Status för att se om den aktuella enhetsinformationen om representerar en enhet som är frånvarande. Avgöra om funktionen status är lika med CR_NO_SUCH_DEVINST eller till CR_NO_SUCH_VALUE.
  4. Du kan också för en frånvarande anropa funktionen CM_Get_Device_ID hämta instans-ID för enheten och visa-ID innan du tar bort informationen.
  5. Frånvarande enheten använda i klassinformationen som du hämtade i steg 1 och instansinformation som du hämtade i steg 2. Anropa funktionen SetupDiCallClassInstaller (DIF_REMOVE,...) om du vill ta bort informationen från registret.
  6. När alla enheter i den aktuella klassen har hanterats, anropa funktionen SetupDiDestroyDeviceInfoList för att rensa upp.

Obs! I vissa fall kan behöva du rensa registret, inte bara för GUID_DEVCLASS_DISKDRIVE och GUID_DEVCLASS_VOLUME disk klass-GUID, utan också för GUID_DEVCLASS_SCSIADAPTER och GUID_DEVCLASS_VOLUMESNAPSHOT disk klass-GUID. Om du vill göra detta måste du ändra DiskClassesToClean definition i följande exempelkod.

Följande Win32 console-program är ett exempel på ett program som rensar registret. Gör följande om du vill använda det här programmet.

Microsoft tillhandahåller programmeringsexempel endast utan garanti varken uttryckliga eller underförstådda. Detta inkluderar men är inte begränsat till, underförstådda garantier om säljbarhet eller lämplighet för ett särskilt ändamål. Den här artikeln förutsätter att du är bekant med det programmeringsspråk som demonstreras och de verktyg som används för att skapa och felsöka procedurer. Microsofts supporttekniker kan hjälpa till att förklara funktionen hos en viss procedur. De kommer inte ändra dessa exempel för att ge ytterligare funktioner eller skapa procedurer som motsvarar dina speciella behov.

  1. Klicka på NyArkiv -menyn och sedan på projekti Microsoft Visual Studio 2005.
  2. Expandera Visual C++och klicka sedan på Win32.
  3. Klicka på Win32-program för konsolenoch skriv Diskrensning i textrutan namn .
  4. Klicka på Slutför i dialogrutan Guiden för Win32-program .
  5. Expandera Källfileri Solution Explorer, högerklicka på Cleanup.cppoch klicka på Visa kod.
  6. Leta upp följande kod:
    int _tmain(int argc, _TCHAR* argv[]){return 0;}
  7. Ersätta den kod som du hittade i steg 6 med följande kod.
    /**************************************************************************************************/     /*                                                                                                */     /* 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__cdeclmain(     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. Klicka på Felsök -menyn och klicka sedan på Starta felsökning.

Hur du skapar för Windows Server 2012 och Visual Studio 2012

Följ dessa steg om du vill skapa för Windows Server 2012 och Microsoft Visual Studio 2012.

Obs!  Vi rekommenderar att du använder verktyget DevNodeClean för aktiviteten. Följande steg och kodexempel i steg 7 tillhandahålls endast i informationssyfte.

  1. Klicka på NyArkiv -menyn och sedan på projekti Microsoft Visual Studio 2012.
  2. Skriv rensning i fältet namn i dialogrutan Nytt projekt och dubbelklicka sedan på Win32-projekt.
  3. Klicka på Nästai guiden Win32-program.
  4. Markera Konsolprogramunder Programtypoch klicka sedan på Slutför.
  5. Expandera Källfileri Solution Explorer, högerklicka på Cleanup.cppoch klicka på Visa kod.
  6. Leta upp följande kod:
    int _tmain(int argc, _TCHAR* argv[]){return 0;}
  7. Ersätta den kod som du hittade i steg 6 med följande kod.
    //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__cdeclmain(     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. Högerklicka på rensningi Solution Explorer och klicka sedan på Egenskaper.
  9. Expandera Konfigurationsegenskaper Linker, och klicka sedan på inmatning.
  10. Markera Ytterligare beroendenklickar du på nedpilen och välj sedan Redigera.
  11. I dialogrutan för Ytterligare beroenden , typ setupapi.lib och cfgmgr32.lib.
  12. Klicka på OK två gånger.
  13. Bygga projektet.