Удаление параметров реестра для устройств, которые не будут повторно использоваться на компьютере под управлением Windows Server 2003 или более поздней версии

Переводы статьи Переводы статьи
Код статьи: 934234
Развернуть все | Свернуть все

В этой статье

ВВЕДЕНИЕ

На компьютере под управлением Windows Server 2003 или более поздней версии Windows только на короткое время могут быть подключены устройства хранения, подключенного через оптоволоконного или по протоколу iSCSI. При подключении к устройству хранения данных Windows создает данные реестра для устройства. Со временем реестра может содержать много записей для устройств, которые не будут использоваться повторно. В данной статье описывается, как удалить эту информацию из системного реестра.

Дополнительная информация

При подключении нового устройства к компьютеру Windows записывает сведения об устройстве в системном реестре. Для большинства устройств эта процедура не должно составлять проблемы. Тем не менее после устройства хранения данных представлен номер логического устройства (LUN) через оптоволоконного или iSCSI, устройство может никогда не будут обнаружены снова на компьютере. Например устройство может быть идентифицирована по серийному номеру или по страницам SCSI 0x83 и 0x80.

В этом случае реестра может содержать записи для устройств, которые не могут появиться снова. Не только выполнять эти операции занимают места в реестре, они могут в конечном итоге вызывать проблем в работе. Например поскольку индексы для функций Plug and Play использовать дробные значения из четырех цифр, проблема может возникнуть при подключении устройства диапазон 10 001.

Чтобы устранить это ограничение функциональных возможностей Plug and Play, может потребоваться удалить из реестра сведения об устройстве, когда устройство установлено на жестком диске, который больше не существует. Это можно сделать с помощью Microsoft DevNodeClean Служебная программа.

Как построить для Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 и Visual Studio 2005

Чтобы очистить в реестре GUID класса GUID_DEVCLASS_DISKDRIVE диск и для GUID_DEVCLASS_VOLUME GUID класса на диске, выполните следующие действия.

ПримечаниеМы рекомендуем использовать DevNodeCleanСлужебная программа для этой задачи. Приведенные ниже инструкции и пример кода на шаге 7 предоставляются только в информационных целях.
  1. Вызов функции SetupDiGetClassDevs для получения сведений для класса, который связан с идентификатором GUID.
  2. Вызов функции SetupDiEnumDeviceInfo для получения сведений об экземпляре для каждого устройства в текущем классе.
  3. Вызов функции CM_Get_DevNode_Status для просмотра того, представляет ли сведения о текущем устройстве устройство отсутствует. Определите, является ли состояние функции равно CR_NO_SUCH_DEVINST или CR_NO_SUCH_VALUE.
  4. При необходимости устройства отсутствует, вызовите функцию CM_Get_Device_ID для получения идентификатора экземпляра устройства и вывести идентификатор, прежде чем удалить сведения о.
  5. Для устройства отсутствует используйте данные класса, полученным на шаге 1 и данные экземпляра, полученным на шаге 2. Вызов функции SetupDiCallClassInstaller (DIF_REMOVE,...) , чтобы удалить сведения из реестра.
  6. После обработки всех устройств в текущем классе, вызовите функцию SetupDiDestroyDeviceInfoList для очистки.
Примечание В некоторых случаях может потребоваться очистить реестр не только для GUID_DEVCLASS_DISKDRIVE и GUID_DEVCLASS_VOLUME на диске GUID классов но также для GUID_DEVCLASS_SCSIADAPTER и GUID_DEVCLASS_VOLUMESNAPSHOT на диске GUID классов. Чтобы сделать это, необходимо изменить определение DiskClassesToClean в следующем примере кода.

Следующее консольное приложение Win32 является примером приложения, которое выполняет очистку реестра. Чтобы использовать это приложение, выполните следующие действия.

Корпорация Майкрософт предлагает примеры программного кода только для ознакомления, без гарантий, явных или подразумеваемых. Это включает, но не ограничивается, подразумеваемыми гарантиями товарной пригодности или пригодности для определенной цели. В данной статье предполагается, что вы знакомы с языком программирования предложенном и средствами, которые используются для создания и отладки. Сотрудники службы поддержки Майкрософт могут объяснить возможности конкретной процедуры. Тем не менее будут изменять примеры для реализации дополнительных возможностей или создания процедур для определенных требований.
  1. В Microsoft Visual Studio 2005 нажмите кнопку Создать в меню файл и выберите команду проект.
  2. Разверните узел Visual C++и щелкните Win32.
  3. Выберите Консольное приложение Win32, тип Очистка в поле имя , а затем щелкните ОК.
  4. Нажмите кнопку Готово в диалоговом окне Мастер приложений Win32 .
  5. В обозревателе решений разверните узел Исходные файлы, щелкните правой кнопкой мыши Cleanup.cppи выберите команду Просмотреть код.
  6. Найдите следующий код:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Замените код, найденных на шаге 6 на следующий код.
    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. Выберите в меню Отладка выберите команду Начать отладку

Способы построения для Visual Studio 2012 и Windows Server 2012

Для построения Windows Server 2012 и Microsoft Visual Studio 2012, выполните следующие действия.

ПримечаниеМы рекомендуем использоватьDevNodeCleanСлужебная программа для этой задачи. Приведенные ниже инструкции и пример кода на шаге 7 предоставляются только в информационных целях.
  1. В Microsoft Visual Studio 2012 нажмите кнопку Создать в меню файл и выберите команду проект.
  2. Введите в диалоговом окне Новый проектОчистка в поле имя поля, а затем дважды щелкните Проект Win32.
  3. В мастере приложений Win32 нажмите кнопку Далее.
  4. В поле Тип приложения, щелкните, чтобы выбрать <b00> </b00>консольное приложение, а затем нажмите кнопку Готово.
  5. В обозревателе решений разверните узел Исходные файлы, щелкните правой кнопкой мыши Cleanup.cppи выберите команду Просмотреть код.
  6. Найдите следующий код:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    
  7. Замените код, найденных на шаге 6 на следующий код.
    //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. В обозревателе решений щелкните правой кнопкой мыши очисткии нажмите кнопку Свойства.
  9. Разверните узел Свойства конфигурации, разверните узел Компоновщики нажмите кнопку Ввод.
  10. Выберите Дополнительные зависимости, щелкните направленную вниз стрелку и выберите Изменить.
  11. В диалоговом окне Дополнительные зависимости , типа setupapi.lib и cfgmgr32.lib.
  12. Два раза нажмите кнопку ОК .
  13. Выполните построение проекта.

Свойства

Код статьи: 934234 - Последний отзыв: 12 апреля 2014 г. - Revision: 9.0
Ключевые слова: 
kboem kbcode kbinfo kbhowto kbmt KB934234 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Данная статья переведена с использованием программного обеспечения Майкрософт для машинного перевода и, возможно, отредактирована посредством технологии Community Translation Framework (CTF). Корпорация Майкрософт предлагает вам статьи, обработанные средствами машинного перевода, отредактированные членами сообщества Майкрософт и переведенные профессиональными переводчиками, чтобы вы могли ознакомиться со всеми статьями нашей базы знаний на нескольких языках. Статьи, переведенные с использованием средств машинного перевода и отредактированные сообществом, могут содержать смысловое, синтаксические и (или) грамматические ошибки. Корпорация Майкрософт не несет ответственности за любые неточности, ошибки или ущерб, вызванные неправильным переводом контента или его использованием нашими клиентами. Подробнее об CTF можно узнать по адресу http://support.microsoft.com/gp/machine-translation-corrections/ru.
Эта статья на английском языке: 934234

Отправить отзыв

 

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