硬盘或硬盘驱动器的序列号

8
起初这似乎是一个非常简单的问题,有些人可能会试图建议我尝试谷歌,但实际上对我来说很难,我已经尝试了谷歌和Stack Overflow,但找不到任何好的解决方案。
只想使用C#获取硬盘或硬盘驱动器的序列号,请仔细阅读:硬盘的序列号,而不是硬盘的卷序列号(例如C,D,E等)。
为了获得硬盘卷的序列号,我在网络上找到了解决方案,并且它可以很好地工作,但问题是如何获取硬盘的序列号。
有些人可能会尝试将此问题复制到下面的Stake Overflow问题中,或者提供该问题的链接。但事实并非如此。
以下任何问题都没有为这个问题提供好的C#解决方案:
  1. C#中如何获取硬盘序列号(无WMI)?
  2. .net中如何检索HDD固件序列号?
  3. Hdd序列号

1
我不明白。你已经提供了答案链接。就在最底下的文章中,那个你很喜欢的截图。C++有什么“无聊”的地方? - Cody Gray
更重要的是,为什么有那么多人需要找到我的硬盘序列号?这个问题经常被问到(你已经找到至少3个重复的),考虑到根本没有有效的用例。卷序列号是您唯一可能关心的事情;它是唯一重要的事情。 - Cody Gray
因为我尝试在C#中实现它,但无法成功..... 我们的应用程序使用硬盘序列号,仅在客户端计算机上运行,如果在我们的应用程序可执行文件的数据库中找到客户端计算机的硬盘序列号.....简而言之,它会将数据库中的硬盘序列号与从客户端计算机获取的硬盘序列号进行匹配.........如果找到,则我们的应用程序将运行..... - Pritesh
1
@CodyGray 我相信这个问题有6k的浏览量,肯定有使用场景。我正在一个项目中工作,我们需要更换旧硬盘并获取硬盘序列号。我正在寻找一种远程获取此信息的方法。 - JSuar
6个回答

9
这是最终的解决方案:

无需使用WMI获取物理硬盘序列号

只需编写这些代码:

DriveListEx diskInfo = new DriveListEx();
diskInfo.Load();
string serialNo = diskInfo[0].SerialNumber;

不要忘记在DriveInfoEx.dll中添加引用。


1
为什么不直接将未托管的 C++ 代码从 DLL 转换为托管的 C# 呢?它并没有进行无法使用托管语言实现的操作。这样一来,您就可以消除对第三方 DLL 的依赖了。 - Cody Gray
@ Cody Gray,但对我来说更难......甚至我还没有尝试过......如果你能的话,请在这里发布,我会接受你的答案......谢谢...... - Pritesh
1
好的解决方案:但有时它不起作用...我在4台电脑上尝试过了,第一台电脑上没有运行,但在右键单击EXE并选择“以管理员身份运行”选项后可以运行...对于第二和第三台电脑,它都正常运行...对于第四台没有管理员权限的电脑,由于出现异常,它无法工作。 - Sangram Nandkhile
2
DriveInfoex.dll在Windows 7操作系统上无法工作。它会抛出以下错误:System.IO.FileLoadException: 无法加载文件或程序集“DriveInfoEx.dll”或其某个依赖项。该应用程序启动失败,因为应用程序配置不正确。重新安装该应用程序可能会解决此问题。(HRESULT异常代码:0x800736B1) - user1033301
@EvgeniyKrechun,是什么意思,请详细说明? - Pritesh

4

看这里

http://www.codeproject.com/KB/system/GetHardwareInformation.aspx

只需从那里下载演示并选择“数据存储”选项卡,然后从中选择Win32_DiskDrive,您将获得下面提到的所有磁盘驱动器(硬盘)的信息,并查看一个属性“SerialNumber”,该属性位于sectorpertrack之后和signature属性之前...

输入图像描述


1
您可以在下面的链接中查看屏幕截图,了解我运行应用程序时发生了什么。您将无法找到“SerialNumber”字段。链接:http://pritesharyan.weebly.com/question3.html - Pritesh
1
可能是系统的问题。我已经搜索了一下,很多解决方案都报告说在Windows XP和64位Windows系统上无法工作。您可能需要根据软件应该运行的系统找到多个解决方案。 - CasperT
不,我不认为这是WinXP的问题。因为我曾在WinXP中使用它进行应用程序注册,我需要硬盘序列号、主板和处理器...以制作产品密钥。当时它运行良好,我得到了所有东西...我认为这可能是硬盘/主板/IDE控制器的问题...但我不是回答硬件问题的合适人选...对此很抱歉。 - asharajay
@jAX,没关系亲爱的……我也是为了同样的目的在使用它……但我卡住了,谢谢你的回复…… - Pritesh

2
我发现最好的方法是:
  1. 这里下载.dll文件。

  2. 将.dll文件添加到您的项目中。

  3. 添加以下代码:

    [DllImportAttribute("HardwareIDExtractorC.dll")]
    public static extern String GetIDESerialNumber(byte DriveNumber);

  4. 从需要的位置调用硬盘ID:

    GetIDESerialNumber(0).Replace(" ", string.Empty);

注意:在资源管理器中转到dll文件的属性,并将Build Action设置为Embedded Resource


1
我找到了一个非常好的库,可以做你想要的事情:https://www.nuget.org/packages/Hardware.Info/10.0.1?_src=template
using Hardware.Info;

IHardwareInfo hardwareInfo = new HardwareInfo();

hardwareInfo.RefreshDriveList();

foreach (var drive in hardwareInfo.DriveList)
{
    Console.WriteLine(drive.SerialNumber);
}

超级的,而且它是MIT许可证下的。 - undefined

1
我使用ILSpy(http://ilspy.net/)查看了System.IO.DriveInfo类,并且找到了下面这段代码,似乎可以正常工作:
'------------------------------------------------------
' Declaration found in Microsoft.Win32.Win32Native
'------------------------------------------------------
Friend Declare Auto Function GetVolumeInformation Lib "kernel32.dll" (drive As String, <Out()> volumeName As StringBuilder, volumeNameBufLen As Integer, <Out()> ByRef volSerialNumber As Integer, <Out()> ByRef maxFileNameLen As Integer, <Out()> ByRef fileSystemFlags As Integer, <Out()> fileSystemName As StringBuilder, fileSystemNameBufLen As Integer) As Boolean

'------------------------------------------------------
' Test in my Form class
'------------------------------------------------------
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
    Try
        Dim volumeName As StringBuilder = New StringBuilder(50)
        Dim stringBuilder As StringBuilder = New StringBuilder(50)
        Dim volSerialNumber As Integer
        Dim maxFileNameLen As Integer
        Dim fileSystemFlags As Integer
        If Not GetVolumeInformation("C:\", volumeName, 50, volSerialNumber, maxFileNameLen, fileSystemFlags, stringBuilder, 50) Then
            Dim lastWin32Error As Integer = Marshal.GetLastWin32Error()
            MsgBox("Error number:" & lastWin32Error)
        Else
            MsgBox(volSerialNumber.ToString("X"))
        End If

    Catch ex As Exception
        MsgBox(ex.ToString())
    End Try
End Sub

1
// Function driveser (model)
// Returns the serial number of the drive specified in "model" or an empty string. 
// Please include this is you are going to use it.
// (C) By Zibri 2013
// Free for non commercial use.
// zibri AT zibri DOT org

public string driveser(string model)
{
    string functionReturnValue = null;
    string devid = "";
    functionReturnValue = "";
    try {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDrive WHERE Model LIKE '%" + model + "%'");
        foreach (ManagementObject queryObj in searcher.Get()) {
            if (!string.IsNullOrEmpty(queryObj("SerialNumber")))
                functionReturnValue = queryObj("SerialNumber");
            Debug.Print(queryObj("Model") + ":" + functionReturnValue);
        }
    } catch (ManagementException err) {
        Debug.Print("An error occurred while querying for WMI data: " + err.Message);
    }
    return functionReturnValue;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接