Applies ToWindows 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 Standard Windows Server 2012 Datacenter Windows Server 2012 Datacenter Windows Server 2016, all editions Windows Server 2016 Standard Windows Server 2016 Essentials Windows Server 2016 Windows Server 2016 Standard edition Nano Server installation option Windows Server 2016 Datacenter edition Nano Server installation option

ĮVADAS

Kai saugojimo įrenginys yra prijungtas prie "Windows", net jei tik trumpai, windows sukuria registro informacija apie įrenginį. Laikui bėgant, registras gali turėti daug įrašų įrenginių, kurie bus būti naudojami dar kartą. Šiame straipsnyje aprašoma, kaip pašalinti šią informaciją iš sistemos registre.

Atsako programinę įrangą, kuri nustato, kad ryšys tarp saugojimo įrenginį ir "Windows" tinkamai išvalyti įrenginio informacija. Šis procesas yra būtinas, nes "Windows" nežino, kai saugojimo įrenginys pašalinamas laikinai arba visam laikui. Tačiau programinę įrangą, kuri nustato ryšį paprastai žino, tai. Pvz., jei atsarginių kopijų kūrimo programinė įranga yra loginis vienetų skaičių (LUNs) tvirtinimo sukurti atsargines kopijas ir tada unmounting LUNs, būtų atsako atsarginių kopijų kūrimo programinė įranga išvalyti LUN informaciją iš "Windows", dėl to paties saugojimo įrenginys bus daugiau dar kartą naudoti "Windows".

Daugiau informacijos

Kai naujas įrenginys yra prijungtas prie kompiuterio, Windows pateikia informaciją apie įrenginį sistemos registre. Daugumai prietaisų, ši procedūra nekelia problemų. Tačiau kai saugojimo įrenginyje yra pateikiamos pluošto kanalą arba iSCSI LUN, įrenginys gali niekada susidurti vėl kompiuterį. Pvz., įrenginys gali būti identifikuojami serijos numeris arba SCSI puslapiuose 0x80 ir 0x83.Tokiu atveju registras gali būti įrašų, skirtų įrenginių, kurie gali niekada vėl atsirasti. Ne tik daryti šių įrašų užima vietos registre, šie įrašai ilgainiui gali sukelti veikimo problemų. Pvz., kadangi rodykles Plug and Play funkcija naudoja keturių skaitmenų raidę, problema gali kilti, kai prijungtas 10,001.Norėdami išspręsti šio apribojimo Plug and Play funkcija, galite pašalinti įrenginio informaciją iš registro, kai įrenginys yra standžiajame diske, kad nebėra. Galite padaryti naudodami "Microsoft" DevNodeCleanįrankis.

Kaip sukurti Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 ir Visual Studio 2005

Valyti registras, kuriame GUID_DEVCLASS_DISKDRIVE disko klasės GUID ir dėl to GUID_DEVCLASS_VOLUME disko klasės GUID, atlikite toliau nurodytus veiksmus. Pastaba. Rekomenduojame naudoti priemonę DevNodeClean šią užduotį. Šiuos veiksmus ir kodo pavyzdys atlikdami 7 veiksmą pateikiami tik informaciniais tikslais.

  1. Skambinti SetupDiGetClassDevs funkcija gauti informacijos rūšies, susieta su GUID.

  2. Skambinti SetupDiEnumDeviceInfo funkcija gauti egzempliorių informaciją kiekvienam įrenginiui į dabartinę klasę.

  3. Skambinti CM_Get_DevNode_Status funkcija matyti ar šiuo metu įrenginį informaciją sudaro nėra įtaisu. Nustatyti, ar funkcija Būsena lygi CR_NO_SUCH_DEVINST arba CR_NO_SUCH_VALUE.

  4. Jei norite, nėra prietaisas, skambinkite CM_Get_Device_ID funkcija įrenginio egzemplioriaus ID ir Rodyti ID prieš šalindami informaciją.

  5. Nėra įrenginio, naudokite klasės informacija, įsigijote 1 veiksme ir egzempliorių informacija, kurios įsigijote 2 veiksme. Skambinti SetupDiCallClassInstaller (DIF_REMOVE,...) funkcija kad pašalintumėte informaciją iš registro.

  6. Kai visi dabartinės klasės įrenginių buvo tvarkomi, skambinti SetupDiDestroyDeviceInfoList funkcija išvalyti.

Pastaba. Kai kuriais atvejais gali tekti valyti registras, ne tik dėl GUID_DEVCLASS_VOLUME ir kuriame GUID_DEVCLASS_DISKDRIVE disko klasės GUID, bet ir GUID_DEVCLASS_SCSIADAPTER ir GUID_DEVCLASS_VOLUMESNAPSHOT disko klasės GUID. Norėdami tai padaryti, turite pakeisti šį mėginio kodą DiskClassesToClean apibrėžimą.Win32 console pareiškimą yra programa, kuri išvalo registro pavyzdys. Norėdami naudoti šią taikomąją programą, atlikite toliau nurodytus veiksmus. "Microsoft" pateikia programavimo pavyzdžius tik, tačiau nesuteikia jokių aiškių arba numanomų garantijų. Tai apima, bet neapsiribojant, numanomas garantijas dėl perkamumo ir tinkamumo konkrečiam tikslui. Šis straipsnis parašytas galvojant, kad esate susipažinę su pateikta programavimo kalba ir įrankiais, kurie yra naudojami procedūroms kurti ir derinti. "Microsoft" palaikymo inžinieriai gali padėti paaiškindami konkrečios procedūros funkcines galimybes. Tačiau jie nekeis šių pavyzdžių, kad numatytų papildomą funkcinę galimybę arba sukurtų konkrečius jūsų reikalavimus atitinkančias procedūras.

  1. Microsoft Visual Studio 2005, meniu failas spustelėkite naujas , ir spustelėkite projekto.

  2. Išplėskite Visual C ++, ir tada spustelėkite Win32.

  3. Spustelėkite Win32 konsolės programa, pavadinimą teksto lauke įveskite valymo , ir tada spustelėkite gerai.

  4. Spustelėkite baigtiWin32 taikomoji programa vedlys dialogo lange.

  5. Solution Explorer, išplėskite Šaltinio failus, dešiniuoju pelės mygtuku spustelėkite cleanup.cppirir tada spustelėkite Rodyti kodą.

  6. Suraskite šį kodą:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. Pakeisti kodą, kurį radote atlikdami 6 veiksmą, kodas.

    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. Spustelėkite meniu derinti , ir spustelėkite Pradėti derinimą.

Kaip sukurti Windows Server 2012 "ir" Visual Studio 2012

Norėdami kurti Windows Server 2012 "ir" Microsoft Visual Studio 2012, atlikite toliau nurodytus veiksmus. Pastaba. Rekomenduojame naudoti priemonę DevNodeClean šią užduotį. Šiuos veiksmus ir kodo pavyzdys atlikdami 7 veiksmą pateikiami tik informaciniais tikslais.

  1. Microsoft Visual Studio 2012, spustelėkite naujas meniu failas , ir spustelėkite projekto.

  2. Dialogo lange Naujas projektas įveskite valymas lauko pavadinimas , ir tada dukart spustelėkite Win32 projekto.

  3. Win32 programa vedlyje spustelėkite Pirmyn.

  4. Pagal programos rūšį, spustelėkite, kad pažymėtumėte Console Application, ir spustelėkite baigti.

  5. Solution Explorer, išplėskite Šaltinio failus, dešiniuoju pelės mygtuku spustelėkite cleanup.cppirir tada spustelėkite Rodyti kodą.

  6. Suraskite šį kodą:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. Pakeisti kodą, kurį radote atlikdami 6 veiksmą, kodas.

    //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. Sprendimas "Internet Explorer", dešiniuoju pelės mygtuku spustelėkite valymo, ir tada spustelėkite Ypatybės.

  9. Išplėsti Konfigūracijos ypatybes, išplėsti saitai, ir spustelėkite įvesties.

  10. Pasirinkite Papildomų priklausomybių, spustelėkite rodyklę žemyn ir pasirinkite Redaguoti.

  11. Papildomų priklausomybių dialogo lange, tipo setupapi.lib ir cfgmgr32.lib.

  12. Du kartus spustelėkite gerai .

  13. Sukurti projektą.

Reikia daugiau pagalbos?

Norite daugiau parinkčių?

Sužinokite apie prenumeratos pranašumus, peržiūrėkite mokymo kursus, sužinokite, kaip apsaugoti savo įrenginį ir kt.

Bendruomenės padeda užduoti klausimus ir į juos atsakyti, pateikti atsiliepimų ir išgirsti iš ekspertų, turinčių daug žinių.