Windows10
GPDPocket

GPD Pocket(Windows版)用に作ったツールについて

はじめに

この投稿は、GPD Pocket Advent Calendar 2017 23日目の投稿です。

GPD Pocketという小型ノートPC向けに、下記のツールを作りました(`・ω・´)
(ちなみに、若干放置気味ですがWikiも作りました。)

  • Pocket Fan Controller
    → GPD Pocketのファン回転数を手動で設定できるツール
  • CPU Power Limiter
    → CPU使用率の上限を設定し、バッテリー消費を抑えられるツール

この投稿では、各ツールが内部で何をしているのかについてご説明します。

各ツールの内部処理

Pocket Fan Controller

GitHub: https://github.com/t-miyake/PocketFanController/

前提知識

GPD Pocketでは、下記レジストリにファンに関する設定が保存されてます。

SYSTEM\CurrentControlSet\Services\wfan0109

設定項目は下記の4つです。
※ファンのスピードは4段階で変化するようになっています。
(以降「最低速、低速、高速、最高速」 と呼びます)

  • margin:正確に挙動を理解していませんが、読んで字のごとくマージンだと思います。
  • t0:低速でファンを回転させ始める温度
  • t1:高速でファンを回転させ始める温度
  • t2:最高速でファンを回転させ始める温度

なお、t0で設定された温度未満の場合、最低速でファンが動作します。

Pocket Fan Controllerの内部処理

処理は下記の通りとてもシンプルです。

  1. 上記のレジストリの内容を書き換える。
  2. ファンをコントロールしているサービスを強制的に再起動する。

コードを見てみる

処理をしている箇所の抜粋です。
こんな感じで、無理やり設定を変更することで、
ファンの回転スピードを手動で調整できるようにしています。

    //★ファンのスピードを高速に設定している箇所
    public void SetFast()
    {
        WriteReg(@"SYSTEM\CurrentControlSet\Services\wfan0109", "margin", 5);
        WriteReg(@"SYSTEM\CurrentControlSet\Services\wfan0109", "t0", 99);
        WriteReg(@"SYSTEM\CurrentControlSet\Services\wfan0109", "t1", 10);
        WriteReg(@"SYSTEM\CurrentControlSet\Services\wfan0109", "t2", 99);
        RestartService();
    }

    //★レジストリに書き込むメソッド
    public void WriteReg(string subKey, string keyName, int value)
    {
        var key = Registry.LocalMachine.CreateSubKey(subKey);
        key?.SetValue(keyName, value, RegistryValueKind.DWord);
        key?.Close();
    }

    // ★ファンをコントロールしているサービスの強制再起動
    public void RestartService()
    {
        //サービスを停止したり再起動できないので、exeをkillする
        var oldProcesses = Process.GetProcessesByName("FanMonitorService");
        foreach (var p in oldProcesses)
        {
            p.Kill();
        }

        //サービスのスタートがアプリ側からできないので、コマンドプロンプトからスタートさせる
        var cmd = new Process
        {
            StartInfo =
            {
                FileName = Environment.GetEnvironmentVariable("ComSpec"),
                CreateNoWindow = true,
                UseShellExecute = false,
                Arguments = @"/c net start ""Fan Monitor"""
            }
        };
        cmd.Start();
    }

CPU Power Limiter

GitHub: https://github.com/t-miyake/CpuPowerLimiter
※Windows PCであれば、何でも動くと思います。

前提知識

Windowsでは、電源オプションとして設定可能な項目が多くあります。
ただし、そのほとんどが、GUIから変更できないようになっています。

それらの設定項目は、レジストリを個別に編集してGUIから編集可能にするか、
Powercfg コマンドを使用することで、設定内容を変更することができます。

CPU使用率の上限値や、ターボブーストの可否についても、
電源オプションの設定項目の一つとして設定が可能です。

CPU Power Limiterの内部処理

とてもシンプルです。
Powercfg コマンドを実行して、設定を変更しているだけです。
※CPU使用率の上限を設定すると同時に、ターボブーストも無効化するようにしています。

コードを見てみる

    public void SetSettings(int cpuLimitPercentage,int turboBoostParam)
    {
        var currentPowerSchemes = ReadReg(@"SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes", "ActivePowerScheme");

        var cmd = new Process
        {
            StartInfo =
            {
                FileName = Environment.GetEnvironmentVariable("ComSpec"),
                CreateNoWindow = true,
                UseShellExecute = false,
                Arguments = $@"/c powercfg -setacvalueindex {currentPowerSchemes} 54533251-82be-4824-96c1-47b60b740d00 bc5038f7-23e0-4960-96da-33abaf5935ec {cpuLimitPercentage} & powercfg -setdcvalueindex {currentPowerSchemes} 54533251-82be-4824-96c1-47b60b740d00 bc5038f7-23e0-4960-96da-33abaf5935ec {cpuLimitPercentage} & powercfg -setacvalueindex {currentPowerSchemes} 54533251-82be-4824-96c1-47b60b740d00 be337238-0d82-4146-a960-4f3749d470c7 {turboBoostParam} & powercfg -setdcvalueindex {currentPowerSchemes} 54533251-82be-4824-96c1-47b60b740d00 be337238-0d82-4146-a960-4f3749d470c7 {turboBoostParam} & Powercfg -setactive {currentPowerSchemes}"
            }
        };
        cmd.Start();
    }

おわりに

シンプルな処理でも、手作業だとちょっと手間がかかってしまいます。
そういったものは、簡単なツールにすることで、色々と楽になりますね!(∩´∀`)∩

せっかくなので、GPD Pocketのユーザさんは是非ご利用ください―