用C#获取硬盘序列号,CPU序列号,网卡MAC地址
這個問題首先得考慮的就是你的硬盤是不是SCSI硬盤
如果是,那么根本不存在"物理序列號",只可能取得卷標的序列號
如果是卷標序列號,要注意的是每次格式化硬盤的時候這個序列號都會變
代碼可以參考:
http://www.csdn.net/Develop/Read_Article.asp?Id=25196
如果是物理序列號:
String HDid;
ManagementClass cimobject = new ManagementClass("Win32_DiskDrive");
ManagementObjectCollection moc = cimobject.GetInstances();
foreach(ManagementObject mo in moc)
{
HDid = (string)mo.Properties["Model"].Value;
MessageBox.Show(HDid );
}
如果是取得邏輯序列號(Format產生的那個),用WMI就可以,在引用中,添加system.mangement以后。
using System.Management;
.....
ManagementObject m_objDisk = new ManagementObject( "win32_logicaldisk.deviceid=\"c\"");
string strSN = (string)m_objDisk.GetPropertyValue( "VolumeSerialNumber ");
如果要取得物理分區號,看這個帖子:
關于硬盤序列號,高手請留步啊. (之一)
http://expert.csdn.net/Expert/TopicView3.asp?id=1143107
683E0480(第一種方案取得)
ST3160815AS (第二個方案取得的)
5239355835565745202020202020202020202020(第三種方案取得)
private string[] GetMoc()
{
string[] str = new string[3];
ManagementClass mcCpu = new ManagementClass("win32_Processor");
ManagementObjectCollection mocCpu = mcCpu.GetInstances();
foreach(ManagementObject m in mocCpu)
{
str[0] = m["ProcessorId"].ToString();
}
以上為取硬盤邏輯分區序列號,重新格式化會改變
以下為硬盤物理序列號,需管理員權限,wmi
復制代碼
using System;
using System.Management;
namespace HTSoft.Common.Register
{
/// <summary>
/// 計算機信息類
/// </summary>
internal class Computer
{
public string CpuID;
public string MacAddress;
public string DiskID;
public string IpAddress;
public string LoginUserName;
public string ComputerName;
public string SystemType;
public string TotalPhysicalMemory; //單位:M
private static Computer _instance;
}
復制代碼
第三種方案:
Code
一般軟件的注冊機制可以通過獲取硬件序列號,然后用非對稱加密算法生成相應的公鑰和私鑰。但是用Managed Code寫獲取硬盤序列號的代碼不能解決所有的問題,比如不能在非管理員的權限下使用,前幾天Sunmast在他的Blog上發布了《如何得到硬盤序列號?.NET版本[C#]》,就是沒有解決這個問題,用WMI也有很多問題。
要想順利獲取硬盤的序列號,目前只能依靠非托管代碼了。DiskId32是一個源碼公開的C++程序,可以解決上述問題。由于代碼比較底層,我對VC和DDK不熟悉,沒有能力將其封裝為DLL,希望各位幫忙!
還有,就算封裝好了這個Native DLL并可以使用了,但還有問題沒有解決。如果封裝到了Native DLL,該DLL很容易被人替換成另外一個,畢竟在Managed Code里面可以看到調用Native DLL的函數聲明,別人只要模仿這些函數界面重新寫一個新的就很容易達到破解目的了。不過具體我沒有測試過,不知道行不行。
于是我又想到了另外一個方法,就是把獲取硬盤序列號的Native DLL作為資源文件封裝到Managed Code中,然后在每次要調要該DLL時,先把該DLL寫入磁盤,再動態綁定。由于Managed Code可以通過混淆器來保護,以致不能對其進行修改,這個我在《如何保護我們的 .NET 程序集?》中已經給出了答案。動態綁定Native DLL又是另外一個技術難題,我已經找到了一些資料,與大家分享。
Late binding on native DLLs with C#
Late-Binding DLLs in C#
Using legacy plug-ins with .NET - Part 1
Using legacy plug-ins with .NET - Part 2
C-Function pointer for .NET
Dynamic PInvoke method calls
不過最牛的就是下面這一招了!直接把Native Code用字節數組保存在Managed Code中,然后調用,真是牛B,不過我還沒有完全弄懂,希望大家來實踐實踐。
Execute Native Code From .NET
另外還有一篇文章是關于加密字符串的,值得研究!
Poly-Engine Crypt String
希望各位多多交流.NET程序的保護問題,找出最好的解決方案!
http://www.winsim.com/diskid32/diskid32.html
復制代碼
這個問題我查找了一下,已經有很多很多很多人問過了,有給了一些相映的解答。
1)利用 WMI 讀取
2)有高人給了一個地址,http://www.winsim.com/diskid32/diskid32.html 。同時給了一大段代碼,代碼見后面。
但是沒有明確講出來如何使用。尤其是第二種方法,感覺不錯,只是不懂得如何使用,哪位指點小弟一二
public class IDE
{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
internal struct IDSECTOR
{
public ushort wGenConfig;
public ushort wNumCyls;
public ushort wReserved;
public ushort wNumHeads;
public ushort wBytesPerTrack;
public ushort wBytesPerSector;
public ushort wSectorsPerTrack;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=3)]
public ushort [] wVendorUnique;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=20)]
public string sSerialNumber;
public ushort wBufferType;
public ushort wBufferSize;
public ushort wECCSize;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=8)]
public string sFirmwareRev;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=40)]
public string sModelNumber;
public ushort wMoreVendorUnique;
public ushort wDoubleWordIO;
public ushort wCapabilities;
public ushort wReserved1;
public ushort wPIOTiming;
public ushort wDMATiming;
public ushort wBS;
public ushort wNumCurrentCyls;
public ushort wNumCurrentHeads;
public ushort wNumCurrentSectorsPerTrack;
public uint ulCurrentSectorCapacity;
public ushort wMultSectorStuff;
public uint ulTotalAddressableSectors;
public ushort wSingleWordDMA;
public ushort wMultiWordDMA;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=128 )]
public byte [] bReserved;
}
}
[StructLayout(LayoutKind.Sequential)] internal struct GETVERSIONOUTPARAMS { public byte bVersion; public byte bRevision; public byte bReserved; public byte bIDEDeviceMap; public uint fCapabilities; [ MarshalAs( UnmanagedType.ByValArray, SizeConst=4 )] public uint [] dwReserved; // For future use. } [DllImport("kernel32.dll")] private static extern int CloseHandle(uint hObject); [DllImport("kernel32.dll")] private static extern int DeviceIoControl(uint hDevice, uint dwIoControlCode, ref SENDCMDINPARAMS lpInBuffer, int nInBufferSize, ref SENDCMDOUTPARAMS lpOutBuffer, int nOutBufferSize, ref uint lpbytesReturned, int lpOverlapped); [DllImport("kernel32.dll")] private static extern int DeviceIoControl(uint hDevice, uint dwIoControlCode, int lpInBuffer, int nInBufferSize, ref GETVERSIONOUTPARAMS lpOutBuffer, int nOutBufferSize, ref uint lpbytesReturned, int lpOverlapped); [DllImport("kernel32.dll")] private static extern uint CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, int lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, int hTemplateFile); private const uint GENERIC_READ = 0x80000000; private const uint GENERIC_WRITE = 0x40000000; private const uint FILE_SHARE_READ = 0x00000001; private const uint FILE_SHARE_WRITE = 0x00000002; private const uint OPEN_EXISTING = 3; private const uint INVALID_HANDLE_VALUE = 0xffffffff; private const uint DFP_GET_VERSION = 0x00074080; private const int IDE_ATAPI_IDENTIFY = 0xA1; // Returns ID sector for ATAPI. private const int IDE_ATA_IDENTIFY = 0xEC; // Returns ID sector for ATA. private const int IDENTIFY_BUFFER_SIZE = 512; private const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088; public static string Read(byte drive) { OperatingSystem os = Environment.OSVersion; if (os.Platform != PlatformID.Win32NT) throw new NotSupportedException("僅支持WindowsNT/2000/XP"); //我沒有NT4,請哪位大大測試一下NT4下能不能用 //if (os.Version.Major < 5) throw new NotSupportedException("僅支持WindowsNT/2000/XP"); string driveName = "\\\\.\\PhysicalDrive" + drive.ToString(); uint device = CreateFile(driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (device == INVALID_HANDLE_VALUE) return ""; GETVERSIONOUTPARAMS verPara = new GETVERSIONOUTPARAMS(); uint bytRv = 0; if (0 != DeviceIoControl(device, DFP_GET_VERSION, 0, 0, ref verPara, Marshal.SizeOf(verPara), ref bytRv, 0)) { if (verPara.bIDEDeviceMap > 0) { byte bIDCmd = (byte)(((verPara.bIDEDeviceMap >> drive & 0x10) != 0) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY); SENDCMDINPARAMS scip = new SENDCMDINPARAMS(); SENDCMDOUTPARAMS scop = new SENDCMDOUTPARAMS(); scip.cBufferSize = IDENTIFY_BUFFER_SIZE; scip.irDriveRegs.bFeaturesReg = 0; scip.irDriveRegs.bSectorCountReg = 1; scip.irDriveRegs.bCylLowReg = 0; scip.irDriveRegs.bCylHighReg = 0; scip.irDriveRegs.bDriveHeadReg = (byte)(0xA0 | ((drive & 1) << 4)); scip.irDriveRegs.bCommandReg = bIDCmd; scip.bDriveNumber = drive; if (0 != DeviceIoControl(device, DFP_RECEIVE_DRIVE_DATA, ref scip, Marshal.SizeOf(scip), ref scop, Marshal.SizeOf(scop), ref bytRv, 0)) { StringBuilder s = new StringBuilder(); for (int i = 20; i < 40; i += 2) { s.Append((char)(scop.bBuffer[i+1])); s.Append((char)scop.bBuffer[i]); } CloseHandle(device); return s.ToString().Trim(); } } } CloseHandle(device); return ""; }}
轉載于:https://blog.51cto.com/13269635/2175679
總結
以上是生活随笔為你收集整理的用C#获取硬盘序列号,CPU序列号,网卡MAC地址的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HAProxy详解(二):HAProxy
- 下一篇: 分布式事务概览