world2018/03/21MonitorianとWifinianしばらく前にMonitarianとWifinianをWindowsストアでリリースしました。どちらもWindows用で、OSの機能で行けてないところ(モニターの明るさ調整、Wi-Fi設定)を補完するものです。Bridgeを利用してストアに出しています。これらの使い方自体は、そんなに難しくないと思うので、開発について簡単に説明しておきます。10のアップデートでアクションセンターにモニターの明るさ調整のスライダーが入るらしいと書きましたが、これまでのところは入っていません。環境光センサーとSurfaceMonitorianの設定中の「調整後の明るさを表示する」は、このエントリで触れた問題に対応するもので、(環境光センサーがある場合に)設定値に加えて実際の調整後の値も表示することで、設定を多少やりやすくします。IDをキーに使って統合して利用しています。少々面倒なことに、それぞれに含まれる機能が断片的なので、統合しないと必要な機能が揃わないのですよね。外部モニターについては、DDC/CIが有効であることが条件ですが、これはモニターとその設定によるので、開発側としてはどうしようもありません。この問題に引っ掛かったらしきレビューが付いてますが、必要条件には初めから書いてあるので。一応、それと直接表示する機能を追加しました。名前については、昔アプリには機能が分かりやすい名前を付けるべしという話を読んだことがあって、それを考慮していたこともありますが、そんなお行儀にこだわる必要などないと悟ったので、造語しています。Wifiを利用するアプリから機能を強化・リファインの上、改名したものです。Switchの設定に合わせて自動的に介入して接続先を切り変える機能(Engage)を付けた、というのが主な違いです。8以降で簡略化されたものを、再び使えるようにしたことになります。この辺はMicrosoftのデザイン上の判断で、「Wi-Fiセンサー」の顛末も見るに、ユーザーはWi-Fiに繋がりさえすれば何だって気にしないだろうという判断があったものと想像しますが、まあ実際そうかもとは思いつつ、ユーザーの意図で決めたい場合もあるので。Wifiを強化し、WlanClientを保持してWi-Fiの状態変化を監視できるようにしています。引き続きReactivePropertyを使わせていただいてます。その点で再確認した注意事項は、ReactiveCommandに繋げる前にはUIスレッドに戻しておけということです。名前については、同上。Wifiの後は語感です。ScreenFrameタスクバーの通知領域にアイコンを出しつつ、タスクバーに引っ付いたウィンドウと通知領域アイコンに重なるウィンドウを(NotifyIconのContextMenuと同じ位置に)出すためのライブラリです。Wifinianの前のアプリで開発したものをベースに、Monitorian用に開発し、後にWifinian用に拡充しています。Wifinianではウィンドウのタスクバーからの脱着ができるようになっています。このコードの肝は、WM_WINDOWPOSCHANGINGメッセージに引っ掛けてウィンドウのサイズ・位置調整をすること。これにより、ウィンドウのサイズ・位置変更を全て捕捉し、状態に応じてそのWINDOWPOSを改変することでサイズ・位置変更に自然に介入できる。NotifyIcon中のNativeWindowへのWM_DPICHANGEDメッセージを監視することで、通知領域のあるスクリーンのDPI変化を捕捉すること。マルチモニター環境で通知領域アイコンのあるスクリーンのDPI変化をどう検知するかが課題になっていたが、これによりそのスクリーンにウィンドウがない場合でも検知できる。NativeWindowへのウィンドウメッセージ監視は、そもそもNotifyIconがそうしていることに倣ったもの。ちなみに、非公開メンバーにReflectionでアクセスしている部分がありますが、もはやほとんど開発は行われていないだろうし、実際上、気にする必要はないだろうと。NotifyIconがWinFormsだという点は、それを避けてWin32を直接使うよりマネージドの方がましです。いえば、先日、LGの42.5インチのモニターの実物を見てきましたが、広すぎてスクリーンの端に付いたタスクバーを起点とするUIにはもう無理があると感じました。このサイズのモニターが普及価格帯に入っていますが、Microsoftはどうする気ですかね。StartupAgency/StartupBridge常駐アプリとして必要な自動起動のためのライブラリがStartupAgencyです。自動起動の方法は幾つかありますが、コード的に一番簡単なのはレジストリに登録することで、インストーラによるアンインストールで掃除できることを前提にすれば、それで十分なのでその方法を取っています。Bridgeの場合はその方法ではダメで、UWPのStartupTaskを使う必要があるので、そのための別ライブラリがStartupBridgeという構成になっています。Bridge問題は、これによる自動起動とユーザーによる手動起動をどう判別するかで(自動起動のときはウィンドウを出さないようにしたい)、自動起動のときにArgumentsを付けることができれば簡単ですが、StartupTaskでこれをやる方法が見つかりませんでした。代替策として、完全な方法ではないですが、アプリの起動時間を記録するようにし、自動起動が有効な場合に、起動時に前回の起動時間とOSの起動時間(セッション開始時間)を比較して前者の方が前であれば自動起動と判断する方法を考えましたが、どこに記録するかという選択が残ります。この記録には、ライブラリのモジュール性を高めたかったので、UWPのLocalSettingsを使うようにしました。Bridgeの場合は実はこの手が使えます。いっても、TaskIdはAppxManifest.xmlのものと一致する必要があるので、そこのアプリ本体への依存は避けられませんが。Converterのやり方に慣れたので、そちらを使っています。面倒な画像作成を自動でやってくれます(ただし、サイズが妙に奇数なので、輪郭がぼける)。コマンドはメモしておいてPowerShellに張ればいいので、さほどには。このパッケージ作成を14393より新しいバージョンでやりつつ(BaseImageのバージョンは実際のOSのバージョンと一致している必要がある)最低動作バージョンを14393としておくことは可能で、パッケージ作成のためだけに14393の環境を維持する必要はありません。一応、14393のときのISOで環境を作って動作確認はしましたが。Bridgeでインストールしたアプリには、UWP同様に以下のパスに専用フォルダーが作成されるので、この中を探せばAppDataに作成したファイルを直接見ることは可能です。name]\AppData\Local\PackagesWindowsストアに出すことのメリットは、正直それだけで認知度が上がる感じではないですが、クラッシュ報告が自動的に集計されてくるのは参考になります。Bridgeはまだ専用窓口から申し込んでMicrosoftの担当者とのやり取りを経てから通常のストア申請に移る方式でした。その担当者は現在は既に日本Microsoftの方になっています。Communitywww.flickr.comコメントについてコメントは承認制です。承認まで時間がかかるときがあります。感想、間違いの指摘など歓迎します。間違いについては、その場所と内容を明記してください。エントリと関係がないもの、不適当と思われるものは承認しません。プロフィールEMOGitHub詳しくないプロフィール当てにならないカスタマイズ。