Преминаване към основното съдържание
Поддръжка
Влизане с Microsoft
Влезте или създайте акаунт.
Здравейте,
Изберете друг акаунт.
Имате няколко акаунта
Изберете акаунта, с който искате да влезете.

Въведение

Когато устройството е свързано към Windows, дори само Накратко, windows създава информация за системния регистър за устройството. С времето системния регистър може да съдържа много записи за устройства, които няма да бъдат използвани отново. Тази статия описва как да премахнете тази информация от системния регистър.

Това е отговорност на софтуера, който връзка между устройство и Windows правилно изчистване на информацията за устройството. Този процес е необходимо, защото Windows не знам, когато устройството се отстранява временно или за постоянно. Но софтуерът, който осъществява връзка обикновено знаят това. Например ако софтуер за архивиране монтиране логически номера на (устройства LUN) за целите на архивирането и след това unmounting LUNs, би било отговорност на софтуера за архивиране за изчистване на LUN информацията от Windows, защото същото устройство вече отново се използва от Windows.

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

Когато ново устройство е свързано към компютъра, Windows записва информация за устройството в системния регистър. За повечето устройства тази процедура не представлява проблем. Обаче след като устройство за съхранение е представена от LUN чрез влакна канал или iSCSI, устройството може да не се срещнат отново на компютъра. Например устройство може да бъдат идентифицирани чрез сериен номер или SCSI страници 0x80 от и 0x83.

В тази ситуация системния регистър може да съдържа записи за устройства, които не могат да се появят отново. Не само тези записи да заемат място в системния регистър, тези записи може да предизвика оперативни проблеми. Например защото индекси за Plug and Play функциите използват четирицифрен decimal стойности, може да възникне проблем 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 за тази задача. Следващите стъпки и пример за код в стъпка 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 конзолата е пример за приложение, което почиства системния регистър. За да използвате приложението, изпълнете следните стъпки.

Microsoft предоставя примери само за илюстративни цели без гаранция за определени цели. Това включва, но не е ограничено до, подразбиращи се гаранции за продаваемост или годност за определена цел. Тази статия се предполага, че сте запознати с демонстрирания език за програмиране и инструментите, които се използват за създаване и процедури за отстраняване на грешки. Инженерите на поддръжката на Microsoft могат да помогнат обяснение на функциите на конкретна процедура. Въпреки това те няма да модифицират тези примери с цел осигуряване на допълнителна функционалност или създаване на процедури за удовлетворение на конкретните ви изисквания.

  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. Щракнете върху менюто Debug и щракнете върху Старт грешки.

Как да се изгради за Windows Server 2012 и Visual Studio 2012

За да съставите за Windows Server 2012 и Microsoft Visual Studio 2012, изпълнете следните стъпки.

Забележка: Ние препоръчваме да използвате помощната програма DevNodeClean за тази задача. Следващите стъпки и пример за код в стъпка 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. В разтвора Explorer щракнете върху почистванеи след това щракнете върху свойства.

  9. Разгънете Свойствата на конфигурацията, разгънете Linkerи натиснете вход.

  10. Изберете Допълнителни зависимости, щракнете върху стрелката надолу и след това изберете Редактиране.

  11. В Допълнителни зависимости диалоговия прозорец, въведете setupapi.lib и cfgmgr32.lib.

  12. Щракнете върху OK два пъти.

  13. Изграждане на проекта.

Нуждаете ли се от още помощ?

Искате ли още опции?

Разгледайте ползите от абонамента, прегледайте курсовете за обучение, научете как да защитите устройството си и още.

Общностите ви помагат да задавате и отговаряте на въпроси, да давате обратна връзка и да получавате информация от експерти с богати знания.

Беше ли полезна тази информация?

Доколко сте доволни от качеството на езика?
Какво е повлияло на вашия потребителски опит?
Като натиснете „Подаване“, вашата обратна връзка ще се използва за подобряване на продуктите и услугите на Microsoft. Вашият ИТ администратор ще може да събира тези данни. Декларация за поверителност.

Благодарим ви за обратната връзка!

×