在 .NET 中,如何在不使用 WMI 的情况下找到硬盘设备序列号?

发布于 2024-07-29 16:18:16 字数 91 浏览 8 评论 0 原文

我想从硬盘获取硬连线序列号,但不使用 WMI。 我尝试使用 WMI 代码,但它在我的机器上肯定不起作用。 那么.NET 中有没有其他方法可以查找物理硬盘的序列号呢?

I want to get the hardwired serial number from the hard disk but NOT using WMI. I tried using WMI code, and it doesn't work on my machine for sure. So is there any alternative in .NET for finding the Serial Number of a physical hard disk?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

素罗衫 2024-08-05 16:18:16

这应该有助于开始:

如何在没有 WMI 的

情况 下获取物理 HDD 序列号 WMI 不返回数据的问题; 您确定如何获得从 WMI 获取数据的正确权限吗? 您可以使用 WMI 工具< /a> 检查/修复此问题。

This should help get started:

How to get Physical HDD serial number without WMI

Regarding your problem with WMI not returning data; Are you sure how to the right privileges to get data from WMI? You can use WMI Tools to check/fix this.

绝影如岚 2024-08-05 16:18:16

使用 createfile 作为如下所示。 它可能需要管理权限。在代码中添加 4 个文本框和一个按钮。

 private const int CREATE_NEW = 1;
    private const int OPEN_EXISTING = 3;
    private const uint GENERIC_READ = 0x80000000; 
    private const uint GENERIC_WRITE = 0x40000000;
    // 10000000000000000000000000000000 --- GENERIC_READ
    // 01000000000000000000000000000000 --- GENERIC_WRITE
    // 00100000000000000000000000000000 --- GENERIC_EXECUTE
    // 00010000000000000000000000000000 --- GENERIC_ALL       

    //Securable objects use an access mask format in which the 
    //four high-order bits specify generic access rights


    private const int FILE_SHARE_READ = 0x1;      
    private const int FILE_SHARE_WRITE = 0x2;
    // 00000000000000000000000000000001 --- FILE_SHARE_READ
    // 00000000000000000000000000000010 --- FILE_SHARE_WRITE
    // 00000000000000000000000000000100 --- FILE_SHARE_DELETE 

    private const int VER_PLATFORM_WIN32_NT = 2;
    private const int DFP_RECEIVE_DRIVE_DATA = 0x7C088;
    //     0         000000000000111         11                  0               00000100010         00
    //     Common    Device Type             Required Access     Custom          Function Code       Transfer Type

    private const int INVALID_HANDLE_VALUE = -1;

    public enum DriveTypes { Fixed, Removable, Unknown };
    public string[] DriveStrings = { "Fixed", "Removable", "Unknown" };

    [StructLayout(LayoutKind.Sequential, Size = 8)]
    private class IDEREGS
    {
        public byte Features;
        public byte SectorCount;
        public byte SectorNumber;
        public byte CylinderLow;
        public byte CylinderHigh;
        public byte DriveHead;
        public byte Command;
        public byte Reserved;
    }

    [StructLayout(LayoutKind.Sequential, Size = 32)]
    private class SENDCMDINPARAMS
    {
        public int BufferSize;
        public IDEREGS DriveRegs;
        public byte DriveNumber;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public byte[] Reserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] Reserved2;
        public SENDCMDINPARAMS()
        {
            DriveRegs = new IDEREGS();
            Reserved = new byte[3];
            Reserved2 = new int[4];
        }
    }
    [StructLayout(LayoutKind.Sequential, Size = 12)]
    private class DRIVERSTATUS
    {
        public byte DriveError;
        public byte IDEStatus;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Reserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public int[] Reserved2;
        public DRIVERSTATUS()
        {
            Reserved = new byte[2];
            Reserved2 = new int[2];
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class IDSECTOR
    {
        public short GenConfig;
        public short NumberCylinders;
        public short Reserved;
        public short NumberHeads;
        public short BytesPerTrack;
        public short BytesPerSector;
        public short SectorsPerTrack;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public short[] VendorUnique;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
        public char[] SerialNumber;
        public short BufferClass;
        public short BufferSize;
        public short ECCSize;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public char[] FirmwareRevision;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
        public char[] ModelNumber;
        public short MoreVendorUnique;
        public short DoubleWordIO;
        public short Capabilities;
        public short Reserved1;
        public short PIOTiming;
        public short DMATiming;
        public short BS;
        public short NumberCurrentCyls;
        public short NumberCurrentHeads;
        public short NumberCurrentSectorsPerTrack;
        public int CurrentSectorCapacity;
        public short MultipleSectorCapacity;
        public short MultipleSectorStuff;
        public int TotalAddressableSectors;
        public short SingleWordDMA;
        public short MultiWordDMA;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 382)]
        public byte[] Reserved2;
        public IDSECTOR()
        {
            VendorUnique = new short[3];
            Reserved2 = new byte[382];
            FirmwareRevision = new char[8];
            SerialNumber = new char[20];
            ModelNumber = new char[40];
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class SENDCMDOUTPARAMS
    {
        public int BufferSize;
        public DRIVERSTATUS Status;
        public IDSECTOR IDS;
        public SENDCMDOUTPARAMS()
        {
            Status = new DRIVERSTATUS();
            IDS = new IDSECTOR();
        }
    }

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern int CloseHandle(int hObject);

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern int CreateFile(
                string lpFileName,
                uint dwDesiredAccess,
                int dwShareMode,
                int lpSecurityAttributes,
                int dwCreationDisposition,
                int dwFlagsAndAttributes,
                int hTemplateFile
            );

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern int DeviceIoControl(
            int hDevice,
            int dwIoControlCode,
            [In(), Out()] SENDCMDINPARAMS lpInBuffer,
            int lpInBufferSize,
            [In(), Out()] SENDCMDOUTPARAMS lpOutBuffer,
            int lpOutBufferSize,
            ref int lpBytesReturned,
            int lpOverlapped
        );

    private string SwapChars(char[] chars)
    {
        for (int i = 0; i <= chars.Length - 2; i += 2)
        {
            char t;
            t = chars[i];
            chars[i] = chars[i + 1];
            chars[i + 1] = t;
        }
        string s = new string(chars);
        return s;
    }


     private void button1_Click(object sender, System.EventArgs e)
    {

        string serialNumber = " ", model = " ", firmware = " ";
        bool result;
        DriveTypes driveType = DriveTypes.Unknown;
        int handle, returnSize = 0;
        int driveNumber = 0;
        SENDCMDINPARAMS sci = new SENDCMDINPARAMS();
        SENDCMDOUTPARAMS sco = new SENDCMDOUTPARAMS();

        if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            //               \\.\PhysicalDrive0    Opens the first physical drive.
            //               \\.\PhysicalDrive2    Opens the third physical drive.
            // see more info on http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
            handle = CreateFile("\\\\.\\PhysicalDrive" + "0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
        else // for win'9x
            handle = CreateFile("\\\\.\\Smartvsd", 0, 0, 0, CREATE_NEW, 0, 0);
        if (handle != INVALID_HANDLE_VALUE)
        {
            sci.DriveNumber = (byte)driveNumber;
            sci.BufferSize = Marshal.SizeOf(sco);
            sci.DriveRegs.DriveHead = (byte)(0xA0 | driveNumber << 4);
            sci.DriveRegs.Command = 0xEC;
            sci.DriveRegs.SectorCount = 1;
            sci.DriveRegs.SectorNumber = 1;
            if (DeviceIoControl(handle, DFP_RECEIVE_DRIVE_DATA, sci, Marshal.SizeOf(sci), sco, Marshal.SizeOf(sco), ref returnSize, 0) != 0)
            {
                serialNumber = SwapChars(sco.IDS.SerialNumber);
                model = SwapChars(sco.IDS.ModelNumber);
                firmware = SwapChars(sco.IDS.FirmwareRevision);
            }

            textBox1.Text = serialNumber;
            textBox2.Text = model;
            textBox3.Text = firmware;
            if ((sco.IDS.GenConfig & 0x80) == 0x40)
                driveType = DriveTypes.Removable;
            else if ((sco.IDS.GenConfig & 0x40) == 0x40)
                driveType = DriveTypes.Fixed;
            else
                driveType = DriveTypes.Unknown;
            CloseHandle(handle);
            textBox4.Text = DriveStrings[(int)driveType];
        }
    }

Use the createfile as shown below. It may require administrative permissions.Add 4 text boxes and a button in your code.

 private const int CREATE_NEW = 1;
    private const int OPEN_EXISTING = 3;
    private const uint GENERIC_READ = 0x80000000; 
    private const uint GENERIC_WRITE = 0x40000000;
    // 10000000000000000000000000000000 --- GENERIC_READ
    // 01000000000000000000000000000000 --- GENERIC_WRITE
    // 00100000000000000000000000000000 --- GENERIC_EXECUTE
    // 00010000000000000000000000000000 --- GENERIC_ALL       

    //Securable objects use an access mask format in which the 
    //four high-order bits specify generic access rights


    private const int FILE_SHARE_READ = 0x1;      
    private const int FILE_SHARE_WRITE = 0x2;
    // 00000000000000000000000000000001 --- FILE_SHARE_READ
    // 00000000000000000000000000000010 --- FILE_SHARE_WRITE
    // 00000000000000000000000000000100 --- FILE_SHARE_DELETE 

    private const int VER_PLATFORM_WIN32_NT = 2;
    private const int DFP_RECEIVE_DRIVE_DATA = 0x7C088;
    //     0         000000000000111         11                  0               00000100010         00
    //     Common    Device Type             Required Access     Custom          Function Code       Transfer Type

    private const int INVALID_HANDLE_VALUE = -1;

    public enum DriveTypes { Fixed, Removable, Unknown };
    public string[] DriveStrings = { "Fixed", "Removable", "Unknown" };

    [StructLayout(LayoutKind.Sequential, Size = 8)]
    private class IDEREGS
    {
        public byte Features;
        public byte SectorCount;
        public byte SectorNumber;
        public byte CylinderLow;
        public byte CylinderHigh;
        public byte DriveHead;
        public byte Command;
        public byte Reserved;
    }

    [StructLayout(LayoutKind.Sequential, Size = 32)]
    private class SENDCMDINPARAMS
    {
        public int BufferSize;
        public IDEREGS DriveRegs;
        public byte DriveNumber;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public byte[] Reserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] Reserved2;
        public SENDCMDINPARAMS()
        {
            DriveRegs = new IDEREGS();
            Reserved = new byte[3];
            Reserved2 = new int[4];
        }
    }
    [StructLayout(LayoutKind.Sequential, Size = 12)]
    private class DRIVERSTATUS
    {
        public byte DriveError;
        public byte IDEStatus;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Reserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public int[] Reserved2;
        public DRIVERSTATUS()
        {
            Reserved = new byte[2];
            Reserved2 = new int[2];
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class IDSECTOR
    {
        public short GenConfig;
        public short NumberCylinders;
        public short Reserved;
        public short NumberHeads;
        public short BytesPerTrack;
        public short BytesPerSector;
        public short SectorsPerTrack;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public short[] VendorUnique;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
        public char[] SerialNumber;
        public short BufferClass;
        public short BufferSize;
        public short ECCSize;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public char[] FirmwareRevision;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
        public char[] ModelNumber;
        public short MoreVendorUnique;
        public short DoubleWordIO;
        public short Capabilities;
        public short Reserved1;
        public short PIOTiming;
        public short DMATiming;
        public short BS;
        public short NumberCurrentCyls;
        public short NumberCurrentHeads;
        public short NumberCurrentSectorsPerTrack;
        public int CurrentSectorCapacity;
        public short MultipleSectorCapacity;
        public short MultipleSectorStuff;
        public int TotalAddressableSectors;
        public short SingleWordDMA;
        public short MultiWordDMA;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 382)]
        public byte[] Reserved2;
        public IDSECTOR()
        {
            VendorUnique = new short[3];
            Reserved2 = new byte[382];
            FirmwareRevision = new char[8];
            SerialNumber = new char[20];
            ModelNumber = new char[40];
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class SENDCMDOUTPARAMS
    {
        public int BufferSize;
        public DRIVERSTATUS Status;
        public IDSECTOR IDS;
        public SENDCMDOUTPARAMS()
        {
            Status = new DRIVERSTATUS();
            IDS = new IDSECTOR();
        }
    }

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern int CloseHandle(int hObject);

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern int CreateFile(
                string lpFileName,
                uint dwDesiredAccess,
                int dwShareMode,
                int lpSecurityAttributes,
                int dwCreationDisposition,
                int dwFlagsAndAttributes,
                int hTemplateFile
            );

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern int DeviceIoControl(
            int hDevice,
            int dwIoControlCode,
            [In(), Out()] SENDCMDINPARAMS lpInBuffer,
            int lpInBufferSize,
            [In(), Out()] SENDCMDOUTPARAMS lpOutBuffer,
            int lpOutBufferSize,
            ref int lpBytesReturned,
            int lpOverlapped
        );

    private string SwapChars(char[] chars)
    {
        for (int i = 0; i <= chars.Length - 2; i += 2)
        {
            char t;
            t = chars[i];
            chars[i] = chars[i + 1];
            chars[i + 1] = t;
        }
        string s = new string(chars);
        return s;
    }


     private void button1_Click(object sender, System.EventArgs e)
    {

        string serialNumber = " ", model = " ", firmware = " ";
        bool result;
        DriveTypes driveType = DriveTypes.Unknown;
        int handle, returnSize = 0;
        int driveNumber = 0;
        SENDCMDINPARAMS sci = new SENDCMDINPARAMS();
        SENDCMDOUTPARAMS sco = new SENDCMDOUTPARAMS();

        if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            //               \\.\PhysicalDrive0    Opens the first physical drive.
            //               \\.\PhysicalDrive2    Opens the third physical drive.
            // see more info on http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
            handle = CreateFile("\\\\.\\PhysicalDrive" + "0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
        else // for win'9x
            handle = CreateFile("\\\\.\\Smartvsd", 0, 0, 0, CREATE_NEW, 0, 0);
        if (handle != INVALID_HANDLE_VALUE)
        {
            sci.DriveNumber = (byte)driveNumber;
            sci.BufferSize = Marshal.SizeOf(sco);
            sci.DriveRegs.DriveHead = (byte)(0xA0 | driveNumber << 4);
            sci.DriveRegs.Command = 0xEC;
            sci.DriveRegs.SectorCount = 1;
            sci.DriveRegs.SectorNumber = 1;
            if (DeviceIoControl(handle, DFP_RECEIVE_DRIVE_DATA, sci, Marshal.SizeOf(sci), sco, Marshal.SizeOf(sco), ref returnSize, 0) != 0)
            {
                serialNumber = SwapChars(sco.IDS.SerialNumber);
                model = SwapChars(sco.IDS.ModelNumber);
                firmware = SwapChars(sco.IDS.FirmwareRevision);
            }

            textBox1.Text = serialNumber;
            textBox2.Text = model;
            textBox3.Text = firmware;
            if ((sco.IDS.GenConfig & 0x80) == 0x40)
                driveType = DriveTypes.Removable;
            else if ((sco.IDS.GenConfig & 0x40) == 0x40)
                driveType = DriveTypes.Fixed;
            else
                driveType = DriveTypes.Unknown;
            CloseHandle(handle);
            textBox4.Text = DriveStrings[(int)driveType];
        }
    }
‘画卷フ 2024-08-05 16:18:16

可以在这里找到完美的工作解决方案:

http: //www.codeproject.com/Articles/16941/Get-Physical-HDD-Serial-Number-without-WMI

[编辑]
抱歉,错过了对此的引用已经提交。

A perfectly working solution can be found here:

http://www.codeproject.com/Articles/16941/Get-Physical-HDD-Serial-Number-without-WMI

[edit]
Sorry, missed that a reference to this has already been submitted.

寻找一个思念的角度 2024-08-05 16:18:16

您可以使用:

GetVolumeInformation

Win32 API 函数来获取此信息,如果您必须避免 WMI。 链接页面提供了 API 函数的完整声明签名(VB 和 C# 格式)以及示例代码。

You can use the:

GetVolumeInformation

Win32 API function to get this information, if you must avoid WMI. The linked page gives full the declaration signature (in both VB & C#) for the API function along with sample code.

栖迟 2024-08-05 16:18:16

你最好的选择是Windows api,

我做了一个简单的搜索并得到了这个

一般处理器信息以及阅读这篇文章

Your best options is windows api,

i made a simple search and got this

General processor info and also read this post

妞丶爷亲个 2024-08-05 16:18:16

我在我的项目中使用硬盘固件轨道。 我在 MDI 表单后面进行编程以查找 HDD 固件编号,然后在公司计算机的所有提供的 HDD 编号上进行循环,如果它与这些提供的 HDD 固件编号中的任何一个匹配,则运行应用程序并加载 MDI 表单,否则会提供一个消息“该应用程序未在此计算机上注册,请致电 Afridi 先生在 00923339176357 上注册该应用程序。我的电子邮件地址是 [电子邮件受保护]。我将发送获取如何编程专业硬盘固件编号以及如何阻止其他人非法使用您的应用程序的完整源代码。

cfemail= " 公司立即计算硬盘固件,让应用程序首先选择硬盘固件编号,将其存储在变量中,然后选择该变量的值(字符串值)并使用 OR 逻辑对每个硬盘编号逐一循环操作员。 如果它在具有可变值的公司硬盘编号中找到匹配的编号,则应用程序应加载主表单(mdi),否则通知用户进行注册。

示例代码将使用 vb6 提供。 只需了解如何将非托管代码调用到托管 .net 应用程序中,您以后就可以轻松地在 vb.net 中进行编程。 在本例中为 .dll。

I am using hdd firmware track in my projects. I programmed behind the mdi form to look for hdd firmware number, then its looping on all the provided numbers of hdds of companies computers and if it matches anyone amongst these provided hdds firmware numbers, then run the applicatoin and load mdi form other wise provides a message "The application is not registed on this machine, please call Mr. Afridi to register this application on 00923339176357. My email address is [email protected]. I will send complete source code of fetching how to programm professionaly hdd firmware number and how to stop others by using your app illegaly.

One lovely thing that you should specify all the company computers hdd firmware at once and let the application first pick the hdd firmware number, store it in a variable and then pick the value of this variable(a string value) and loop it one by one with each hdd number by using OR logical operator. If it finds a matching number amongst the companies hdds numbers with variable value, then app should load main form(mdi) other wise notify the user for registration.

The sample code will be provided using vb6. You can easily programm later on in vb.net just by understanding how to call unmanaged code in to a managed .net application. In this case a .dll.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文