ハードディスクのシリアル番号を取得したい。どうすればそれができますか?私は2つのコードで試しましたが、私は得ていません
StringCollection propNames = new StringCollection();
ManagementClass driveClass = new ManagementClass("Win32_DiskDrive");
PropertyDataCollection props = driveClass.Properties;
foreach (PropertyData driveProperty in props)
{
propNames.Add(driveProperty.Name);
}
int idx = 0;
ManagementObjectCollection drives = driveClass.GetInstances();
foreach (ManagementObject drv in drives)
{
Label2.Text+=(idx + 1);
foreach (string strProp in propNames)
{
//Label2.Text+=drv[strProp];
Response.Write(strProp + " = " + drv[strProp] + "</br>");
}
}
この場合、一意のシリアル番号は取得されません。
そして2つ目は
string drive = "C";
ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + drive + ":\"");
disk.Get();
Label3.Text = "VolumeSerialNumber="+ disk["VolumeSerialNumber"].ToString();
ここでVolumeSerialNumber
を取得しています。しかし、それはユニークなものではありません。ハードディスクをフォーマットすると、これが変わります。どうすれば入手できますか?
ええと、最初のコードセットを見て、ハードドライブモデルを(おそらく)取得したと思います。シリアル番号はWin32_PhysicalMedia
。
ハードドライブモデルを取得する
ManagementObjectSearcher searcher = new
ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach(ManagementObject wmi_HD in searcher.Get())
{
HardDrive hd = new HardDrive();
hd.Model = wmi_HD["Model"].ToString();
hd.Type = wmi_HD["InterfaceType"].ToString();
hdCollection.Add(hd);
}
シリアル番号を取得する
searcher = new
ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
int i = 0;
foreach(ManagementObject wmi_HD in searcher.Get())
{
// get the hard drive from collection
// using index
HardDrive hd = (HardDrive)hdCollection[i];
// get the hardware serial no.
if (wmi_HD["SerialNumber"] == null)
hd.SerialNo = "None";
else
hd.SerialNo = wmi_HD["SerialNumber"].ToString();
++i;
}
お役に立てれば :)
プロジェクトで次の方法を使用しましたが、正常に機能しています。
private string identifier(string wmiClass, string wmiProperty)
//Return a hardware identifier
{
string result = "";
System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
//Only get the first one
if (result == "")
{
try
{
result = mo[wmiProperty].ToString();
break;
}
catch
{
}
}
}
return result;
}
下記のように上記のメソッドを呼び出すことができます、
string modelNo = identifier("Win32_DiskDrive", "Model");
string manufatureID = identifier("Win32_DiskDrive", "Manufacturer");
string signature = identifier("Win32_DiskDrive", "Signature");
string totalHeads = identifier("Win32_DiskDrive", "TotalHeads");
一意の識別子が必要な場合は、これらのIDの組み合わせを使用してください。
@ Sprunthの答えには簡単な方法があります。
private void GetAllDiskDrives()
{
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject wmi_HD in searcher.Get())
{
HardDrive hd = new HardDrive();
hd.Model = wmi_HD["Model"].ToString();
hd.InterfaceType = wmi_HD["InterfaceType"].ToString();
hd.Caption = wmi_HD["Caption"].ToString();
hd.SerialNo =wmi_HD.GetPropertyValue("SerialNumber").ToString();//get the serailNumber of diskdrive
hdCollection.Add(hd);
}
}
public class HardDrive
{
public string Model { get; set; }
public string InterfaceType { get; set; }
public string Caption { get; set; }
public string SerialNo { get; set; }
}
「vol」シェルコマンドを使用し、このように出力からシリアルを解析します。少なくともWin7で動作します
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CheckHD
{
class HDSerial
{
const string MY_SERIAL = "F845-BB23";
public static bool CheckSerial()
{
string res = ExecuteCommandSync("vol");
const string search = "Number is";
int startI = res.IndexOf(search, StringComparison.InvariantCultureIgnoreCase);
if (startI > 0)
{
string currentDiskID = res.Substring(startI + search.Length).Trim();
if (currentDiskID.Equals(MY_SERIAL))
return true;
}
return false;
}
public static string ExecuteCommandSync(object command)
{
try
{
// create the ProcessStartInfo using "cmd" as the program to be run,
// and "/c " as the parameters.
// Incidentally, /c tells cmd that we want it to execute the command that follows,
// and then exit.
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
// The following commands are needed to redirect the standard output.
// This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
string result = proc.StandardOutput.ReadToEnd();
// Display the command output.
return result;
}
catch (Exception)
{
// Log the exception
return null;
}
}
}
}
以下に役立つコードをいくつか示します。
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
string serial_number="";
foreach (ManagementObject wmi_HD in searcher.Get())
{
serial_number = wmi_HD["SerialNumber"].ToString();
}
MessageBox.Show(serial_number);
私はこれを使用しています:
<!-- language: c# -->
private static string wmiProperty(string wmiClass, string wmiProperty){
using (var searcher = new ManagementObjectSearcher($"SELECT * FROM {wmiClass}")) {
try {
IEnumerable<ManagementObject> objects = searcher.Get().Cast<ManagementObject>();
return objects.Select(x => x.GetPropertyValue(wmiProperty)).FirstOrDefault().ToString().Trim();
} catch (NullReferenceException) {
return null;
}
}
}
CLRのないOSでアプリケーションを実行する必要がある場合に、win32 apiとstd文字列を使用するソリューションを次に示します。ここで github で見つけました。
#include "stdafx.h"
#include <windows.h>
#include <memory>
#include <string>
//returns the serial number of the first physical drive in a std::string or an empty std::string in case of failure
//based on http://codexpert.ro/blog/2013/10/26/get-physical-drive-serial-number-part-1/
std::string getFirstHddSerialNumber() {
//get a handle to the first physical drive
HANDLE h = CreateFileW(L"\\\\.\\PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (h == INVALID_HANDLE_VALUE) return{};
//an std::unique_ptr is used to perform cleanup automatically when returning (i.e. to avoid code duplication)
std::unique_ptr<std::remove_pointer<HANDLE>::type, void(*)(HANDLE)> hDevice{ h, [](HANDLE handle){CloseHandle(handle); } };
//initialize a STORAGE_PROPERTY_QUERY data structure (to be used as input to DeviceIoControl)
STORAGE_PROPERTY_QUERY storagePropertyQuery{};
storagePropertyQuery.PropertyId = StorageDeviceProperty;
storagePropertyQuery.QueryType = PropertyStandardQuery;
//initialize a STORAGE_DESCRIPTOR_HEADER data structure (to be used as output from DeviceIoControl)
STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader{};
//the next call to DeviceIoControl retrieves necessary size (in order to allocate a suitable buffer)
//call DeviceIoControl and return an empty std::string on failure
DWORD dwBytesReturned = 0;
if (!DeviceIoControl(hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
&storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), &dwBytesReturned, NULL))
return{};
//allocate a suitable buffer
const DWORD dwOutBufferSize = storageDescriptorHeader.Size;
std::unique_ptr<BYTE[]> pOutBuffer{ new BYTE[dwOutBufferSize]{} };
//call DeviceIoControl with the allocated buffer
if (!DeviceIoControl(hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
pOutBuffer.get(), dwOutBufferSize, &dwBytesReturned, NULL))
return{};
//read and return the serial number out of the output buffer
STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(pOutBuffer.get());
const DWORD dwSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset;
if (dwSerialNumberOffset == 0) return{};
const char* serialNumber = reinterpret_cast<const char*>(pOutBuffer.get() + dwSerialNumberOffset);
return serialNumber;
}
#include <iostream>
int main() {
std::string serialNumber = getFirstHddSerialNumber();
if (serialNumber.empty())
std::cout << "failed to retrieve serial number\n";
else
std::cout << "serial number: " << serialNumber << "\n";
return 0;
}
ハードディスクのシリアル番号を取得するための完全に機能する方法を以下に示します。
public string GetHardDiskSerialNo()
{
ManagementClass mangnmt = new ManagementClass("Win32_LogicalDisk");
ManagementObjectCollection mcol = mangnmt.GetInstances();
string result = "";
foreach (ManagementObject strt in mcol)
{
result += Convert.ToString(strt["VolumeSerialNumber"]);
}
return result;
}
コピー保護に使用し、1台のコンピューターで常に同じシリアルを返す必要がある場合(もちろん、最初のhddまたはssdが変更されていない限り)、以下のコードをお勧めします。 ManagementClassの場合、System.Managementへの参照を追加する必要があります。追伸「InterfaceType」と「DeviceID」がなければ、メソッドがランダムディスクのシリアルまたは現在PCに接続したUSBフラッシュドライブのシリアルを返すことができることを確認します。
public static string GetSerial()
{
try
{
var mc = new ManagementClass("Win32_DiskDrive");
var moc = mc.GetInstances();
var res = string.Empty;
var resList = new List<string>(moc.Count);
foreach (ManagementObject mo in moc)
{
try
{
if (mo["InterfaceType"].ToString().Replace(" ", string.Empty) == "USB")
{
continue;
}
}
catch
{
}
try
{
res = mo["SerialNumber"].ToString().Replace(" ", string.Empty);
resList.Add(res);
if (mo["DeviceID"].ToString().Replace(" ", string.Empty).Contains("0"))
{
if (!string.IsNullOrWhiteSpace(res))
{
return res;
}
}
}
catch
{
}
}
res = resList[0];
if (!string.IsNullOrWhiteSpace(res))
{
return res;
}
}
catch
{
}
return string.Empty;
}
私が見つけた最良の方法は、 here からdllをダウンロードすることです
次に、dllをプロジェクトに追加します。
次に、コードを追加します。
[DllImportAttribute("HardwareIDExtractorC.dll")]
public static extern String GetIDESerialNumber(byte DriveNumber);
次に、必要な場所からハードディスクIDを呼び出します
GetIDESerialNumber(0).Replace(" ", string.Empty);
注:エクスプローラーでdllのプロパティに移動し、[ビルドアクション]を[埋め込みリソース]に設定します