Перейти до основного
Підтримка
Вхід
Вхід за допомогою облікового запису Microsoft
Увійдіть або створіть обліковий запис.
Вітаємо,
Виберіть інший обліковий запис.
У вас є кілька облікових записів
Виберіть обліковий запис, за допомогою якого потрібно ввійти.

ВСТУП

Під час запам'ятовуючий пристрій підключено до системи Windows, навіть, якщо лише короткий, windows створює відомості реєстру для пристрою. Через деякий час реєстру, він може містити багато записів для пристроїв, які не можна використовувати знову. У цій статті описано, як видалити ці відомості з системного реєстру.

Це відповідальність за програмне забезпечення, яке встановлюється підключення між пристроєм збереження даних а також Windows належним чином очистити дані для пристрою. Через те, що Windows не знає, коли пристрій збереження даних буде видалено, тимчасово або постійно, цей процес не потрібні. Проте відомо програмного забезпечення, яке встановлюється підключення, як правило, це. Наприклад, якщо резервного копіювання монтажу номери для логічного пристрою (LUN) архівування а потім від'єднання, до LUN, було б відповідальність резервного копіювання, щоб очистити LUN інформацію з Windows, тому, що цей пристрій збереження даних більше не будуть використовувати знову Windows.

Додаткові відомості

Тоді, коли новий пристрій підключено до комп'ютера, Windows-записи відомості про пристрій у системному реєстрі. Більшість пристроїв ця процедура не являють собою проблеми. Проте після того, як пристрій збереження даних, представлено LUN, через канал волокон або iSCSI, пристрій не можна зіткнутися знову на комп'ютері. Наприклад, пристрій може визначити серійний номер, або SCSI-сторінок, 0x80 і 0x83.

У цьому випадку реєстру, він може містити записи для пристроїв, які ніколи не може з'явитися знову. Не лише зробити ці записи, які займають простір, у реєстрі, ці записи, зрештою, може спричинити проблеми в роботі. Наприклад, через те, що індексів для функцій Plug and Play, використовуйте чотиризначний, десяткове значення, проблема може виникнути підключений пристрій 10,001.

Щоб усунути це обмеження, у функцій Plug and Play, можна видалити відомості про пристрій з реєстру, коли пристрій на жорсткий диск, який відсутній. Це можна зробити за допомогою програми Microsoft DevNodeClean .

Як створити для Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 і Visual Studio 2005

Очищення реєстру на диск GUID_DEVCLASS_DISKDRIVE клас GUID, і для з GUID_DEVCLASS_VOLUME диска, клас GUID, виконайте такі дії.

Примітка. Корпорація Майкрософт рекомендує, що ви використовуєте DevNodeClean . exe, для цього завдання. Наведені нижче дії, так і на кроці 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, введіть очищення у текстовому полі ім'я та натисніть кнопку OK.

  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. Налагодження меню і виберіть Запустити налагодження.

Як створити для Windows Server 2012 і Visual Studio 2012

Щоб створити для Windows Server 2012 і Microsoft Visual Studio 2012, виконайте такі дії.

Примітка. Корпорація Майкрософт рекомендує, що ви використовуєте DevNodeClean . exe, для цього завдання. Наведені нижче дії, так і на кроці 7, зразок коду надається лише для ознайомлення.

  1. У Microsoft Visual Studio 2012 клацніть створити " файл " і виберіть проект.

  2. У діалоговому вікні Нового проекту введіть очищення , у полі " ім'я " і двічі клацніть Win32 проекту.

  3. У майстрі Win32 застосунок натисніть кнопку " Далі".

  4. У полі тип програмивиберіть Консолі застосункута клацніть Готово.

  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. Створення проекту.

Потрібна додаткова довідка?

Потрібні додаткові параметри?

Ознайомтеся з перевагами передплати, перегляньте навчальні курси, дізнайтесь, як захистити свій пристрій тощо.

Спільноти допомагають ставити запитання й відповідати на них, надавати відгуки та дізнаватися думки висококваліфікованих експертів.

Чи ця інформація була корисною?

Наскільки ви задоволені якістю мови?
Що вплинуло на ваші враження?
Натиснувши кнопку "Надіслати", ви надасте свій відгук для покращення продуктів і служб Microsoft. Ваш ІТ-адміністратор зможе збирати ці дані. Декларація про конфіденційність.

Дякуємо за відгук!

×