📌
Powershellで電源をチェックできる関数を実装する
Powershellに電源を確認するコマンドレットは無いです。
よって、windowsのcuiで簡単に電源を確認する方法はありません!
困りましたね。
ということで実装しましょう。
今現在、dotnetに電源の状態を取得する方法が実装されていないので、csharpからC++のwin32apiの
関数を呼び出し、そのcsharpのソースコードをPowershellから読み込み、型定義を行うことによって、
Powershellに関数の定義を行います。
一応、最近できたcsharpからwin32を実行するためのCsWin32というライブラリを使うこともできますが、ビルドする必要があるうえ、dotnet 5.0以上縛りがあり、Powershell7.2以上でないと動作できない関数になります。
GetSystemPowerStatusの定義は
ここにあるのでそれを参考にcsharp側にC++と同じ作りの構造体を作り上げ、その構造体を参照渡しすることで実現できます。
Kernel32Dll.cs
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct LPSYSTEM_POWER_STATUS {
public byte ACLineStatus;
public byte BatteryFlag;
public byte BatteryLifePercent;
public byte SystemStatusFlag;
public uint BatteryLifeTime;
public uint BatteryFullLifeTime;
}
public class Kernel32Dll {
[DllImport("Kernel32.dll")]
private static extern int GetSystemPowerStatus(ref LPSYSTEM_POWER_STATUS lPSYSTEM_POWER_STATUS);
public static LPSYSTEM_POWER_STATUS GetSystemPowerStatus() {
var power_status= new LPSYSTEM_POWER_STATUS();
var result = GetSystemPowerStatus(ref power_status);
return power_status;
}
}
このcsharpのソースコードを下のように読み込み実行すると、
Powershellから電源の情報を取得できるようになります。
$src = Get-Content Kernel32Dll.cs -Raw
# C++のDLLをインポート
Add-Type -TypeDefinition $src
# DLL内の関数を呼び出し
[Kernel32Dll]::GetSystemPowerStatus()
モジュールにする場合
モジュールにする場合は下記のようにします。
下記のKernel32dll.csと同じフォルダに入れてください。
GetSystemPowerStatus.ps1
$path = (Split-Path $MyInvocation.MyCommand.Path -Parent)
$src = Get-Content (Join-Path $path Kernel32Dll.cs) -Raw
# C++のDLLをインポート
Add-Type -TypeDefinition $src
function Get-SystemPowerStatus {
param(
)
# DLL内の関数を呼び出し
[Kernel32Dll]::GetSystemPowerStatus()
}
このモジュールをImportするとGet-SystemPowerStatusから電源の情報を取得できるようになります。
Import-Module path/to/GetSystemPowerStatus.ps1
Get-SystemPowerStatus
まとめ
C++の基礎がわからんとキツイ気もしますが、何とかなることが分かったと思います。
このソースコードはpowershell5系列でも、最新のdotnet core系のPowershellでも正しく動きます。
Discussion