DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

電源の状態(ACかDCか、充電中か、バッテリー残量など)を取得する

ここでは、現在のシステムの電源状態(AC電源かDC電源か、充電中か、バッテリー残量はどの位かなど)を取得する方法を紹介します。

SystemInformation.PowerStatusプロパティを使用する方法

SystemInformationクラス(System.Windows.Forms名前空間)のPowerStatusプロパティを使用すると、電源状態を簡単に取得できます。このプロパティは、.NET Framework 2.0以降で使用できます。

以下に示すコードでは、AC電源に接続されている(オンライン)か否(オフライン)か、バッテリーの残量、残り時間などの情報を表示しています。

VB.NET
コードを隠すコードを選択
'Imports System.Windows.Forms

'AC電源の状態
Dim pls As PowerLineStatus = SystemInformation.PowerStatus.PowerLineStatus
Select Case pls
    Case PowerLineStatus.Offline
        Console.WriteLine("AC電源がオフラインです")
        Exit Select
    Case PowerLineStatus.Online
        Console.WriteLine("AC電源がオンラインです")
        Exit Select
    Case PowerLineStatus.Unknown
        Console.WriteLine("AC電源の状態は不明です")
        Exit Select
End Select

'バッテリーの充電状態を取得する
Dim bcs As BatteryChargeStatus = _
    SystemInformation.PowerStatus.BatteryChargeStatus
If bcs = BatteryChargeStatus.Unknown Then
    Console.WriteLine("不明です")
Else
    If (bcs And BatteryChargeStatus.High) = _
        BatteryChargeStatus.High Then
        Console.WriteLine("充電レベルは、高い(66%より上)です")
    End If
    If (bcs And BatteryChargeStatus.Low) = _
        BatteryChargeStatus.Low Then
        Console.WriteLine("充電レベルは、低い(33%未満)です")
    End If
    If (bcs And BatteryChargeStatus.Critical) = _
        BatteryChargeStatus.Critical Then
        Console.WriteLine("充電レベルは、最低(5%未満)です")
    End If
    If (bcs And BatteryChargeStatus.Charging) = _
        BatteryChargeStatus.Charging Then
        Console.WriteLine("充電中です")
    End If
    If (bcs And BatteryChargeStatus.NoSystemBattery) = _
        BatteryChargeStatus.NoSystemBattery Then
        Console.WriteLine("バッテリーが存在しません")
    End If
End If

'バッテリー残量(割合)
Dim blp As Single = SystemInformation.PowerStatus.BatteryLifePercent
Console.WriteLine("バッテリー残量は、{0}%です", blp * 100)

'バッテリー残量(時間)
Dim blr As Integer = SystemInformation.PowerStatus.BatteryLifeRemaining
If -1 < blr Then
    Console.WriteLine("バッテリー残り時間は、{0}秒です", blr)
Else
    'AC電源がオンラインの時など
    Console.WriteLine("バッテリー残り時間は、不明です")
End If

'バッテリーがフル充電された時の持ち時間(バッテリー駆動時間)
Dim bfl As Integer = SystemInformation.PowerStatus.BatteryFullLifetime
If -1 < bfl Then
    Console.WriteLine("バッテリー駆動時間は、{0}秒です", bfl)
Else
    Console.WriteLine("バッテリー駆動時間は、不明です")
End If
C#
コードを隠すコードを選択
//using System.Windows.Forms;

//AC電源の状態
PowerLineStatus pls = SystemInformation.PowerStatus.PowerLineStatus;
switch (pls)
{
    case PowerLineStatus.Offline:
        Console.WriteLine("AC電源がオフラインです");
        break;
    case PowerLineStatus.Online:
        Console.WriteLine("AC電源がオンラインです");
        break;
    case PowerLineStatus.Unknown:
        Console.WriteLine("AC電源の状態は不明です");
        break;
}

//バッテリーの充電状態を取得する
BatteryChargeStatus bcs =
    SystemInformation.PowerStatus.BatteryChargeStatus;
if (bcs == BatteryChargeStatus.Unknown)
{
    Console.WriteLine("不明です");
}
else
{
    if ((bcs & BatteryChargeStatus.High) ==
        BatteryChargeStatus.High)
    {
        Console.WriteLine("充電レベルは、高い(66%より上)です");
    }
    if ((bcs & BatteryChargeStatus.Low) ==
        BatteryChargeStatus.Low)
    {
        Console.WriteLine("充電レベルは、低い(33%未満)です");
    }
    if ((bcs & BatteryChargeStatus.Critical) ==
        BatteryChargeStatus.Critical)
    {
        Console.WriteLine("充電レベルは、最低(5%未満)です");
    }
    if ((bcs & BatteryChargeStatus.Charging) ==
        BatteryChargeStatus.Charging)
    {
        Console.WriteLine("充電中です");
    }
    if ((bcs & BatteryChargeStatus.NoSystemBattery) ==
        BatteryChargeStatus.NoSystemBattery)
    {
        Console.WriteLine("バッテリーが存在しません");
    }
}

//バッテリー残量(割合)
float blp = SystemInformation.PowerStatus.BatteryLifePercent;
Console.WriteLine("バッテリー残量は、{0}%です", blp * 100);

//バッテリー残量(時間)
int blr = SystemInformation.PowerStatus.BatteryLifeRemaining;
if (-1 < blr)
{
    Console.WriteLine("バッテリー残り時間は、{0}秒です", blr);
}
else
{
    //AC電源がオンラインの時など
    Console.WriteLine("バッテリー残り時間は、不明です");
}

//バッテリーがフル充電された時の持ち時間(バッテリー駆動時間)
int bfl = SystemInformation.PowerStatus.BatteryFullLifetime;
if (-1 < bfl)
{
    Console.WriteLine("バッテリー駆動時間は、{0}秒です", bfl);
}
else
{
    Console.WriteLine("バッテリー駆動時間は、不明です");
}

電源の状態が変化したことを知る

SystemEventsクラスPowerModeChangedイベントにより、電源やバッテリーの状態が変化したことを知ることができます。例えば、AC電源からバッテリーへの移行、バッテリー電圧の低下などによりイベントが発生します。PowerModeChangedイベントは、OSが中断状態(スタンバイ、サスペンド状態)になったり、中断状態から復帰した場合にも発生しますが、下に示す例のように、これらを区別することができます。

VB.NET
コードを隠すコードを選択
'フォームのLoadイベントハンドラ
Private Sub Form1_Load(ByVal sender As Object, _
        ByVal e As EventArgs) Handles MyBase.Load
    'イベントをイベント ハンドラに関連付ける
    'フォームコンストラクタなどの適当な位置に記述してもよい
    AddHandler Microsoft.Win32.SystemEvents.PowerModeChanged, _
        AddressOf SystemEvents_PowerModeChanged
End Sub

'フォームのFormClosedイベントハンドラ
Private Sub Form1_FormClosed(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.FormClosedEventArgs) _
        Handles MyBase.FormClosed
    'イベントを解放する
    'フォームDisposeメソッド内の基本クラスのDisposeメソッド呼び出しの前に
    '記述してもよい
    RemoveHandler Microsoft.Win32.SystemEvents.PowerModeChanged, _
        AddressOf SystemEvents_PowerModeChanged
End Sub

Private Sub SystemEvents_PowerModeChanged(ByVal sender As Object, _
        ByVal e As Microsoft.Win32.PowerModeChangedEventArgs)
    Select Case e.Mode
        Case Microsoft.Win32.PowerModes.StatusChange
            Console.WriteLine("電源の状態が変化しました。")
        Case Microsoft.Win32.PowerModes.Suspend
            Console.WriteLine("OSが中断状態になりました。")
        Case Microsoft.Win32.PowerModes.Resume
            Console.WriteLine("OSが中断状態から復帰しました。")
    End Select
End Sub
C#
コードを隠すコードを選択
//フォームのLoadイベントハンドラ
private void Form1_Load(object sender, EventArgs e)
{
    //イベントをイベント ハンドラに関連付ける
    //フォームコンストラクタなどの適当な位置に記述してもよい
    Microsoft.Win32.SystemEvents.PowerModeChanged +=
        new Microsoft.Win32.PowerModeChangedEventHandler(
            SystemEvents_PowerModeChanged);
}

//フォームのFormClosedイベントハンドラ
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    //イベントを解放する
    //フォームDisposeメソッド内の基本クラスのDisposeメソッド呼び出しの前に
    //記述してもよい
    Microsoft.Win32.SystemEvents.PowerModeChanged -=
        new Microsoft.Win32.PowerModeChangedEventHandler(
            SystemEvents_PowerModeChanged);
}

private void SystemEvents_PowerModeChanged(object sender,
    Microsoft.Win32.PowerModeChangedEventArgs e)
{
    switch (e.Mode)
    {
        case Microsoft.Win32.PowerModes.StatusChange:
            Console.WriteLine("電源の状態が変化しました。");
            break;
        case Microsoft.Win32.PowerModes.Suspend:
            Console.WriteLine("OSが中断状態になりました。");
            break;
        case Microsoft.Win32.PowerModes.Resume:
            Console.WriteLine("OSが中断状態から復帰しました。");
            break;
    }
}

GetSystemPowerStatus関数を使用する方法

Win32 APIのGetSystemPowerStatus functionを使用すると、SystemInformation.PowerStatusプロパティと同じ情報を取得することができます。

VB.NET
コードを隠すコードを選択
'Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential)> _
Public Structure SYSTEM_POWER_STATUS
    Public ACLineStatus As Byte
    Public BatteryFlag As Byte
    Public BatteryLifePercent As Byte
    Public Reserved1 As Byte
    Public BatteryLifeTime As Integer
    Public BatteryFullLifeTime As Integer
End Structure

<DllImport("kernel32.dll")> _
Private Shared Function GetSystemPowerStatus( _
    ByRef lpSystemPowerStatus As SYSTEM_POWER_STATUS) As Boolean
End Function

'Button1のClickイベントハンドラ
Private Sub Button1_Click(sender As Object, e As EventArgs) _
    Handles Button1.Click

    'システムの電源状態を取得する
    Dim sps As New SYSTEM_POWER_STATUS()
    GetSystemPowerStatus(sps)

    'AC電源の状態
    Select Case sps.ACLineStatus
        Case 0
            Console.WriteLine("AC電源がオフラインです")
            Exit Select
        Case 1
            Console.WriteLine("AC電源がオンラインです")
            Exit Select
        Case 255
            Console.WriteLine("AC電源の状態は不明です")
            Exit Select
    End Select

    'バッテリーの充電状態を取得する
    If sps.BatteryFlag = 255 Then
        Console.WriteLine("不明です")
    Else
        If (sps.BatteryFlag And 1) = 1 Then
            Console.WriteLine("充電レベルは、高い(66%より上)です")
        End If
        If (sps.BatteryFlag And 2) = 2 Then
            Console.WriteLine("充電レベルは、低い(33%未満)です")
        End If
        If (sps.BatteryFlag And 4) = 4 Then
            Console.WriteLine("充電レベルは、最低(5%未満)です")
        End If
        If (sps.BatteryFlag And 8) = 8 Then
            Console.WriteLine("充電中です")
        End If
        If (sps.BatteryFlag And 128) = 128 Then
            Console.WriteLine("バッテリーが存在しません")
        End If
    End If

    'バッテリー残量(%)
    If sps.BatteryLifePercent < 255 Then
        Console.WriteLine("バッテリー残量は、{0}%です", _
                          sps.BatteryLifePercent)
    Else
        Console.WriteLine("バッテリー残量は、不明です")
    End If

    'バッテリー残量(時間)
    If -1 < sps.BatteryLifeTime Then
        Console.WriteLine("バッテリー残り時間は、{0}秒です", _
                          sps.BatteryLifeTime)
    Else
        Console.WriteLine("バッテリー残り時間は、不明です")
    End If

    'バッテリーがフル充電された時の持ち時間(バッテリー駆動時間)
    If -1 < sps.BatteryFullLifeTime Then
        Console.WriteLine("バッテリー駆動時間は、{0}秒です", _
                          sps.BatteryFullLifeTime)
    Else
        Console.WriteLine("バッテリー駆動時間は、不明です")
    End If
End Sub
C#
コードを隠すコードを選択
//using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_POWER_STATUS
{
    public byte ACLineStatus;
    public byte BatteryFlag;
    public byte BatteryLifePercent;
    public byte Reserved1;
    public int BatteryLifeTime;
    public int BatteryFullLifeTime;
}

[DllImport("kernel32.dll")]
static extern bool GetSystemPowerStatus(
    out SYSTEM_POWER_STATUS lpSystemPowerStatus);

//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //システムの電源状態を取得する
    SYSTEM_POWER_STATUS sps = new SYSTEM_POWER_STATUS();
    GetSystemPowerStatus(out sps);

    //AC電源の状態
    switch (sps.ACLineStatus)
    {
        case 0:
            Console.WriteLine("AC電源がオフラインです");
            break;
        case 1:
            Console.WriteLine("AC電源がオンラインです");
            break;
        case 255:
            Console.WriteLine("AC電源の状態は不明です");
            break;
    }

    //バッテリーの充電状態を取得する
    if (sps.BatteryFlag == 255)
    {
        Console.WriteLine("不明です");
    }
    else
    {
        if ((sps.BatteryFlag & 1) == 1)
        {
            Console.WriteLine("充電レベルは、高い(66%より上)です");
        }
        if ((sps.BatteryFlag & 2) == 2)
        {
            Console.WriteLine("充電レベルは、低い(33%未満)です");
        }
        if ((sps.BatteryFlag & 4) == 4)
        {
            Console.WriteLine("充電レベルは、最低(5%未満)です");
        }
        if ((sps.BatteryFlag & 8) == 8)
        {
            Console.WriteLine("充電中です");
        }
        if ((sps.BatteryFlag & 128) == 128)
        {
            Console.WriteLine("バッテリーが存在しません");
        }
    }

    //バッテリー残量(%)
    if(sps.BatteryLifePercent < 255)
    {
        Console.WriteLine("バッテリー残量は、{0}%です",
            sps.BatteryLifePercent);
    }
    else
    {
        Console.WriteLine("バッテリー残量は、不明です");
    }

    //バッテリー残量(時間)
    if (-1 < sps.BatteryLifeTime)
    {
        Console.WriteLine("バッテリー残り時間は、{0}秒です",
            sps.BatteryLifeTime);
    }
    else
    {
        Console.WriteLine("バッテリー残り時間は、不明です");
    }

    //バッテリーがフル充電された時の持ち時間(バッテリー駆動時間)
    if (-1 < sps.BatteryFullLifeTime)
    {
        Console.WriteLine("バッテリー駆動時間は、{0}秒です",
            sps.BatteryFullLifeTime);
    }
    else
    {
        Console.WriteLine("バッテリー駆動時間は、不明です");
    }
}

WMIを使用する方法

WMIのWin32_Battery classを使用することで、バッテリーに関する様々な情報を取得することもできます。

以下のサンプルを実行するには、参照設定に「System.Management.dll」を追加する必要があります。その方法が分からないという場合は、「「○○○.dllを参照に追加します」の意味は?」をご覧ください。

VB.NET
コードを隠すコードを選択
'ManagementClassオブジェクトを作成する
Dim mc As New System.Management.ManagementClass("Win32_Battery")
'ManagementObjectCollectionオブジェクトを取得する
Dim moc As System.Management.ManagementObjectCollection = mc.GetInstances()
For Each mo As System.Management.ManagementObject In moc
    'バッテリーの情報を表示する
    '(ここで紹介しているのは、取得できる情報の一部です)
    '(すべての情報が必ず取得できるわけではありません)
    Console.WriteLine("名前:{0}", mo("Name"))
    Console.WriteLine("デバイスID:{0}", mo("DeviceID"))
    Console.WriteLine("説明:{0}", mo("Description"))
    Console.WriteLine("バッテリー残量:{0}%", mo("EstimatedChargeRemaining"))
    Console.WriteLine("バッテリー残り時間:{0}分", mo("EstimatedRunTime"))
    Console.WriteLine("設計容量:{0}mWh", mo("DesignCapacity"))
    Console.WriteLine("設計電圧:{0}mV", mo("DesignVoltage"))
    Console.WriteLine("フル充電容量:{0}mVh", mo("FullChargeCapacity"))
    Console.WriteLine("フル充電までにかかる時間:{0}分", mo("TimeToFullCharge"))
    Console.WriteLine("0からフル充電までにかかる時間:{0}分", mo("MaxRechargeTime"))
    Console.WriteLine("バッテリー使用時間:{0}秒", mo("TimeOnBattery"))

    Console.Write("バッテリーの状態:")
    Select Case DirectCast(mo("BatteryStatus"), UInt16)
        Case 1
            Console.WriteLine("放電中")
            Exit Select
        Case 2
            Console.WriteLine("AC電源")
            Exit Select
        Case 3
            Console.WriteLine("充電完了")
            Exit Select
        Case 4
            Console.WriteLine("低")
            Exit Select
        Case 5
            Console.WriteLine("最低")
            Exit Select
        Case 6
            Console.WriteLine("充電中")
            Exit Select
        Case 7
            Console.WriteLine("充電中/高")
            Exit Select
        Case 8
            Console.WriteLine("充電中/低")
            Exit Select
        Case 9
            Console.WriteLine("充電中/最低")
            Exit Select
        Case 10
            Console.WriteLine("未定義")
            Exit Select
        Case 11
            Console.WriteLine("一部充電")
            Exit Select
    End Select

    Console.Write("バッテリーの種類:")
    Select Case DirectCast(mo("Chemistry"), UInt16)
        Case 1
            Console.WriteLine("その他")
            Exit Select
        Case 2
            Console.WriteLine("不明")
            Exit Select
        Case 3
            Console.WriteLine("鉛蓄電池(鉛酸バッテリー)")
            Exit Select
        Case 4
            Console.WriteLine("ニッケル・カドミウム蓄電池(Ni-Cd)")
            Exit Select
        Case 5
            Console.WriteLine("ニッケル・水素充電池(Ni-MH)")
            Exit Select
        Case 6
            Console.WriteLine("リチウムイオン電池(LiB)")
            Exit Select
        Case 7
            Console.WriteLine("空気亜鉛電池")
            Exit Select
        Case 8
            Console.WriteLine("リチウムポリマー電池(Lipo)")
            Exit Select
    End Select
Next

'後始末
moc.Dispose()
mc.Dispose()
C#
コードを隠すコードを選択
//ManagementClassオブジェクトを作成する
System.Management.ManagementClass mc =
    new System.Management.ManagementClass("Win32_Battery");
//ManagementObjectCollectionオブジェクトを取得する
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
    //バッテリーの情報を表示する
    //(ここで紹介しているのは、取得できる情報の一部です)
    //(すべての情報が必ず取得できるわけではありません)
    Console.WriteLine("名前:{0}", mo["Name"]);
    Console.WriteLine("デバイスID:{0}", mo["DeviceID"]);
    Console.WriteLine("説明:{0}", mo["Description"]);
    Console.WriteLine("バッテリー残量:{0}%", mo["EstimatedChargeRemaining"]);
    Console.WriteLine("バッテリー残り時間:{0}分", mo["EstimatedRunTime"]);
    Console.WriteLine("設計容量:{0}mWh", mo["DesignCapacity"]);
    Console.WriteLine("設計電圧:{0}mV", mo["DesignVoltage"]);
    Console.WriteLine("フル充電容量:{0}mVh", mo["FullChargeCapacity"]);
    Console.WriteLine("フル充電までにかかる時間:{0}分", mo["TimeToFullCharge"]);
    Console.WriteLine("0からフル充電までにかかる時間:{0}分", mo["MaxRechargeTime"]);
    Console.WriteLine("バッテリー使用時間:{0}秒", mo["TimeOnBattery"]);

    Console.Write("バッテリーの状態:");
    switch ((UInt16)mo["BatteryStatus"])
    {
        case 1:
            Console.WriteLine("放電中");
            break;
        case 2:
            Console.WriteLine("AC電源");
            break;
        case 3:
            Console.WriteLine("充電完了");
            break;
        case 4:
            Console.WriteLine("低");
            break;
        case 5:
            Console.WriteLine("最低");
            break;
        case 6:
            Console.WriteLine("充電中");
            break;
        case 7:
            Console.WriteLine("充電中/高");
            break;
        case 8:
            Console.WriteLine("充電中/低");
            break;
        case 9:
            Console.WriteLine("充電中/最低");
            break;
        case 10:
            Console.WriteLine("未定義");
            break;
        case 11:
            Console.WriteLine("一部充電");
            break;
    }

    Console.Write("バッテリーの種類:");
    switch ((UInt16)mo["Chemistry"])
    {
        case 1:
            Console.WriteLine("その他");
            break;
        case 2:
            Console.WriteLine("不明");
            break;
        case 3:
            Console.WriteLine("鉛蓄電池(鉛酸バッテリー)");
            break;
        case 4:
            Console.WriteLine("ニッケル・カドミウム蓄電池(Ni-Cd)");
            break;
        case 5:
            Console.WriteLine("ニッケル・水素充電池(Ni-MH)");
            break;
        case 6:
            Console.WriteLine("リチウムイオン電池(LiB)");
            break;
        case 7:
            Console.WriteLine("空気亜鉛電池");
            break;
        case 8:
            Console.WriteLine("リチウムポリマー電池(Lipo)");
            break;
    }
}

//後始末
moc.Dispose();
mc.Dispose();
  • 履歴:
  • 2014/10/14 タイトルを変更。「SystemInformation.PowerStatusプロパティを使用する方法」で、サンプルを変更。「GetSystemPowerStatus関数を使用する方法」、「WMIを使用する方法」を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • 「???を参照に追加します」の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。