Como remover informações de registo para dispositivos que nunca irão ser utilizados novamente num computador que esteja a executar o Windows Server 2003 ou uma versão posterior

Traduções de Artigos Traduções de Artigos
Artigo: 934234 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

INTRODUÇÃO

Num computador que esteja a executar o Windows Server 2003 ou uma versão posterior do Windows, um dispositivo de armazenamento que está ligado através de um canal de Fibra ou através do protocolo iSCSI pode ser ligado por um breve período. Quando está ligado um dispositivo de armazenamento, o Windows cria informações de registo para o dispositivo. Ao longo do tempo, o registo pode conter muitos movimentos para dispositivos que nunca serão utilizados novamente. Este artigo descreve como remover estas informações do registo do sistema.

Mais Informação

Quando um novo dispositivo está ligado a um computador, informações de registos do Windows sobre o dispositivo no registo do sistema. Para a maioria dos dispositivos, este procedimento não constituir um problema. No entanto, depois de um dispositivo de armazenamento é apresentado por um número de unidade lógica (LUN) através de um canal de Fibra ou iSCSI, o dispositivo poderá 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.

Nesta situação, o registo pode conter entradas para dispositivos que nunca podem aparecer de novo. Não só efectue estas entradas de ocupar espaço no registo, estas entradas podem eventualmente causar problemas de funcionamento. Por exemplo, uma vez que os índices para a funcionalidade Plug and Play utilizam valores decimais de quatro dígitos, poderá ocorrer um problema quando está ligado o dispositivo 10,001.

Para resolver esta limitação na funcionalidade Plug and Play, poderá remover informações sobre o dispositivo do registo quando o dispositivo é uma unidade de disco rígido que já não está presente. Pode fazê-lo utilizando o Microsoft DevNodeClean utilitário.

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

Para limpar o registo para a classe de disco GUID_DEVCLASS_DISKDRIVE GUID e para o GUID_DEVCLASS_VOLUME de GUID de classe de disco, siga estes passos.

NotaRecomendamos que utilize a DevNodeCleanutilitário para esta tarefa. Os seguintes passos e o exemplo de código no passo 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 sobre ocorrências para cada dispositivo na classe actual.
  3. Chame a função CM_Get_DevNode_Status para ver se as informações do dispositivo actual representam um dispositivo ausente. Determine se o estado da função é igual a CR_NO_SUCH_DEVINST ou CR_NO_SUCH_VALUE.
  4. Opcionalmente, para um dispositivo ausente, chame a função de CM_Get_Device_ID para obter o ID de instância de dispositivo e para apresentar o ID antes de remover as informações.
  5. Para o dispositivo ausente, utilize as informações de classe obtido no passo 1 e as informações de instância obtido no passo 2. Chame a função SetupDiCallClassInstaller (DIF_REMOVE...) para remover as informações do registo.
  6. Quando todos os dispositivos da classe actual tenham sido manuseados, chame a função de SetupDiDestroyDeviceInfoList para limpar.
Nota Em alguns cenários, poderá ter de limpar o registo não só para o GUID_DEVCLASS_DISKDRIVE e GUID_DEVCLASS_VOLUME do disco GUIDs de classe mas também para os GUID_DEVCLASS_SCSIADAPTER e GUID_DEVCLASS_VOLUMESNAPSHOT do disco GUIDs de classe. Para tal, tem de alterar a definição DiskClassesToClean no seguinte exemplo de código.

A seguinte aplicação de consola do Win32 é um exemplo de uma aplicação que limpa o registo. Para utilizar esta aplicação, siga estes passos.

A Microsoft fornece exemplos de programação apenas, a título sem garantia expressa ou implícita. Isto inclui, mas não está limitado a, garantias implícitas de comercialização ou adequação a um fim específico. Este artigo pressupõe que está familiarizado com a linguagem de programação apresentada e com as ferramentas que são utilizadas para criar e depurar procedimentos. Técnicos de suporte da Microsoft podem ajudar a explicar a funcionalidade de um determinado procedimento. No entanto, não modificarão estes exemplos para proporcionarem funcionalidades adicionais nem criarão procedimentos adaptados às necessidades específicas do utilizador.
  1. No Microsoft Visual Studio 2005, clique em Novo no menu ficheiro e, em seguida, clique em projecto.
  2. Expanda o Visual C++e, em seguida, clique em Win32.
  3. Clique em Aplicação de consola do Win32, tipo Limpeza no texto do nome e, em seguida, clique OK.
  4. Clique em Concluir na caixa de diálogo Assistente de aplicação de Win32 .
  5. No Solution Explorer, expanda os Ficheiros de origem, Cleanup.cppcom o botão direito e, em seguida, clique em Ver código.
  6. Localize o seguinte código:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Substitua o código localizado no passo 6 com o seguinte código.
    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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 Depurar e, em seguida, clique em Iniciar a depuração.

A criação de 2012 do servidor de Windows e Visual Studio 2012

Para criar aplicações para Windows Server 2012 e Microsoft Visual Studio 2012, siga estes passos.

NotaRecomendamos que utilize aDevNodeCleanutilitário para esta tarefa. Os seguintes passos e o exemplo de código no passo 7 são fornecidas apenas para fins informativos.
  1. No Microsoft Visual de 2012 Studio, clique em Novo no menu ficheiro e, em seguida, clique em projecto.
  2. Na caixa de diálogo Novo projecto , escreva Limpeza o nome de campo e, em seguida, faça duplo clique em Projecto Win32.
  3. No Assistente de aplicação de Win32, clique em seguinte.
  4. Em tipo de aplicação, clique para seleccionar <b00> </b00>aplicação de consolae, em seguida, clique em Concluir.
  5. No Solution Explorer, expanda os Ficheiros de origem, Cleanup.cppcom o botão direito e, em seguida, clique em Ver código.
  6. Localize o seguinte código:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Substitua o código localizado no passo 6 com o seguinte código.
    //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, com o botão direito Limpezae, em seguida, clique em Propriedades.
  9. Expanda Propriedades de configuração, expanda Linkere, em seguida, clique em Introdução.
  10. Selecionar Dependências adicionais, clique na seta para baixo e, em seguida, seleccione Editar.
  11. Na caixa de diálogo de Dependências adicionais , de tipo setupapi.lib e cfgmgr32.lib.
  12. Clique duas vezes em OK .
  13. Crie o projecto.

Propriedades

Artigo: 934234 - Última revisão: 13 de julho de 2014 - Revisão: 4.0
A informação contida neste artigo aplica-se a:
  • Microsoft Windows Server 2003 Standard Edition
  • Microsoft Windows Server 2003 Enterprise Edition
  • Microsoft Windows Server 2003 Datacenter Edition
  • 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 Edition (64-Bit x86)
  • Microsoft Windows Server 2003 R2 Enterprise Edition (64-Bit x86)
  • Microsoft Windows Server 2003 R2 Standard Edition (64-Bit x86)
  • 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 por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
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