Jak odebrat informace registru pro zařízení, která nebudou nikdy použity znovu v počítači se systémem Windows Server 2003 nebo novější

Překlady článku Překlady článku
ID článku: 934234 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

ÚVOD

V počítači se systémem Windows Server 2003 nebo novější verzi systému Windows může být připojeno zařízení úložiště, který je připojen prostřednictvím fiber channel nebo iSCSI protokol pouze na krátkou dobu. Je-li připojen k zařízení úložiště, vytvoří systém Windows informace registru pro zařízení. V průběhu času registru může obsahovat mnoho položek pro zařízení, která nebudou nikdy použity znovu. Tento článek popisuje, jak odebrat tyto údaje ze systémového registru.

Další informace

Při připojení nového zařízení k počítači, systém Windows zaznamená informace o zařízení v systémovém registru. Tento postup u většiny zařízení nepředstavuje problém. Však po číslo logické jednotky (LUN) pomocí fiber channel nebo iSCSI je předložena paměťové zařízení, zařízení pravděpodobně nikdy se vyskytuje znovu počítač. Zařízení lze označit například sériové číslo, nebo SCSI stránky 0x80 a 0x83.

V takovém případě registru může obsahovat položky pro zařízení, které se nikdy mohou znovu objevit. Nejen se tyto položky zabírají místo v registru, tyto položky mohou způsobit provozní problémy. Například protože indexy pro funkce Plug and Play pomocí čtyř číslic desítkové hodnoty, může dojít k potížím při připojení zařízení 10,001.

Chcete-li vyřešit toto omezení funkce Plug and Play, můžete odebrat z registru informace o zařízení, když je zařízení na jednotku pevného disku, který již neexistuje. Můžete to provést pomocí Microsoft DevNodeClean nástroj.

Jak sestavit pro systém Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 a Visual Studio 2005

Chcete-li vyčistit do registru identifikátor GUID třídy disku GUID_DEVCLASS_DISKDRIVE a GUID_DEVCLASS_VOLUME na disku identifikátor GUID třídy, postupujte takto.

Poznámka:Doporučujeme použít DevNodeCleanNástroj pro tento úkol. Následující postup a příklad kódu v kroku 7 jsou poskytovány pouze pro informační účely.
  1. Volání funkce SetupDiGetClassDevs Chcete-li získat informace o třídě, který je přidružen k identifikátoru GUID.
  2. Volání funkce SetupDiEnumDeviceInfo Chcete-li získat informace o instanci pro všechna zařízení v aktuální třídy.
  3. Volání funkce CM_Get_DevNode_Status Chcete-li zjistit, zda aktuální informace o zařízení představuje chybí zařízení. Zjistěte, zda je stav funkce CR_NO_SUCH_DEVINST nebo CR_NO_SUCH_VALUE.
  4. Případně chybí zařízení, volání funkce CM_Get_Device_ID Chcete-li získat ID instance zařízení a chcete-li zobrazit ID před odebráním informací.
  5. Chybí zařízení pomocí informací třídy, který jste získali v kroku 1 a informace o instanci, který jste získali v kroku 2. Volání funkce SetupDiCallClassInstaller (DIF_REMOVE,...) k odstranění informací z registru.
  6. Při všech zařízení v aktuální třídě byly manipulovány, volání funkce SetupDiDestroyDeviceInfoList pro vyčištění.
Poznámka: V některých případech může mít nejen pro GUID_DEVCLASS_DISKDRIVE a GUID_DEVCLASS_VOLUME disk GUID třídy ale také pro GUID_DEVCLASS_SCSIADAPTER a GUID_DEVCLASS_VOLUMESNAPSHOT třídy GUID disku čištění registru. Chcete-li to provést, musíte změnit definici DiskClassesToClean v následujícím ukázkovém kódu.

Následující aplikace konzoly Win32 je příkladem aplikace, která čistí registru. Chcete-li tuto aplikaci používat, postupujte takto.

Společnost Microsoft poskytuje ukázky programování pouze pro ilustraci bez žádné záruky výslovně uvedené nebo odvozené. Zejména jde o implicitní záruky obchodovatelnosti nebo vhodnosti pro určitý účel. Tento článek předpokládá, že jste obeznámeni s programovacím jazykem, který je předmětem ukázky, a s nástroji, které se používají k vytvoření a ladění skriptu. Pracovníci podpory společnosti Microsoft mohou vysvětlit funkce určitého postupu. Nemohou však následující příklady rozšířit o další funkce nebo konstrukce podle konkrétních požadavků.
  1. V aplikaci Microsoft Visual Studio 2005 v nabídce soubor klepněte na příkaz Nový a klepněte na příkaz projekt.
  2. Rozbalte Visual C++a klepněte na Win32.
  3. Klepněte na tlačítko Aplikace konzoly Win32, zadejte Vyčištění v textu název a klepněte na tlačítko OK.
  4. Klepněte na tlačítko Dokončit v dialogovém okně Průvodce aplikací Win32 .
  5. V Průzkumníku řešení rozbalte Zdrojové soubory, klepněte pravým tlačítkem myši Cleanup.cppa potom klepněte na tlačítko Zobrazit kód.
  6. Vyhledejte následující kód:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Nahraďte kód, který jste nalezli v kroku 6 následujícím kódem.
    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. V nabídce Debug klepněte na tlačítko a potom klepněte na příkaz Spustit ladění.

Jak sestavit pro Windows Server 2012 a Visual Studio 2012

Chcete-li sestavit Windows Server 2012 a Microsoft Visual Studio 2012, postupujte takto.

Poznámka:Doporučujeme použítDevNodeCleanNástroj pro tento úkol. Následující postup a příklad kódu v kroku 7 jsou poskytovány pouze pro informační účely.
  1. V aplikaci Microsoft Visual Studio 2012 v nabídce soubor klepněte na příkaz Nový a klepněte na příkaz projekt.
  2. Zadejte v dialogovém okně Nový projektVyčištění do pole název pole a potom poklepejte na Projekt Win32.
  3. V Průvodci aplikací Win32 klikněte na Další.
  4. Ve skupinovém rámečku Typ aplikace, klepněte na tlačítko vyberte <b00> </b00>aplikace konzolya potom klepněte na tlačítko Dokončit.
  5. V Průzkumníku řešení rozbalte Zdrojové soubory, klepněte pravým tlačítkem myši Cleanup.cppa potom klepněte na tlačítko Zobrazit kód.
  6. Vyhledejte následující kód:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Nahraďte kód, který jste nalezli v kroku 6 následujícím kódem.
    //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. V Průzkumníku řešení klepněte pravým tlačítkem na Vyčištěnía potom klepněte na příkaz Vlastnosti.
  9. Rozbalte uzel Vlastnosti konfigurace, rozbalte Linkera potom klepněte na tlačítko vstup.
  10. Vyberte Další závislosti, klepněte na šipku dolů a vyberte Upravit.
  11. V dialogovém okně Další závislosti , typ setupapi.lib a cfgmgr32.lib.
  12. Klepněte dvakrát na tlačítko OK.
  13. Sestavte projekt.

Vlastnosti

ID článku: 934234 - Poslední aktualizace: 10. července 2014 - Revize: 4.0
Informace v tomto článku jsou určeny pro produkt:
  • 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
Klíčová slova: 
kboem kbcode kbinfo kbhowto kbmt KB934234 KbMtcs
Strojově přeložený článek
DŮLEŽITÉ: Tento článek je přeložen pomocí softwaru na strojový překlad Microsoft. Nepřesný či chybný překlad lze opravit prostřednictvím technologie Community Translation Framework (CTF). Microsoft nabízí strojově přeložené, komunitou dodatečně upravované články, a články přeložené lidmi s cílem zajistit přístup ke všem článkům v naší znalostní bázi ve více jazycích. Strojově přeložené a dodatečně upravované články mohou obsahovat chyby ve slovníku, syntaxi a gramatice. Společnost Microsoft není odpovědná za jakékoliv nepřesnosti, chyby nebo škody způsobené nesprávným překladem obsahu nebo jeho použitím našimi zákazníky. Více o CTF naleznete na http://support.microsoft.com/gp/machine-translation-corrections/cs.
Projděte si také anglickou verzi článku: 934234

Dejte nám zpětnou vazbu

 

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