2024年5月24日金曜日

TvRockの予約録画時のスリープからの復帰方法について

 いまさらTvRockかとお呆れのかたもございましょうが、お許しください。

(成果物だけほしい方向け: `tvrock.schから補正'版はこちら、`TvRock単体で動作`版はこちらです)

表題の件ですが、タスクスケジューラとそれ以外があります。そして、今回はそれ以外のほうのお話をさせていただきます。

その前に、まず小ネタから。

0.9t8ではTvRockDTV.x64.dllがないためにTvTestとかTSTaskの64bit版が動かないとお嘆きの方に。実は0.9u2で生成させたTvRockDTV.x64.dllをそのまま保持しておいて0.9t8に戻せばTvTestやTSTaskの64bit版が使えます。

他は64bit化したものの、TvRockだけはどうにも余人を以て代え難く、しかし0.9u2はTvRockがOSのスリープを(powercfg /requestsoverrideしてしまわない限り)阻止し続けるので使いたくないという方向けのニッチすぎる情報でした。

さて、TvRockで録画を予約するときに「復帰処理をタスクスケジューラで行う」にチェックボックスを入れていなくてもきちんとスリープから復帰して録画が開始されますが、powercfg /waketimersを行ってもスリープ状態の解除タイマーはありません。

以前から気になっていたのですが、今回こんなネタを知ったのでスリープからの復帰時間の補正をするツールを書くついでにだいたい見当はつくけど確かめてみようということでghidraを用いてバイナリを紐解いてみました。

思った通りWM_POWERBROADCASTを受けたときにwParamがPBT_APMSUSPENDのとき、つまりスリープに入る直前にSetWaitableTimerして、レジュームした直後(PBT_APMRESUMEAUTOMATIC)にCancelしてました。

そのため、普段はpowercfg /waketimersを行っても見えません。普段は登録されていないのですから当たり前です。

ここで、先のACPI Wake Alarmによる遅延のために何とかしたいとする場合は、予約前の準備時間以上スリープしないようにシステムを設定しておくのが無難でしょう。

あえてプログラムを書こうという場合、いくつかアプローチがありますが、私はtvrockと同様にWM_POWERBROADCASTでPBT_APMSUSPENDを受けたときにtvrock.schから現在時刻からの直近で4時間以上未来の録画予約があれば予想遅延時間を引いた時刻でwaitable timerを設定しています。この方法だとPBT_APMSUSPENDをもらってから2秒以内にすべてを終わらせる必要があるのでCで書きました

でもこれは物好きだからやっているだけで、普段からtvrock.schを監視しておいて、変更されたらschtasksコマンドやpowershellを使ってタスクスケジューラ経由でスリープを解除させる方法が簡単だと思います。TvRock.exeではTvRock.schを開く際はCreateFile()で排他しているので書き込み中にリードしたりといった事故は起きないと思います。

ちなみにtvrock.schのSTARTはunix epochなJSTです。

tvrockを卒業することになるかと思いきや、解決策が見つかってしまったのでまだまだ使い続けることになりそうです。やっといてなんですが、もう録画してまで見るものがないのでした。

最後で恐縮ですが、TvRock, TvTest, RecTest, TSTask, Spinel, BonDriverProxyEx, BonDriver_PT3-ST, pt2wdm の作者様方のみならず、多くの関係者の方に心から感謝しています。

以上、このような駄文を読ませてしまい、誠に申し訳ございませんでした。

0 件のコメント:

コメントを投稿