Bỏ qua để tới nội dung chính
Đăng nhập với Microsoft
Đăng nhập hoặc tạo một tài khoản.
Xin chào,
Chọn một tài khoản khác.
Bạn có nhiều tài khoản
Chọn tài khoản bạn muốn đăng nhập.

GIỚI THIỆU

Khi thiết bị lưu trữ được kết nối với Windows, ngay cả khi chỉ một thời gian ngắn, windows tạo ra thông tin đăng ký cho thiết bị. Theo thời gian, sổ đăng ký có thể chứa nhiều mục sẽ không bao giờ được sử dụng lại các thiết bị. Bài viết này mô tả cách loại bỏ thông tin này từ sổ đăng ký hệ thống.

Đó là trách nhiệm của phần mềm thiết lập kết nối giữa các thiết bị lưu trữ và cửa sổ để làm sạch đúng thông tin cho thiết bị. Quá trình này là cần thiết vì Windows không biết khi loại bỏ thiết bị lưu trữ tạm thời hoặc vĩnh viễn. Tuy nhiên, phần mềm thiết lập kết nối thường biết điều này. Ví dụ: nếu phần mềm sao lưu kết hợp lý đơn vị số (LUNs) cho mục đích sao lưu và sau đó unmounting các LUNs, nó sẽ là trách nhiệm của phần mềm sao lưu để xoá thông tin Luân Windows, do cùng một thiết bị lưu trữ sẽ không được sử dụng lại Windows.

Thông tin

Khi một thiết bị được kết nối với máy tính, Windows ghi lại thông tin về thiết bị trong sổ đăng ký hệ thống. Đối với thiết bị, quy trình này không gây ra sự cố. Tuy nhiên, sau khi thiết bị lưu trữ được trình bày bởi Luân thông qua một kênh cáp hoặc iSCSI, thiết bị có thể không bao giờ được gặp lại máy tính. Ví dụ: một thiết bị có thể được xác định bởi một số hoặc SCSI trang 0x80 0x83.

Trong trường hợp này, đăng ký có thể chứa các mục nhập cho thiết bị có thể không xuất hiện lại. Không chỉ thực hiện các mục chiếm không gian trong sổ đăng ký, các mục nhập cuối cùng có thể gây ra sự cố hoạt động. Ví dụ: vì chỉ mục cho cắm và chạy chức năng sử dụng giá trị thập phân 4 chữ số, sự cố có thể xảy ra khi kết nối thiết bị 10,001.

Để khắc phục hạn chế này trong chức năng cắm và chạy, bạn có thể muốn loại bỏ thiết bị thông tin từ sổ đăng ký khi ổ đĩa cứng mà không có thiết bị. Bạn có thể thực hiện việc này bằng cách sử dụng tiện ích Microsoft DevNodeClean .

Làm thế nào để xây dựng cho Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 và Visual Studio 2005

Để xoá đăng ký cho GUID_DEVCLASS_DISKDRIVE đĩa lớp GUID dành cho GUID_DEVCLASS_VOLUME đĩa lớp GUID, làm theo các bước sau.

Lưu ý Chúng tôi khuyên bạn sử dụng tiện ích DevNodeClean cho tác vụ này. Các bước sau và mẫu mã bước 7 được cung cấp chỉ cho mục đích thông tin.

  1. Gọi hàm SetupDiGetClassDevs để lấy thông tin cho lớp liên quan đến GUID.

  2. Gọi hàm SetupDiEnumDeviceInfo để biết thông tin Phiên bản cho từng thiết bị trong giai đoạn hiện tại.

  3. Gọi hàm CM_Get_DevNode_Status để xem xem thông tin thiết bị hiện đại diện cho thiết bị không. Xác định xem vị chức năng bằng CR_NO_SUCH_DEVINST hoặc CR_NO_SUCH_VALUE.

  4. Tuỳ chọn cho một thiết bị không gọi hàm CM_Get_Device_ID để lấy ID instance của thiết bị và hiển thị ID trước khi bạn loại bỏ các thông tin.

  5. Thiết bị không sử dụng lớp thông tin mà bạn đã nhận được trong bước 1 và thông tin Phiên bản mà bạn đã nhận được trong bước 2. Gọi hàm SetupDiCallClassInstaller (DIF_REMOVE...) để loại bỏ các thông tin từ sổ đăng ký.

  6. Khi tất cả các thiết bị trong giai đoạn hiện nay đã được xử lý, gọi hàm SetupDiDestroyDeviceInfoList để làm sạch.

Lưu ý Trong một số trường hợp, bạn có thể phải xoá sổ đăng ký không chỉ cho GUID_DEVCLASS_DISKDRIVE và GUID_DEVCLASS_VOLUME đĩa lớp GUID, mà còn cho GUID_DEVCLASS_SCSIADAPTER và GUID_DEVCLASS_VOLUMESNAPSHOT đĩa lớp GUID. Để thực hiện việc này, bạn phải thay đổi định nghĩa DiskClassesToClean trong mã mẫu sau.

Ứng dụng bàn điều khiển Win32 sau đây là ví dụ về ứng dụng làm sạch registry. Để sử dụng ứng dụng này, hãy làm theo các bước sau.

Microsoft cung cấp mô hình lập trình để minh hoạ, không bảo hành hoặc rõ ràng hay ngụ ý. Điều này bao gồm, nhưng không giới hạn ở các bảo đảm cho một mục đích cụ thể hoặc sự. Bài viết này giả định rằng bạn đã quen với ngôn ngữ lập trình đang được giải thích và các công cụ được sử dụng để tạo và quy trình gỡ lỗi. Các kỹ sư hỗ trợ Microsoft có thể giúp giải thích các chức năng của một quy trình cụ thể. Tuy nhiên, họ sẽ không sửa đổi các ví dụ để cung cấp thêm chức năng hoặc xây dựng quy trình nhằm đáp ứng các yêu cầu cụ thể của bạn.

  1. Microsoft Visual Studio 2005, mới vào menu tệp , và sau đó bấm dự án.

  2. Mở rộng Visual C++, và sau đó bấm Win32.

  3. Nhấp vào Ứng dụng bàn điều khiển Win32, nhập dọn vào hộp văn bản tên và sau đó bấm OK.

  4. Bấm kết thúc trong hộp thoại Win32 ứng dụng thuật sĩ .

  5. Trong giải pháp Explorer, mở rộng Tệp nguồn, bấm chuột phải vào Cleanup.cpp, và sau đó nhấp vào Xem mã.

  6. Tìm mã sau:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. Thay thế mã mà bạn tìm thấy trong bước 6 với mã sau.

    /**************************************************************************************************/     
    /*                                                                                                */     
    /* 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. Bấm menu gỡ lỗi , và sau đó bấm Bắt đầu gỡ lỗi.

Làm thế nào để xây dựng cho Windows Server 2012 và Visual Studio 2012

Xây dựng cho Windows Server 2012 và Microsoft Visual Studio 2012, hãy làm theo các bước sau.

Lưu ý Chúng tôi khuyên bạn sử dụng tiện ích DevNodeClean cho tác vụ này. Các bước sau và mẫu mã bước 7 được cung cấp chỉ cho mục đích thông tin.

  1. Microsoft Visual Studio 2012, mới vào menu tệp , và sau đó bấm dự án.

  2. Trong hộp thoại Dự án mới , nhập dọn vào trường tên và sau đó bấm đúp Win32 dự án.

  3. Trong thuật sỹ ứng dụng Win32, bấm tiếp theo.

  4. Theo loại ứng dụng, bấm để chọn Bàn điều khiển ứng dụngvà sau đó bấm kết thúc.

  5. Trong giải pháp Explorer, mở rộng Tệp nguồn, bấm chuột phải vào Cleanup.cpp, và sau đó nhấp vào Xem mã.

  6. Tìm mã sau:

    int _tmain(int argc, _TCHAR* argv[])
    {
    return 0;
    }
    
  7. Thay thế mã mà bạn tìm thấy trong bước 6 với mã sau.

    //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. Trong giải pháp Explorer, bấm chuột phải vào dọn, và sau đó bấm thuộc tính.

  9. Bung rộng Cấu hình thuộc tính, mở rộng Linker, và sau đó bấm vào.

  10. Chọn Thêm phụ thuộc, bấm vào mũi tên xuống và chọn chỉnh sửa.

  11. Trong Các tệp phụ thuộc thoại hộp, loại setupapi.lib và cfgmgr32.lib.

  12. Bấm OK hai lần.

  13. Xây dựng dự án.

Bạn cần thêm trợ giúp?

Bạn muốn xem các tùy chọn khác?

Khám phá các lợi ích của gói đăng ký, xem qua các khóa đào tạo, tìm hiểu cách bảo mật thiết bị của bạn và hơn thế nữa.

Cộng đồng giúp bạn đặt và trả lời các câu hỏi, cung cấp phản hồi và lắng nghe ý kiến từ các chuyên gia có kiến thức phong phú.

Thông tin này có hữu ích không?

Bạn hài lòng đến đâu với chất lượng dịch thuật?
Điều gì ảnh hưởng đến trải nghiệm của bạn?
Khi nhấn gửi, phản hồi của bạn sẽ được sử dụng để cải thiện các sản phẩm và dịch vụ của Microsoft. Người quản trị CNTT của bạn sẽ có thể thu thập dữ liệu này. Điều khoản về quyền riêng tư.

Cảm ơn phản hồi của bạn!

×