如何删除的设备,将永远不会再次使用运行 Windows Server 2003 或更高版本的计算机上的注册表信息

针对 Windows Server 2003 的支持已于 2015 年 7 月 14 日终止。

Microsoft 已于 2015 年 7 月 14 日终止了对于 Windows Server 2003 的支持。该更改已影响到您的软件更新和安全选项。 了解这一措施对于您的含义以及如何继续保持受保护状态。

重要说明:本文是由 Microsoft 机器翻译软件进行的翻译并可能由 Microsoft 社区通过社区翻译机构(CTF)技术进行后期编辑,或可能是由人工进行的翻译。Microsoft 同时向您提供机器翻译、人工翻译及社区后期编辑的文章,以便对我们知识库中的所有文章以多种语言提供访问。翻译的文章可能存在词汇、句法和/或语法方面的错误。Microsoft 对由于内容的误译或客户对内容的使用所导致的任何不准确、错误或损失不承担责任。

点击这里察看该文章的英文版: 934234
简介
在计算机上正在运行 Windows Server 2003 或更高版本的 Windows,可能在短时间内连接通过光纤通道或 iSCSI 协议连接的存储设备。连接存储设备后,Windows 将创建该设备的注册表信息。随着时间的推移注册表可能包含许多项永远不会再次用到的设备。本文介绍了如何从系统注册表中删除此信息。
更多信息
当新的设备连接到计算机时,Windows 系统注册表中的设备记录信息。对于大多数设备,此过程不会带来问题。但是,提出的逻辑单元号 (LUN) 通过光纤通道或 iSCSI 存储设备后,设备可能永远不会遇到再次的计算机。例如,通过序列号或 SCSI 页 0x80 和 0x83,则可能会识别设备。

在这种情况下,注册表可能包含项的设备,可能永远不会再次出现。不仅做这些条目占用空间,在注册表中的,这些条目可能最终会导致操作问题。例如,由于插功能的索引使用四位数字的十进制值,10,001 设备连接时,可能会出现问题。

若要解决此限制,插功能,可能需要硬盘驱动器上已不存在的设备时从注册表中删除设备的信息。您可以使用执行此操作 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函数来获取设备实例 ID 和显示 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 控制台应用程序中,类型 清理名称文本框中,然后再单击确定
  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__cdeclmain(     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用于此任务的实用程序。仅用于提供信息之目的提供了以下步骤和步骤 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__cdeclmain(     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.libcfgmgr32.lib
  12. 单击确定两次。
  13. 生成项目。

iSCSI LUN win2003

警告:本文已自动翻译

属性

文章 ID:934234 - 上次审阅时间:07/14/2014 05:07:00 - 修订版本: 4.0

Microsoft Windows Server 2003 Standard Edition, Microsoft Windows Server 2003 Enterprise Edition, Microsoft Windows Server 2003 Datacenter Edition, Microsoft Windows Server 2003, Enterprise x64 Edition, Microsoft Windows Server 2003, Datacenter x64 Edition, Microsoft Windows Server 2003, Standard x64 Edition, Microsoft Windows Server 2003, Enterprise Edition for Itanium-based Systems, Microsoft Windows Server 2003, Datacenter Edition for Itanium-Based Systems, Microsoft Windows Server 2003 R2 Standard Edition (32-bit x86), Microsoft Windows Server 2003 R2 Enterprise Edition (32-Bit x86), Microsoft Windows Server 2003 R2 Datacenter Edition (32-Bit x86), Microsoft Windows Server 2003 R2 Datacenter Edition (64-Bit x86), Microsoft Windows Server 2003 R2 Enterprise Edition (64-Bit x86), Microsoft Windows Server 2003 R2 Standard Edition (64-Bit x86), Microsoft Windows Storage Server 2003 R2 x64 Enterprise, Microsoft Windows Storage Server 2003 R2 x64 Standard, Windows 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 Datacenter

  • kboem kbcode kbinfo kbhowto kbmt KB934234 KbMtzh
反馈