Cómo quitar la información del registro para los dispositivos que no se nunca volverá a utilizar en un equipo que ejecuta Windows Server 2003 o una versión posterior

Seleccione idioma Seleccione idioma
Id. de artículo: 934234 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

INTRODUCCIÓN

En un equipo que ejecuta Windows Server 2003 o una versión posterior de Windows, puede conectar un dispositivo de almacenamiento que se conecta a través de un canal de fibra o el protocolo iSCSI por un breve período. Cuando se conecta un dispositivo de almacenamiento, Windows crea la información del registro para el dispositivo. Con el tiempo, el registro puede contener muchas entradas para dispositivos que no se utilizarán otra vez. Este artículo describe cómo quitar esta información del registro del sistema.

Más información

Cuando un nuevo dispositivo está conectado a un equipo, registra información acerca del dispositivo en el registro del sistema de Windows. Para la mayoría de los dispositivos, este procedimiento no supone un problema. Sin embargo, después de que un dispositivo de almacenamiento sea presentado por un número de unidad lógica (LUN) a través de un canal de fibra o iSCSI, el dispositivo no se puede producir otra vez el equipo. Por ejemplo, un dispositivo puede identificarse por un número de serie o por páginas de SCSI 0 x 80 y 0 x 83.

En esta situación, el registro puede contener entradas para dispositivos que no aparecerá de nuevo. No sólo hacer estas entradas ocupan espacio en el registro, estas entradas pueden provocar problemas de funcionamiento. Por ejemplo, dado que los índices de funcionalidad Plug and Play utilizan valores de cuatro dígitos decimales, puede ocurrir un problema cuando se conecta el dispositivo 10.001.

Para resolver esta limitación en la funcionalidad Plug and Play, es aconsejable quitar la información del dispositivo del registro cuando el dispositivo es una unidad de disco duro que ya no está presente. Puede hacerlo mediante la Microsoft DevNodeClean utilidad.

Cómo construir para Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 y Visual Studio 2005 de

Para limpiar el registro de la clase de disco GUID_DEVCLASS_DISKDRIVE GUID y para el GUID_DEVCLASS_VOLUME GUID de clase de disco, siga estos pasos.

NotaLe recomendamos que utilice la DevNodeCleanutilidad para esta tarea. El ejemplo de código en el paso 7 y los pasos siguientes se proporcionan únicamente con fines informativos.
  1. Llame a la función SetupDiGetClassDevs para obtener información sobre la clase a la que está asociada con el GUID.
  2. Llame a la función SetupDiEnumDeviceInfo para obtener información de instancia para cada dispositivo en la clase actual.
  3. Llame a la función CM_Get_DevNode_Status para ver si la información del dispositivo actual representa un dispositivo ausente. Determinar si el estado de la función es igual a CR_NO_SUCH_DEVINST o a CR_NO_SUCH_VALUE.
  4. Opcionalmente, para un dispositivo ausente, llame a la función CM_Get_Device_ID para obtener el identificador de instancia de dispositivo y para mostrar el ID antes de quitar la información.
  5. Para el dispositivo ausente, use la información de clase que obtuvo en el paso 1 y la información de instancia que obtuvo en el paso 2. Llame a la función SetupDiCallClassInstaller (DIF_REMOVE,...) para quitar la información del registro.
  6. Cuando se han tratado todos los dispositivos de la clase actual, llame a la función SetupDiDestroyDeviceInfoList para limpiar.
Nota En algunos casos, tendrá que limpiar el registro, no sólo para el GUID_DEVCLASS_DISKDRIVE y el GUID_DEVCLASS_VOLUME de disco los GUIDs de clase sino también para los GUIDs de clase de disco de los GUID_DEVCLASS_SCSIADAPTER y GUID_DEVCLASS_VOLUMESNAPSHOT. Para ello, debe cambiar la definición de DiskClassesToClean en el siguiente código de ejemplo.

La siguiente aplicación de consola Win32 es un ejemplo de una aplicación que limpia el registro. Para usar esta aplicación, siga estos pasos.

Microsoft proporciona ejemplos de programación unicamente con fines ilustrativos, sin ninguna garantía tanto expresa como implícita. Esto incluye las garantías implícitas de comerciabilidad o idoneidad para un fin determinado, pero sin limitarse a ellas. Este artículo se supone que está familiarizado con el lenguaje de programación que se muestra y con las herramientas que se utilizan para crear y depurar procedimientos. Los ingenieros de soporte técnico de Microsoft pueden explicarle la funcionalidad de un determinado procedimiento. Sin embargo, no modificarán estos ejemplos para ofrecer mayor funcionalidad ni crearán procedimientos que cumplan sus requisitos específicos.
  1. En Microsoft Visual Studio 2005 de, haga clic en nuevo en el menú archivo y, a continuación, haga clic en proyecto.
  2. Expanda Visual C++y, a continuación, haga clic en Win32.
  3. Haga clic en Aplicación de consola Win32, tipo Limpieza en el texto del nombre y a continuación, haga clic en Aceptar.
  4. Haga clic en Finalizar en el cuadro de diálogo Asistente para aplicaciones Win32 .
  5. En el Explorador de soluciones, expanda Archivos de código fuente, haga clic en Cleanup.cppy, a continuación, haga clic en Ver código.
  6. Busque el código siguiente:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Reemplace el código que encontró en el paso 6 con el código siguiente.
    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. Haga clic en el menú Depurar y, a continuación, haga clic en Iniciar depuración.

Cómo construir para Windows Server 2012 y 2012 de Visual Studio

Para generar para Windows Server 2012 y Microsoft Visual Studio 2012, siga estos pasos.

NotaLe recomendamos que utilice laDevNodeCleanutilidad para esta tarea. El ejemplo de código en el paso 7 y los pasos siguientes se proporcionan únicamente con fines informativos.
  1. En Microsoft Visual Studio 2012 haga clic en nuevo en el menú archivo y, a continuación, haga clic en proyecto.
  2. En el cuadro de diálogo Nuevo proyecto , escriba Limpieza en el nombre del campo y, a continuación, haga doble clic en Proyecto Win32.
  3. En el Asistente para aplicaciones Win32, haga clic en siguiente.
  4. En tipo de aplicación, haga clic para seleccionar <b00> </b00>aplicación de consolay, a continuación, haga clic en Finalizar.
  5. En el Explorador de soluciones, expanda Archivos de código fuente, haga clic en Cleanup.cppy, a continuación, haga clic en Ver código.
  6. Busque el código siguiente:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Reemplace el código que encontró en el paso 6 con el código siguiente.
    //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. En el Explorador de soluciones, haga clic en Liberador de espacioy, a continuación, haga clic en Propiedades.
  9. Expanda Las propiedades de configuración, expanda vinculadory, a continuación, haga clic en entrada.
  10. Seleccione Dependencias adicionales, haga clic en la flecha abajo y, a continuación, seleccione Editar.
  11. En el cuadro de diálogo Dependencias adicionales , de tipo setupapi.lib y cfgmgr32.lib.
  12. Haga clic en Aceptar dos veces.
  13. Genere el proyecto.

Propiedades

Id. de artículo: 934234 - Última revisión: jueves, 10 de julio de 2014 - Versión: 4.0
La información de este artículo se refiere 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
Palabras clave: 
kboem kbcode kbinfo kbhowto kbmt KB934234 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 934234

Enviar comentarios

 

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