C Sharpの基礎 - デバイス情報
概要
PCのデバイス情報には、以下に示すようなものがある。
- CPU
- 種類、速度、コア数
- メモリ
- 容量、種類、速度
- ストレージ
- 種類(HDD / SSD)、容量
- グラフィックカード
- モデル、VRAM容量
- マザーボード
- モデル、チップセット
- PCにインストールされているソフトウェア情報
- OS (種類、バージョン)
- インストールされたドライバ
- インストールされたアプリケーション
- ネットワーク情報
- IPアドレス
- MACアドレス
- ネットワークアダプタの種類
- 周辺機器情報
- 接続されたモニタ
- プリンタ
- その他のUSBデバイス
デバイス情報を取得することのメリットを以下に示す。
- アプリケーションのパフォーマンス最適化
- ハードウェア情報に基づいて処理を調整できる。
- トラブルシューティング
- システム情報を使って問題の原因特定が容易になる。
- ユーザエクスペリエンスの向上
- デバイスに適したUIや機能を提供できる。
- セキュリティ強化
- デバイス固有の情報を認証に利用できる。
また、デバイス情報を取得するにあたり、以下に示すようなデメリットも存在する。
- プライバシーの懸念
- ユーザの個人情報を収集する可能性がある。
- セキュリティリスク
- 悪用される可能性のある情報を取得する。
- 互換性の問題
- OSやハードウェアの変更により、取得方法が変わる可能性がある。
- パフォーマンスへの影響
- 頻繁な情報取得はシステムに負荷をかける可能性がある。
CPU
LibreHardwareMonitorライブラリ
LibreHardwareMonitorライブラリとは
LibreHardwareMonitorライブラリは、コンピュータのハードウェア情報を包括的に監視するためのオープンソースライブラリである。
元々は、OpenHardwareMonitorプロジェクトから派生しており、現在も活発に開発が続けられている。
LibreHardwareMonitorライブラリの主な特徴は、システムの様々なコンポーネントから詳細な情報を取得できることである。
CPU、GPU、マザーボード、RAM、ストレージデバイス、ネットワークアダプタ等、幅広いハードウェアをサポートしている。
各コンポーネントについて、温度、クロック速度、使用率、電圧等の重要なパラメータを監視することができる。
LibreHardwareMonitorライブラリの設計は非常に柔軟で、必要な情報のみを選択して取得することができる。
例えば、CPUの情報だけが必要な場合は、他のコンポーネントの監視を無効にすることにより、リソース使用を最適化できる。
また、このライブラリは異なるハードウェアメーカーや型番に対応するため、抽象化レイヤーを使用している。
これにより、開発者は特定のハードウェアの詳細を気にすることなく、一貫したインターフェースを通じて情報を取得することができる。
性能面では、LibreHardwareMonitorライブラリは一般的に効率的であるが、頻繁に更新を行う場合や全てのセンサを同時に監視する場合には、システムに若干の負荷がかかる可能性がある。
そのため、アプリケーションの要件に応じて、更新頻度や監視するコンポーネントを適切に選択することが重要である。
LibreHardwareMonitorライブラリは、システムのハードウェア情報を詳細に把握するアプリケーションにとって、強力で信頼性の高いツールである。
システム監視、パフォーマンス最適化、ハードウェア診断等、幅広い用途に活用できる有用なライブラリといえる。
LibreHardwareMonitorライブラリは、MPL 2.0ライセンスに準拠している。
- LibreHardwareMonitorライブラリの公式Webサイト
※注意 1
一部の機能では管理者権限が必要になる場合がある。
特に、センサからの詳細な読み取りや一部のハードウェア固有の情報を取得する場合が当てはまる。
※注意 2
LibreHardwareMonitorライブラリはWindowsプラットフォームで最も広範なサポートを提供している。
Linux上での使用は可能であるが、一部の機能が制限される、あるいは、追加の設定が必要な場合がある。
取得可能な情報
- CPU
- 温度
- 使用率
- クロック速度
- 電力消費
- マザーボード
- 各種センサの温度
- ファン速度
- RAM
- 使用量
- 空き容量
- GPU
- 温度
- 使用率
- メモリ使用量
- ファン速度
- ストレージデバイス
- 温度
- 使用量
- 読み書き速度
- ネットワークアダプタ
- データ送受信量
- 電源ユニット (対応している場合)
- 電圧
- 電流
- 電力消費
ただし、上記の情報は、システムやハードウェアの構成により利用可能な項目が異なる場合がある。
LibreHardwareMonitorライブラリのインストール
RiderまたはVisual StudioからNuGetを使用して、LibreHardwareMonitorライブラリをインストールする。
- Riderの場合
- プロジェクトを開く。
- [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
- メイン画面下部にある[パッケージ]タブから LibreHardwareMonitor と入力して検索する。
- メイン画面下部の右にある[+]ボタンを押下して、LibreHardwareMonitorライブラリをインストールする。
- Visual Studioの場合
- プロジェクトを開く。
- NuGetパッケージマネージャーを開く。
- [ツール]メインメニュー - [NuGetパッケージマネージャー]を選択して、[ソリューションのNuGetパッケージの管理]を選択する。
- または、ソリューションエクスプローラーでプロジェクトを右クリックして、コンテキストメニューから[NuGetパッケージの管理]を選択する。
- LibreHardwareMonitorライブラリを検索する。
- NuGetパッケージマネージャーの検索ボックスに LibreHardwareMonitor と入力して検索する。
- LibreHardwareMonitorライブラリのインストール
- 検索結果からTomlynLibreHardwareMonitorライブラリを選択して、[インストール]ボタンを押下する。
- インストールの確認ダイアログが表示されるので、[OK]ボタンを押下してインストールを完了する。
- 参照の確認
- インストールが完了した後、プロジェクトの参照にLibreHardwareMonitorライブラリが追加されていることを確認する。
- パッケージマネージャーコンソールからインストールする場合
- プロジェクトを開く。
- [表示]メインメニュー - [その他のウィンドウ] - [パッケージマネージャーコンソール]を選択して、パッケージマネージャーコンソールを開く。
- パッケージマネージャーコンソールから、Tomlynライブラリをダウンロードしてインストールする。
Install-Package LibreHardwareMonitorLib
- ソリューションエクスプローラーのプロジェクトの参照において、LibreHardwareMonitorライブラリが追加されていることを確認する。
dotnet
コマンドを使用する場合- ターミナルを開く。
- プロジェクトのルートディレクトリに移動する。
- LibreHardwareMonitorライブラリをインストールする。
- 最新の安定版をインストールする場合
dotnet add package LibreHardwareMonitorLib
- バージョンを指定してインストールする場合
dotnet add package LibreHardwareMonitorLib --version <バージョン>
- ※注意
- プロジェクトがGit等のバージョン管理システムを使用している場合、これらの変更がトラッキングされることを確認すること。
- プロジェクトを再ビルドして、新しく追加されたパッケージが正しく統合されていることを確認することを推奨する。
プロジェクトにおいて、LibreHardwareMonitorライブラリを使用する場合は、ソースコードファイルの先頭にusingステートメントを追加する。
これにより、名前空間を使用することで、LibreHardwareMonitorライブラリに関する主要な機能にアクセスすることができる。
using LibreHardwareMonitor.Hardware;
使用例
以下の例では、CPU情報を取得している。
また、LibreHardwareMonitorライブラリは、CPU以外の他のデバイス情報も提供しているため、より包括的な情報を取得することができる。
※注意 1
一部の情報 (特に温度や詳細な使用率) を取得する場合は、管理者権限が必要な場合がある。
※注意 2
LibreHardwareMonitorライブラリは常に最新のハードウェアに対応しているわけではない。
特に新しいCPUモデルの場合、一部の情報が正確でない可能性がある。
※注意 3
LibreHardwareMonitorライブラリはクロスプラットフォームをサポートしているが、一部の機能はWindowsでのみ動作する可能性がある。
using System;
using LibreHardwareMonitor.Hardware;
class Program
{
static void Main()
{
var computer = new Computer
{
IsCpuEnabled = true,
};
computer.Open();
foreach (var hardware in computer.Hardware)
{
if (hardware.HardwareType == HardwareType.Cpu)
{
Console.WriteLine($"CPU: {hardware.Name}");
hardware.Update();
foreach (var sensor in hardware.Sensors)
{
switch (sensor.SensorType)
{
case SensorType.Clock:
Console.WriteLine($"Clock: {sensor.Value} MHz");
break;
case SensorType.Temperature:
Console.WriteLine($"Temperature: {sensor.Value} °C");
break;
case SensorType.Load:
Console.WriteLine($"Load: {sensor.Value} %");
break;
}
}
}
}
computer.Close();
}
}
Hardware.Infoライブラリ
Hardware.Infoライブラリとは
Hardware.Infoライブラリは、C#で開発されたオープンソースのライブラリであり、コンピュータのハードウェア情報を収集するために設計されている。
このライブラリを使用することにより、開発者はシステムの詳細な情報を簡単に取得することができる。
主な特徴として、CPU、マザーボード、メモリ、ストレージデバイス、ネットワークアダプタ、ビデオカード等、様々なハードウェアコンポーネントの情報を提供する。
また、OSやBIOSの詳細も取得可能である。
Hardware.Infoライブラリのメリットの1つはその使いやすさであり、シンプルなAPIを通じて、複雑なハードウェア情報へのアクセスが可能になる。
これにより、システム診断ツール、ハードウェアモニタリングアプリケーション、システム要件チェッカー等の開発が容易になる。
このライブラリは、Windows、Linux、MacOS等の複数のプラットフォームをサポートしている。
クロスプラットフォーム対応により、開発者は異なるOS上で一貫したハードウェア情報収集が可能になる。
パフォーマンスの面では、Hardware.Infoライブラリは効率的な設計がなされており、システムへの負荷を最小限に抑えつつ迅速にデータを取得する。
また、非同期操作もサポートしているため、アプリケーションの応答性を維持しながら情報収集を行うことができる。
セキュリティとプライバシーに配慮して設計されており、センシティブな情報へのアクセスは制限されている。
ライブラリは必要最小限の権限で動作して、ユーザデータの保護に努めている。
拡張性も考慮されており、新しいハードウェアコンポーネントや技術に対応するためのアップデートが定期的に行われている。
開発者コミュニティからの貢献も活発で、継続的な改善が行われている。
Hardware.Infoライブラリのライセンスは、MITライセンスに準拠している。
- Hardware.Infoライブラリの公式Webサイト
取得可能な情報
- BIOS
- CPU および SoC
- RAM
- ストレージドライブ
- ネットワークアダプタ
- サウンドカード
- GPU
- バッテリー
- マザーボード
- マウス
- キーボード
- モニタ
- プリンタ
Hardware.Infoライブラリは、WindowsではWMI、Linuxでは/dev、/proc、/sys、MacOSではsysctl、system_profilerを使用する。
Hardware.Infoライブラリのインストール
RiderまたはVisual StudioからNuGetを使用して、Hardware.Infoライブラリをインストールする。
- Riderの場合
- プロジェクトを開く。
- [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
- メイン画面下部にある[パッケージ]タブから Hardware.Info と入力して検索する。
- メイン画面下部の右にある[+]ボタンを押下して、Hardware.Infoライブラリをインストールする。
- Visual Studioの場合
- プロジェクトを開く。
- NuGetパッケージマネージャーを開く。
- [ツール]メインメニュー - [NuGetパッケージマネージャー]を選択して、[ソリューションのNuGetパッケージの管理]を選択する。
- または、ソリューションエクスプローラーでプロジェクトを右クリックして、コンテキストメニューから[NuGetパッケージの管理]を選択する。
- Hardware.Infoライブラリを検索する。
- NuGetパッケージマネージャーの検索ボックスに Hardware.Info と入力して検索する。
- Hardware.Infoライブラリのインストール
- 検索結果からHardware.Infoライブラリを選択して、[インストール]ボタンを押下する。
- インストールの確認ダイアログが表示されるので、[OK]ボタンを押下してインストールを完了する。
- 参照の確認
- インストールが完了した後、プロジェクトの参照にHardware.Infoライブラリが追加されていることを確認する。
- パッケージマネージャーコンソールからインストールする場合
- プロジェクトを開く。
- [表示]メインメニュー - [その他のウィンドウ] - [パッケージマネージャーコンソール]を選択して、パッケージマネージャーコンソールを開く。
- パッケージマネージャーコンソールから、Hardware.Infoライブラリをダウンロードしてインストールする。
Install-Package Hardware.Info
- ソリューションエクスプローラーのプロジェクトの参照において、Hardware.Infoライブラリが追加されていることを確認する。
dotnet
コマンドを使用する場合- ターミナルを開く。
- プロジェクトのルートディレクトリに移動する。
- Hardware.Infoライブラリをインストールする。
- 最新の安定版をインストールする場合
dotnet add package Hardware.Info
- バージョンを指定してインストールする場合
dotnet add package Hardware.Info --version <バージョン>
- ※注意
- プロジェクトがGit等のバージョン管理システムを使用している場合、これらの変更がトラッキングされることを確認すること。
- プロジェクトを再ビルドして、新しく追加されたパッケージが正しく統合されていることを確認することを推奨する。
プロジェクトにおいて、Hardware.Infoライブラリを使用する場合は、ソースコードファイルの先頭にusingステートメントを追加する。
これにより、名前空間を使用することで、Hardware.Infoライブラリに関する主要な機能にアクセスすることができる。
using Hardware.Info;
使用例
以下の例では、CPU情報を取得している。
HardwareInfoクラスのtimeoutInWMIには、各クエリを実行するManagementObjectSearcherのEnumerationOptionsのTimeoutプロパティを設定する。
デフォルト値は、EnumerationOptions.InfiniteTimeoutである。
各ハードウェアコンポーネントには1つ以上のクエリが存在するため、RefreshAllメソッドでは16を超えるクエリが実行される。
クエリがタイムアウトに達すると、System.Management.ManagementException例外がスローされる。
ここで、例外クラスManagementExceptionのErrorCodeプロパティには、System.Management.ManagementStatus.Timedoutになる。
timeoutInWMIを設定する場合は、try-catchブロックを使用する必要がある。
using System;
using Hardware.Info;
class Program
{
static void Main()
{
IHardwareInfo hardwareInfo;
try
{
hardwareInfo = new HardwareInfo(timeoutInWMI: TimeSpan.FromMilliseconds(100));
hardwareInfo.RefreshAll();
}
catch (ManagementException ex) when (ex.ErrorCode == ManagementStatus.Timedout)
{
Console.WriteLine(ex);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
// CPUの情報のみを取得する場合
//IHardwareInfo hardwareInfo = new HardwareInfo();
//hardwareInfo.RefreshCPUList();
foreach (var cpu in hardwareInfo.CpuList)
{
Console.WriteLine($"CPU Name: {cpu.Name}");
Console.WriteLine($"Manufacturer: {cpu.Manufacturer}");
Console.WriteLine($"Caption: {cpu.Caption}");
Console.WriteLine($"Description: {cpu.Description}");
Console.WriteLine($"Number of Cores: {cpu.NumberOfCores}");
Console.WriteLine($"Number of Logical Processors: {cpu.NumberOfLogicalProcessors}");
Console.WriteLine($"L2 Cache Size: {cpu.L2CacheSize}");
Console.WriteLine($"L3 Cache Size: {cpu.L3CacheSize}");
Console.WriteLine($"Socket Designation: {cpu.SocketDesignation}");
Console.WriteLine($"Max Clock Speed: {cpu.MaxClockSpeed}");
}
}
}
ネットワークインターフェース
有線LAN
以下の例では、イーサネット (有線LAN) の情報を取得している。
- ネットワークアダプタの説明
- ネットワークアダプタの種類
- MACアドレス
- IPv4アドレス (存在する場合)
- 全てのIPv6アドレス (存在する場合)
IPv6アドレスには、一般的に、グローバルアドレス、リンクローカルアドレス、一時アドレス等、複数の種類が存在する可能性がある。
以下に示すサンプルコードでは、これら全てを表示している。
- まず、全てのネットワークインターフェースを取得する。
- イーサネット (有線LAN) インターフェースを検索して、稼働中のインターフェースが存在するかどうかを確認する。
- 存在する場合、そのインターフェースの情報を取得して表示する。
using System;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace GetWiredMACAddress;
class Program
{
public static void Main()
{
try {
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) {
// 稼働中のイーサネット (有線LAN) インターフェースの情報を検索
if (nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
nic.OperationalStatus == OperationalStatus.Up) {
Console.WriteLine($"ネットワークアダプタ: {nic.Description}");
Console.WriteLine($"アダプタの種類: {nic.NetworkInterfaceType}");
// 稼働中の有線LANのMACアドレスを取得して文字列形式に変換
// 表示形式は、16進数の大文字 (AA-BB-CC-DD-EE-FF)
PhysicalAddress mac = nic.GetPhysicalAddress();
string macAddress = BitConverter.ToString(mac.GetAddressBytes()).Replace("-", ":");
Console.WriteLine($"MACアドレス: {macAddress}");
// 稼働中の有線LANのIPアドレスを取得
var ipProperties = nic.GetIPProperties();
// 稼働中の有線LANのIPv4アドレスを取得
var ipv4Address = ipProperties.UnicastAddresses
.FirstOrDefault(addr => addr.Address.AddressFamily == AddressFamily.InterNetwork);
if (ipv4Address != null) {
Console.WriteLine($"IPv4アドレス: {ipv4Address.Address}");
}
else {
Console.WriteLine("IPv4アドレスが見つかりません。");
}
// 稼働中の有線LANのIPv6アドレスを取得
var ipv6Addresses = ipProperties.UnicastAddresses
.Where(addr => addr.Address.AddressFamily == AddressFamily.InterNetworkV6)
.Select(addr => addr.Address)
.ToList();
if (ipv6Addresses.Any()) {
Console.WriteLine("IPv6アドレス:");
foreach (var ipv6 in ipv6Addresses) {
Console.WriteLine($"{ipv6}");
}
}
else {
Console.WriteLine("IPv6アドレスが見つかりません。");
}
}
}
}
catch (Exception ex) {
Console.WriteLine($"エラーが発生しました: {ex.Message}");
}
}
}
無線LAN
以下の例では、無線LANの情報を取得している。
- ネットワークアダプタの説明
- ネットワークアダプタの種類
- MACアドレス
- IPv4アドレス (存在する場合)
- 全てのIPv6アドレス (存在する場合)
- SSID
- 信号強度
IPv6アドレスには、一般的に、グローバルアドレス、リンクローカルアドレス、一時アドレス等、複数の種類が存在する可能性がある。
以下に示すサンプルコードでは、これら全てを表示している。
- まず、全てのネットワークインターフェースを取得する。
- 無線LAN インターフェースを検索して、稼働中のインターフェースが存在するかどうかを確認する。
- 存在する場合、そのインターフェースの情報を取得して表示する。
SSIDと信号強度の取得は、使用するOSやライブラリにより実装方法が異なる。
そのため、以下に示すような方法を検討する必要がある。
- Windows
- Native Wi-Fi APIを使用する。
- または、Managed-Wifiライブラリを使用する。
- Linux
- /proc/net/wirelessファイルを読み込む、または、iwconfigコマンドの出力を解析する。
- あるいは、Tmds.DBusライブラリを使用して、NetworkManagerのD-Busを通じてWiFi情報にアクセスする。
- ただし、NetworkManagerへのアクセスに必要なため、root権限が必要な場合がある。
- プロジェクトにTmds.DBusライブラリを追加する場合は、NuGetパッケージを追加する。
dotnet add package Tmds.DBus
- MacOS
- CoreWLANフレームワークを使用する。
using System;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
using Tmds.DBus;
namespace GetWiredMACAddress;
class Program
{
public static void Main()
{
try {
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) {
// 稼働中のイーサネット (無線LAN) インターフェースの情報を検索
if (nic.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 &&
nic.OperationalStatus == OperationalStatus.Up) {
Console.WriteLine($"ネットワークアダプタ: {nic.Description}");
Console.WriteLine($"アダプタの種類: {nic.NetworkInterfaceType}");
// 稼働中の無線LANのMACアドレスを取得して文字列形式に変換
// 表示形式は、16進数の大文字 (AA-BB-CC-DD-EE-FF)
PhysicalAddress mac = nic.GetPhysicalAddress();
string macAddress = BitConverter.ToString(mac.GetAddressBytes()).Replace("-", ":");
Console.WriteLine($"MACアドレス: {macAddress}");
// 稼働中の無線LANのIPアドレスを取得
var ipProperties = nic.GetIPProperties();
// 稼働中の有線LANのIPv4アドレスを取得
var ipv4Address = ipProperties.UnicastAddresses
.FirstOrDefault(addr => addr.Address.AddressFamily == AddressFamily.InterNetwork);
if (ipv4Address != null) {
Console.WriteLine($"IPv4アドレス: {ipv4Address.Address}");
}
else {
Console.WriteLine("IPv4アドレスが見つかりません。");
}
// 稼働中の無線LANのIPv6アドレスを取得
var ipv6Addresses = ipProperties.UnicastAddresses
.Where(addr => addr.Address.AddressFamily == AddressFamily.InterNetworkV6)
.Select(addr => addr.Address)
.ToList();
if (ipv6Addresses.Any()) {
Console.WriteLine("IPv6アドレス:");
foreach (var ipv6 in ipv6Addresses) {
Console.WriteLine($"{ipv6}");
}
}
else {
Console.WriteLine("IPv6アドレスが見つかりません。");
}
// SSIDおよび信号強度の取得
var (ssid, strength) = await GetWifiInfo(nic.Name);
Console.WriteLine($"SSID: {ssid}");
Console.WriteLine($"信号強度: {strength}");
}
}
}
catch (Exception ex) {
Console.WriteLine($"エラーが発生しました: {ex.Message}");
}
}
// D-Busを使用してSSIDおよび信号強度を取得する
static async Task<(string ssid, int strength)> GetWifiInfo(string interfaceName)
{
var connection = Connection.System;
var nmManager = connection.CreateProxy<INetworkManager>("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager");
var devices = await nmManager.GetDevicesAsync();
foreach (var devicePath in devices) {
var device = connection.CreateProxy<IDevice>("org.freedesktop.NetworkManager", devicePath);
var deviceInterface = await device.GetInterfaceAsync();
if (deviceInterface == interfaceName) {
var wifiDevice = connection.CreateProxy<IWifiDevice>("org.freedesktop.NetworkManager", devicePath);
var activeAccessPoint = await wifiDevice.GetActiveAccessPointAsync();
if (activeAccessPoint != "/") {
var ap = connection.CreateProxy<IAccessPoint>("org.freedesktop.NetworkManager", activeAccessPoint);
var ssid = System.Text.Encoding.UTF8.GetString(await ap.GetSsidAsync());
var strength = await ap.GetStrengthAsync();
return (ssid, strength);
}
}
}
return ("Not connected", 0);
}
}
// Linux
// NetworkManagerのD-Busインターフェース名およびD-Busインターフェースメソッド
[DBusInterface("org.freedesktop.NetworkManager")]
interface INetworkManager
{
Task<ObjectPath[]> GetDevicesAsync();
}
[DBusInterface("org.freedesktop.NetworkManager.Device")]
interface IDevice
{
Task<string> GetInterfaceAsync();
}
[DBusInterface("org.freedesktop.NetworkManager.Device.Wireless")]
interface IWifiDevice
{
Task<ObjectPath> GetActiveAccessPointAsync();
}
[DBusInterface("org.freedesktop.NetworkManager.AccessPoint")]
interface IAccessPoint
{
Task<byte[]> GetSsidAsync();
Task<byte> GetStrengthAsync();
}