简体   繁体   English

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

[英]How can I find the Harddisk Device Serial Number without using the WMI in .NET?

I want to get the hardwired serial number from the hard disk but NOT using WMI. 我想从硬盘上获取有线序列号,但不使用WMI。 I tried using WMI code, and it doesn't work on my machine for sure. 我尝试使用WMI代码,但肯定不能在我的计算机上使用它。 So is there any alternative in .NET for finding the Serial Number of a physical hard disk? 那么,.NET中是否可以找到物理硬盘的序列号呢?

This should help get started: 这应该有助于入门:

How to get Physical HDD serial number without WMI 如何在没有WMI的情况下获取物理硬盘序列号

Regarding your problem with WMI not returning data; 关于WMI不返回数据的问题; Are you sure how to the right privileges to get data from WMI? 您确定如何获得从WMI获取数据的正确特权吗? You can use WMI Tools to check/fix this. 您可以使用WMI工具检查/修复此问题。

Use the createfile as shown below. 如下所示使用createfile It may require administrative permissions.Add 4 text boxes and a button in your code. 它可能需要管理权限。在代码中添加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];
        }
    }

A perfectly working solution can be found here: 可以在这里找到一个完美的解决方案:

http://www.codeproject.com/Articles/16941/Get-Physical-HDD-Serial-Number-without-WMI 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. [edit]对不起,错过了对此的引用。

You can use the: 您可以使用:

GetVolumeInformation GetVolumeInformation

Win32 API function to get this information, if you must avoid WMI. 如果必须避免WMI,则需要Win32 API函数来获取此信息。 The linked page gives full the declaration signature (in both VB & C#) for the API function along with sample code. 链接的页面提供了API函数的完整声明签名(在VB和C#中)以及示例代码。

I am using hdd firmware track in my projects. 我在项目中使用HDD固件轨道。 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 munawar_s_afridi@yahoo.com. 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. 我在mdi表格后面编程以查找硬盘固件号,然后在所有提供的公司计算机硬盘号上循环播放,如果它与这些提供的硬盘固件号中的任何一个匹配,则运行应用程序并以其他方式加载mdi表格以提供一个消息“该应用程序未在此计算机上注册,请致电Afridi先生在00923339176357上注册此应用程序。我的电子邮件地址是munawar_s_afridi@yahoo.com。我将发送完整的源代码,以获取如何对专业的HDD固件编号进行编程以及如何进行编程。通过非法使用您的应用来阻止他人。

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. 一件很可爱的事,您应该立即指定所有公司计算机的硬盘固件,然后让应用程序首先选择硬盘固件号,将其存储在变量中,然后选择此变量的值(字符串值)并逐个循环通过使用OR逻辑运算符来处理每个硬盘号。 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. 如果它在具有可变值的公司硬盘编号中找到匹配的编号,则应用程序应加载主表格(mdi),否则通知用户进行注册。

The sample code will be provided using vb6. 将使用vb6提供示例代码。 You can easily programm later on in vb.net just by understanding how to call unmanaged code in to a managed .net application. 您可以稍后在vb.net中轻松编程,只需了解如何将非托管代码调用到托管.net应用程序中即可。 In this case a .dll. 在这种情况下,.dll。

Your best options is windows api, 最好的选择是Windows API,

i made a simple search and got this 我做了一个简单的搜索并得到了这个

General processor info and also read this post 一般处理器信息 ,也请阅读这篇文章

Use WMI from Server Explorer in VS 在VS中从Server Explorer使用WMI

  • Open Server explorer 打开服务器资源管理器
  • Expand your machine 扩展您的机器
  • Expand management classes 扩展管理课程
  • Expand Disk Volumes 扩展磁盘卷
  • Select the drive 选择驱动器
  • Drag it onto a form to see the generated code 将其拖动到表单上以查看生成的代码
  • Access the VolumeSerialNumber property in code 在代码中访问VolumeSerialNumber属性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM