#author("2021-10-06T20:52:13+09:00","","")
#author("2021-10-06T20:53:26+09:00","","")
#navi(../)
* サスペンド前・復帰の時に処理を行いたい時のサンプルコード [#w0bbd1ef]
PCがサスペンドに入る前にネットワークを閉じたい、ファイルを一時保存しておきたいなどスリープ状態になる前に処理を実行したい。~
同様にスリープ復帰後に処理を行いたい場合のサンプルコードを以下に記します。

PowerModesのイベントによる処理になります。~
電源の抜き差し(ノートPCのAC電源駆動、バッテリ駆動の処理も実装してあります。

#contents
#htmlinsert(windev-top.html)

* 動作確認環境 [#m3091fa6]
- Windows 10 ver. 21H1
- Visual Studio 2019
- WPFアプリケーション
- .NET Framework 4.7.2

* ソリューションファイル [#hb030d07]
本記事で作成したソリューション(プロジェクト一式)は以下からダウンロードできます。
- ソシューション(プロジェクト一式)
#ref(SuspendResume.zip);

* 参考サイト [#r7725672]
- dobon.net~
電源の状態(ACかDCか、充電中か、バッテリー残量など)を取得する~
https://dobon.net/vb/dotnet/system/powerstatus.html
- 端末のスリープと復帰を検知する~
https://qiita.com/muro/items/96646280c0a6d398ca02

* 実行結果 [#s5efc169]
以下のキャプチャの通り、電源状態が変わった場合(今回はAC駆動、バッテリ駆動のみ判定)、スリープ前、スリープから復帰時にTextBlockに~
時間とメッセージを追記しています。~
スリープ前、スリープ復帰時にメッセージが追記されているのができます。~
AC ON|OFF Line はノートPCから電源ケーブルを抜き差しすると出力されます。
#ref(01.png) 

* サンプルコード [#g8ad412a]
* C# サンプルコード [#g8ad412a]
サンプルコードは、上記参考サイトを利用させて頂き追記しました。~
WPFのため、SystemInformation.PowerStatusは使えず(System.Windows.Formsのため)、UWPのWindows.Devices.Powerを使うための設定も面倒なので、~
DllImportによりGetSystemPowerStatusを使う方法で、AC駆動、バッテリ駆動を判別しています。

以下、追記・修正したファイルのみとなります。

** MainWindow.xaml [#t5ce2792]
 <Window x:Class="SuspendResume.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:SuspendResume"
         mc:Ignorable="d"
         Title="MainWindow" Height="400" Width="400">
     <Grid>
         <TextBlock Name="MsgTxtBlk" />
     </Grid>
 </Window>


** MainWindow.xaml.cs [#yd0de3ab]
 using Microsoft.Win32;
 using System;
 using System.Runtime.InteropServices;
 using System.Windows;
 
 namespace SuspendResume
 {
     public partial class MainWindow : Window
     {
         public MainWindow()
         {
             InitializeComponent();
             MsgTxtBlk.Text = "Start" + Environment.NewLine; ;
             MonitorPowerModes();
         }
 
         private void MonitorPowerModes()
         {
             SystemEvents.PowerModeChanged += (sender, e) =>
             {
                 string nowTime = DateTime.Now.ToString("HH:mm:ss");
 
                 switch (e.Mode)
                 {
                     case PowerModes.Suspend:
                         MsgTxtBlk.Text += nowTime + " - Suspend" + Environment.NewLine;
                         break;
                     case PowerModes.Resume:
                         MsgTxtBlk.Text += nowTime + " - Resume" + Environment.NewLine;
                         break;
                     case PowerModes.StatusChange:
                         MsgTxtBlk.Text += nowTime + " - " + ACLineStatusMsg() + Environment.NewLine;
                         break;
                     default:
                         MsgTxtBlk.Text += nowTime + " - Unknown" + Environment.NewLine;
                         break;
                 }
             };
         }
 
         [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);
 
         private string ACLineStatusMsg()
         {
             SYSTEM_POWER_STATUS sps = new SYSTEM_POWER_STATUS();
             _ = GetSystemPowerStatus(out sps);
 
             string msg = "";
 
             switch (sps.ACLineStatus)
             {
                 case 0:
                     msg = "AC OFF line.";
                     break;
                 case 1:
                     msg = "AC ON line.";
                     break;
                 case 255:
                 default:
                     msg = "Unknown.";
                     break;
             }
             return msg;
         }
     }
 }

以上、サスペンド前、サスペンド復帰時に処理を記述する方法でした。

#htmlinsert(windev-btm.html)

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS