Iniciar sessão com a Microsoft
Iniciar sessão ou criar uma conta.
Olá,
Selecione uma conta diferente.
Tem várias contas
Selecione a conta com a qual pretende iniciar sessão.

INTRODUÇÃO

Quando um dispositivo de armazenamento está ligado ao Windows, mesmo que apenas por breves instantes, 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.

É da responsabilidade do software que estabelece a ligação entre o dispositivo de armazenamento e o Windows para limpar correctamente as informações para o dispositivo. Este processo é necessário porque o Windows não sabe quando um dispositivo de armazenamento é removido temporariamente ou permanentemente. Mas o software que estabelece a ligação, normalmente, a saber isto. Por exemplo, se o software de cópia de segurança é montar números de unidades lógicas (LUNs) para fins de cópia de segurança e, em seguida, desmontar LUNs, seria a responsabilidade do software de cópia de segurança para limpar as informações de LUN do Windows, porque o mesmo dispositivo de armazenamento já não serão ser novamente utilizado pelo Windows.

Mais informações

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 LUN através de um canal de Fibra ou iSCSI, o dispositivo pode nunca ser detectado novamente pelo computador. Por exemplo, um dispositivo pode ser identificado por um número de série ou 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á pretender 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 utilitário Microsoft DevNodeClean .

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 GUID de classe de disco, siga estes passos.

Nota Recomendamos que utilize o utilitário DevNodeClean para esta tarefa. O exemplo de código no passo 7 e os seguintes passos são fornecidos 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 em falta. 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 classe GUIDs, 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 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 ilustrativo, 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 que está a ser demonstrada 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. Faça clique sobre a Aplicação de consola do Win32, escreva Limpeza na caixa de texto nome e, em seguida, clique em 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.

Nota Recomendamos que utilize o utilitário DevNodeClean para esta tarefa. O exemplo de código no passo 7 e os seguintes passos são fornecidos apenas para fins informativos.

  1. No Microsoft Visual Studio 2012, clique em Novo no menu ficheiro e, em seguida, clique em projecto.

  2. Na caixa de diálogo Novo projecto , escreva a Limpeza no campo nome 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 a 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.

Precisa de mais ajuda?

Quer mais opções?

Explore os benefícios da subscrição, navegue em cursos de formação, saiba como proteger o seu dispositivo e muito mais.

As comunidades ajudam-no a colocar e a responder perguntas, a dar feedback e a ouvir especialistas com conhecimentos abrangentes.

Estas informações foram úteis?

Quão satisfeito está com a qualidade do idioma?
O que afetou a sua experiência?
Ao selecionar submeter, o seu feedback será utilizado para melhorar os produtos e serviços da Microsoft. O seu administrador de TI poderá recolher estes dados. Declaração de Privacidade.

Obrigado pelo seu feedback!

×