Como remover as informações de registro para dispositivos que nunca usará novamente em um computador que esteja executando o Windows Server 2003 ou uma versão posterior

Traduções deste artigo Traduções deste artigo
ID do artigo: 934234 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

INTRODUÇÃO

Em um computador que esteja executando o Windows Server 2003 ou uma versão posterior do Windows, um dispositivo de armazenamento que está conectado por meio de um canal de fibra ou o protocolo iSCSI pode ser conectado por apenas um breve período. Quando um dispositivo de armazenamento está conectado, o Windows cria informações do registro para o dispositivo. Ao longo do tempo, o registro pode conter várias entradas para dispositivos que nunca serão usados novamente. Este artigo descreve como remover essas informações do registro do sistema.

Mais Informações

Quando um novo dispositivo é conectado a um computador, registra as informações Windows sobre o dispositivo no registro do sistema. Para a maioria dos dispositivos, esse procedimento não representar um problema. No entanto, depois que um dispositivo de armazenamento é apresentado por um número de unidade lógica (LUN) por meio de um canal de fibra ou iSCSI, o dispositivo pode nunca ser encontrado novamente pelo computador. Por exemplo, um dispositivo pode ser identificado por um número de série ou por páginas de SCSI 0x80 e 0x83.

Nessa situação, o registro pode conter entradas para dispositivos que nunca podem aparecer novamente. Não só fazer essas entradas ocupam espaço no registro, essas entradas podem eventualmente causar problemas operacionais. Por exemplo, como índices para a funcionalidade Plug and Play usam valores decimais de quatro dígitos, um problema pode ocorrer quando o dispositivo 10,001 está conectado.

Para resolver essa limitação na funcionalidade Plug and Play, convém remover as informações de dispositivo do registro quando o dispositivo é uma unidade de disco rígido que não está mais presente. Você pode fazer isso usando o Microsoft DevNodeClean utilitário.

Como construir para Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 e o Visual Studio 2005

Para limpar o registro para o GUID de classe do disco, no GUID_DEVCLASS_DISKDRIVE e para o GUID_DEVCLASS_VOLUME GUID de classe do disco, siga estas etapas.

ObservaçãoRecomendamos que você use o DevNodeCleanUtilitário para esta tarefa. As etapas a seguir e o exemplo de código na etapa 7 são fornecidas apenas para fins informativos.
  1. Chame a função SetupDiGetClassDevs para obter informações para a classe que está associada com o GUID.
  2. Chame a função SetupDiEnumDeviceInfo para obter informações da instância para cada dispositivo na classe atual.
  3. Chame a função CM_Get_DevNode_Status para ver se as informações do dispositivo atual representam um dispositivo ausente. Determine se o status da função é igual a CR_NO_SUCH_DEVINST ou a CR_NO_SUCH_VALUE.
  4. Opcionalmente, para um dispositivo ausente, chame a função CM_Get_Device_ID para obter a identificação de instância de dispositivo e para exibir a ID antes de remover as informações.
  5. Para o dispositivo ausente, use as informações de classe que você obteve na etapa 1 e as informações da instância que você obteve na etapa 2. Chame a função SetupDiCallClassInstaller (DIF_REMOVE...) para remover as informações do registro.
  6. Quando todos os dispositivos na classe atual foram tratados, chame a função SetupDiDestroyDeviceInfoList para limpar.
Observação Em alguns cenários, talvez você precise limpar o registro, não apenas para o GUID_DEVCLASS_DISKDRIVE e o GUID_DEVCLASS_VOLUME do disco GUIDs de classe mas também para o GUID_DEVCLASS_SCSIADAPTER e o GUID_DEVCLASS_VOLUMESNAPSHOT do disco GUIDs de classe. Para fazer isso, você deve alterar a definição de DiskClassesToClean no código de exemplo a seguir.

O seguinte aplicativo do console Win32 é um exemplo de um aplicativo que limpa o registro. Para usar este aplicativo, siga estas etapas.

A Microsoft fornece exemplos de programação apenas para ilustração, sem garantia expressa ou implícita. Isso inclui, mas não está limitado a, garantias implícitas de comercialização ou adequação a um propósito específico. Este artigo presume que você esteja familiarizado com a linguagem de programação que está sendo demonstrada e com as ferramentas que são usadas para criar e depurar procedimentos. Engenheiros de suporte da Microsoft podem ajudar a explicar a funcionalidade de um determinado procedimento. No entanto, eles não modificarão esses exemplos para fornecer funcionalidades adicionais ou construir procedimentos para atender às suas necessidades específicas.
  1. No Microsoft Visual Studio 2005, clique em novo no menu arquivo e, em seguida, clique em Project.
  2. Expanda Visual C++e, em seguida, clique em Win32.
  3. Clique em Aplicativo do Console Win32, tipo Limpeza no texto nome caixa e, em seguida, clique em OK.
  4. Clique em Concluir na caixa de diálogo Assistente de aplicativos Win32 .
  5. No Solution Explorer, expanda Arquivos de origem, clique com o botão Cleanup.cppe, em seguida, clique em View Code.
  6. Localize o código a seguir:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Substitua o código que você encontrou na etapa 6 com o código a seguir.
    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. Clique no menu Debug e, em seguida, clique em Iniciar depuração.

Como construir para o Windows Server 2012 e o Visual Studio 2012

Para criar para o Windows Server 2012 e o Microsoft Visual Studio 2012, siga estas etapas.

ObservaçãoRecomendamos que você use oDevNodeCleanUtilitário para esta tarefa. As etapas a seguir e o exemplo de código na etapa 7 são fornecidas apenas para fins informativos.
  1. No Microsoft Visual Studio 2012, clique em novo no menu arquivo e, em seguida, clique em Project.
  2. Na caixa de diálogo New Project , digite Limpeza o nome do campo e, em seguida, clique duas vezes em Win32 Project.
  3. No Win32 Application Wizard, clique em Avançar.
  4. Em tipo de aplicativo, clique para selecionar <b00> </b00>aplicativo de Consolee, em seguida, clique em Concluir.
  5. No Solution Explorer, expanda Arquivos de origem, clique com o botão Cleanup.cppe, em seguida, clique em View Code.
  6. Localize o código a seguir:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Substitua o código que você encontrou na etapa 6 com o código a seguir.
    //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. No Solution Explorer, clique com o botão Limpare, em seguida, clique em Propriedades.
  9. Expanda Configuration Properties, expanda vinculadore, em seguida, clique em entrada.
  10. Selecione Dependências adicionais, clique na seta para baixo e, em seguida, selecione Editar.
  11. Na caixa de diálogo Dependências adicionais , tipo setupapi.lib e cfgmgr32.lib.
  12. Clique duas vezes em OK .
  13. Compile o projeto.

Propriedades

ID do artigo: 934234 - Última revisão: domingo, 13 de julho de 2014 - Revisão: 3.0
A informação contida neste artigo aplica-se 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
Palavras-chave: 
kboem kbcode kbinfo kbhowto kbmt KB934234 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido pelo software de tradução automática da Microsoft e eventualmente pode ter sido editado pela Microsoft Community através da tecnologia Community Translation Framework (CTF) ou por um tradutor profissional. A Microsoft oferece artigos traduzidos automaticamente por software, por tradutores profissionais e editados pela comunidade para que você tenha acesso a todos os artigos de nossa Base de Conhecimento em diversos idiomas. No entanto, um artigo traduzido pode conter erros de vocabulário, sintaxe e/ou gramática. A Microsoft não é responsável por qualquer inexatidão, erro ou dano causado por qualquer tradução imprecisa do conteúdo ou por seu uso pelos nossos clientes.
Clique aqui para ver a versão em Inglês deste artigo: 934234

Submeter comentários

 

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