C# 如何在不使用 .NET 中的 WMI 的情况下找到硬盘设备序列号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1176887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I find the Harddisk Device Serial Number without using the WMI in .NET?
提问by Jey Geethan
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?
我想从硬盘获取硬连线序列号但不使用 WMI。我尝试使用 WMI 代码,但它确实在我的机器上不起作用。那么在 .NET 中是否有其他方法可以找到物理硬盘的序列号?
回答by Espo
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 Toolsto check/fix this.
关于 WMI 不返回数据的问题;您确定如何使用正确的权限从 WMI 获取数据吗?您可以使用WMI 工具来检查/修复此问题。
回答by CraigTP
You can use the:
您可以使用:
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.
Win32 API 函数来获取此信息,如果您必须避免 WMI。链接页面提供了 API 函数的完整声明签名(在 VB 和 C# 中)以及示例代码。
回答by Johann Strydom
Use WMI from Server Explorer in VS
在 VS 中使用来自服务器资源管理器的 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 属性
回答by Munawar Shah Afridi
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.
我在我的项目中使用硬盘固件轨道。我在 mdi 表单后面编程以查找 hdd 固件编号,然后它在公司计算机的所有提供的 hdd 编号上循环,如果它与这些提供的 hdds 固件编号中的任何人匹配,则运行应用程序并加载 mdi 表单,否则提供一个留言“该应用程序未在本机注册,请致电Afridi先生在00923339176357注册该应用程序。我的电子邮件地址是[email protected]。我将发送获取如何编程专业硬盘固件号以及如何编程的完整源代码阻止他人非法使用您的应用程序。
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.
一件可爱的事情,您应该一次指定所有公司计算机的硬盘固件,并让应用程序首先选择硬盘固件编号,将其存储在一个变量中,然后选择该变量的值(字符串值)并一个一个循环使用 OR 逻辑运算符对每个硬盘编号进行处理。如果它在具有可变值的公司硬盘号码中找到匹配的号码,则应用程序应加载主表单(mdi),否则通知用户进行注册。
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.
示例代码将使用 vb6 提供。您可以稍后在 vb.net 中轻松编程,只需了解如何将非托管代码调用到托管 .net 应用程序中。在本例中为 .dll。
回答by Smith
Your best options is windows api,
你最好的选择是 windows api,
i made a simple search and got this
我做了一个简单的搜索,得到了这个
General processor infoand also read this post
回答by mtx
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.
[编辑] 抱歉,错过了已经提交的参考。
回答by Navaneet
Use the createfileas shown below. It may require administrative permissions.Add 4 text boxes and a button in your code.
使用的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];
}
}