audio-technicaの軟骨伝導ヘッドホンの新モデルATH-CC500BT2が出ていたので、チェック。
性能面は旧モデルATH-CC500BTからよくなっているだろうから心配してなくて、自分の関心はデザインとフィット感。
旧モデル(上)はShokzなどの既存の骨伝導ヘッドホンとはあえて違う形状を目指した感があったが、新モデル(下)は既存製品に近い形状になっている。
旧モデルはスピーカー部(振動ドライバー)が妙に丸っこく膨らんだ形で、謎のエングレーブが入っていたりして、ここはあまり好きではなかったが、新モデルは小さくすっきりした形になっている。
旧モデルではスピーカー部にボタンとマイク穴(左側)があって、開発陣は、ボタンはここに置いた方が直感的で、マイク穴も口に近い方がよいと考えたのだろうけど、これらをつるに移動させたのは、ボタンは音量ボタンと同じ位置の方がむしろ操作しやすく(オーバーヘッド型ヘッドホンではそうしている)、マイク穴はつるでも声は十分拾えると考えたのだろうと思う(想像)。
振動ドライバーが耳珠に接触する面積は、旧モデルは形状の関係で意外と小さく、新モデルの方が大きいので、位置調整できる幅は大きい。
フィット感については、自分の頭へのフィット感は確実によくなっている。総じて順当な進化なので、旧モデルもまだ十分使えるので惜しくはあるが、買換えに値すると思う。
2025/01/25
2023/04/14
インストールされたアプリの情報取得
別に新しくも何ともないですが、パッケージされたアプリをインストールした後、登録された情報はPowerShellで簡単に確認できます。
PowerShellコンソールから以下です。
これをファイルに記録するには、デスクトップにpackages.txtというファイル名で保存するとして、こうです。
ちなみに、UWPをVisual StudioからLocal Machineで実行したときに自動インストールされたものは、IsDevelopmentModeがTrueになるようです。
PowerShellコンソールから以下です。
Get-AppxPackage
これをファイルに記録するには、デスクトップにpackages.txtというファイル名で保存するとして、こうです。
Get-AppxPackage > $env:USERPROFILE/Desktop/packages.txt
ちなみに、UWPをVisual StudioからLocal Machineで実行したときに自動インストールされたものは、IsDevelopmentModeがTrueになるようです。
2022/11/30
パッケージされたアプリのファイルの保存場所
AppDataフォルダーへのファイル作成について、発見があったのでメモしておきます。
1. 基本
Microsoftストア用にパッケージされたデスクトップアプリの場合、設定情報等の保存場所としては基本的に以下の3通りがあります。
これらのファイルはアプリのアンインストール時に自動的に削除されます。つまり、アプリの実行ファイルのみならず、その作成する情報・ファイルもOSがまとめて管理することで、ゴミとなるファイルを残さずきれいに削除できるようにしているわけです。
ちなみに、AppDataフォルダー以外にもアクセス権に応じてファイルは作成できますが、あえてやることでもなし。
2. 発見
ここまではDesktop Bridgeの基本ですが、3番目について、ふとしたことから例外があるのに気づきました。
1. 基本
Microsoftストア用にパッケージされたデスクトップアプリの場合、設定情報等の保存場所としては基本的に以下の3通りがあります。
- WinRTのApplicationData.LocalSettings
- WinRTのApplicationData.LocalFolderに作成したファイル
- AppDataフォルダー(に作成したフォルダー)に作成したファイル
これらのファイルはアプリのアンインストール時に自動的に削除されます。つまり、アプリの実行ファイルのみならず、その作成する情報・ファイルもOSがまとめて管理することで、ゴミとなるファイルを残さずきれいに削除できるようにしているわけです。
ちなみに、AppDataフォルダー以外にもアクセス権に応じてファイルは作成できますが、あえてやることでもなし。
2. 発見
ここまではDesktop Bridgeの基本ですが、3番目について、ふとしたことから例外があるのに気づきました。
すなわち、アプリをインストールした後、最初にAppDataフォルダーにファイルを作成しようとした際に、
- AppDataフォルダーに指定のフォルダーが存在しない場合、自動的にリダイレクト先の場所が作成され、以後のアクセスはその場所になる。実際のAppDataフォルダーには何も作成されない。これは公式情報どおり。
- AddDataフォルダーに指定と同名のフォルダーが既に存在する場合、そのフォルダーにファイルが作成される。このファイルはアプリをアンインストールしても削除されない。
この2通りのどちらになるかは、最初にアクセスしたときに決まるようです。一旦、1.になった後は、AppDataフォルダーに同名のフォルダーを作成しても、ファイルはそこに作成されません。
開発環境では、パッケージされた状態で実行するときもあれば、されていない状態で実行するときもあり、2.のようなケースがあるのには何となく気づいていましたが、改めて確認したところ、こういうことだったと。
これがどういう意味を持つかというと、例えば、ユーザーごとのTempフォルダーであるAppData\Local\Tempに作成するファイルはリダイレクトされないし、作成された後はアプリをアンインストールしても自動的に削除されないということになります。
他人のことはあまり言えませんが、説明が足らないと思います。
2022/06/06
Razer Pro Click Mini
ゲーミングマウスの性能で高速スクロール可能なモバイルマウスがほしいという願望がずっとあって、サブに使っていたMX AnyWhere 2Sの買い替えを機に、Razer Pro Click Miniを買ってきた。
エクステリアデザインはエクセレント。Logicoolのモバイルマウスの最上位ラインはちょこちょこデザインを変えてきているが、「こういうのでいいんだよ」をとてもきれいにまとめた感じ。一応チェックした大きい方のRazer Pro Clickは縁にクロームのラインをあしらっているが、別にそういうのは要らない。
製品としては明らかにMX AnyWhere 3の対抗馬で、バッテリーが固定内蔵でないのが違うが、重量は単3一本の状態で実測でほぼ同じ(4g軽い)なので、使用上は大きな違いはない。単4一本にすればさらに軽くできる。
ちなみに、上面蓋をどう固定しているのかと思ったら、本体の最後部にマグネットが仕込んであって、それで蓋のネジを引き付ける仕組みになっていた。したがって、爪が折れたりする心配とは無縁だが、机から落としたりすると簡単に外れて飛んでいくので、それはそれで注意が必要かも。
追随性とかは自分には正直差が分からないので、確認点はクリック音とホイールの回転。
Pro Click Miniはクリック音が小さいのを売りの一つにしているが、確かに小さい。擬音的には、「カチッ」というより、小さく「ポクッ」という感じで、音が小さくかつ低音なので響かない。まあこれは、むしろLogicoolがMX AnyWhereのラインで重視していないのが謎な点ではある。
まずフリーホイールとの切り替えはホイール手前のシーソースイッチで行うが、これが少し硬い。ただ、自分は常にフリーホイールで使うので(TrackPointで鍛えられた人間なので、ノッチに頼らなくても支障はない)、むしろ勝手に変わらなくてよい。
ホイールにはラバーに四角錐が5個並んだ滑り止めが施されている。
肝心のホイールの回転については、MX AnyWhere 3の極まったホイール(無音・無抵抗で、ブレもなく、とてもよく回る)に比べると、回転音がしてかすかにブレがある分、少し劣ると言わざるを得ない。シフトスイッチのあるMX AnyWhere 2Sよりも劣るので、この点はLogicoolに一日の長があるのだろうと思う。
ただ、これは極まったMX Anywhere 3と比べての話で、実用上の問題はない。
結論としては、クリック音の小ささではPro Click Miniに、ホイールの回転ではMX AnyWhere 3に軍配が上がる。どちらも使い倒すけど。
エクステリアデザインはエクセレント。Logicoolのモバイルマウスの最上位ラインはちょこちょこデザインを変えてきているが、「こういうのでいいんだよ」をとてもきれいにまとめた感じ。一応チェックした大きい方のRazer Pro Clickは縁にクロームのラインをあしらっているが、別にそういうのは要らない。
製品としては明らかにMX AnyWhere 3の対抗馬で、バッテリーが固定内蔵でないのが違うが、重量は単3一本の状態で実測でほぼ同じ(4g軽い)なので、使用上は大きな違いはない。単4一本にすればさらに軽くできる。
- Pro Click Mini: 92g(単3一本)
- Pro Click Mini: 81g(単4一本アダプター込み)
- MX AnyWhere 3: 96g
ちなみに、上面蓋をどう固定しているのかと思ったら、本体の最後部にマグネットが仕込んであって、それで蓋のネジを引き付ける仕組みになっていた。したがって、爪が折れたりする心配とは無縁だが、机から落としたりすると簡単に外れて飛んでいくので、それはそれで注意が必要かも。
追随性とかは自分には正直差が分からないので、確認点はクリック音とホイールの回転。
クリック音
Pro Click Miniはクリック音が小さいのを売りの一つにしているが、確かに小さい。擬音的には、「カチッ」というより、小さく「ポクッ」という感じで、音が小さくかつ低音なので響かない。まあこれは、むしろLogicoolがMX AnyWhereのラインで重視していないのが謎な点ではある。
ホイール
まずフリーホイールとの切り替えはホイール手前のシーソースイッチで行うが、これが少し硬い。ただ、自分は常にフリーホイールで使うので(TrackPointで鍛えられた人間なので、ノッチに頼らなくても支障はない)、むしろ勝手に変わらなくてよい。
ホイールにはラバーに四角錐が5個並んだ滑り止めが施されている。
肝心のホイールの回転については、MX AnyWhere 3の極まったホイール(無音・無抵抗で、ブレもなく、とてもよく回る)に比べると、回転音がしてかすかにブレがある分、少し劣ると言わざるを得ない。シフトスイッチのあるMX AnyWhere 2Sよりも劣るので、この点はLogicoolに一日の長があるのだろうと思う。
ただ、これは極まったMX Anywhere 3と比べての話で、実用上の問題はない。
まとめ
結論としては、クリック音の小ささではPro Click Miniに、ホイールの回転ではMX AnyWhere 3に軍配が上がる。どちらも使い倒すけど。
2022/06/03
.NET 5でのアプリの更新
Microsoftストアで公開したアプリはストアのAPIを使って更新できますが、.NET 5以降は変わった点があるので、メモしておきます。
更新の際に出るダイアログのために、このオーナーとなるWindowを先に登録する必要がありますが、これは.NET 5より以前は以下のようなものでした。
見てのとおり、COMのIInitializeWithWindowを定義しておいて、StoreContextのインスタンスをこれにキャストするものですが、.NET 5以降はInvalidCastExceptionが出て実行できなくなります。
このための修正としては、usingにWinRTを加えた上でAsでIInitializeWithWindowキャストする。 もしくは、WinRT.Interop.InitializeWithWindow.Initializeを使う。これが公式に出ている方法で、StoreContextをキャストする必要がなく、したがってCOMの定義も要らなくなるので、やるならこちらだと思います。 これを含めた更新のためのヘルパークラスの全体は以下のようになります。
このための修正としては、usingにWinRTを加えた上でAsでIInitializeWithWindowキャストする。 もしくは、WinRT.Interop.InitializeWithWindow.Initializeを使う。これが公式に出ている方法で、StoreContextをキャストする必要がなく、したがってCOMの定義も要らなくなるので、やるならこちらだと思います。 これを含めた更新のためのヘルパークラスの全体は以下のようになります。
2021/11/27
ソリッドなL型ミニプラグ
ヘッドホンのミニプラグをオヤイデ電気のP-3.5 SRL+スプリングに交換したので、記録として。
有線ヘッドホンは、定番のオーソドックスなものにしておこうという理由でSonyのMDR-CD900STを随分前に買って、これは実際に交換部品の入手のしやすさで正解だったのだけど、元のプラグは太い標準プラグなのでミニプラグへの改造が前提で、これを何度か交換してきた。
PCやタブレットのオーディオジャックは側面にあるので、L型のプラグの方が取り回しがよさそうということで、オヤイデのP-3.5 SRLを買ってみたものの、ハンダ付けの難易度が高そうなのと、スプリングが付いておらず、ケーブルの穴径が6mmで穴が余るので(後に穴径が4mmのものが出た)、使わずじまいになっていた。
で、前回の交換時にハンダ付けに手間取っている間に熱で樹脂部分が傷んでいたのか、プラグが壊れたので、P-3.5 SRLを出して眺めていて、ふと思いついて前のプラグに付いていたスプリングをぐいぐい押し込んでみたら、スプリングの外径がぴったり合うことが分かったので、これでやってみるかと作業開始。
黒のアースを付ける位置に迷ったが、フラックスを塗布しておくことでハンダ付けは問題なく終了。
と思ったら、かしめるためにケーブルをねじる途中で黒が切れたので付け直してから固定。ちなみに、現行製品とは端子の穴が違う。
よく見ればスプリングとはメッキの光沢が違うものの、コンパクトかつソリッドな外見で、断線防止のスプリングもあるという、個人的に理想のL型ミニプラグができた。
有線ヘッドホンは、定番のオーソドックスなものにしておこうという理由でSonyのMDR-CD900STを随分前に買って、これは実際に交換部品の入手のしやすさで正解だったのだけど、元のプラグは太い標準プラグなのでミニプラグへの改造が前提で、これを何度か交換してきた。
PCやタブレットのオーディオジャックは側面にあるので、L型のプラグの方が取り回しがよさそうということで、オヤイデのP-3.5 SRLを買ってみたものの、ハンダ付けの難易度が高そうなのと、スプリングが付いておらず、ケーブルの穴径が6mmで穴が余るので(後に穴径が4mmのものが出た)、使わずじまいになっていた。
で、前回の交換時にハンダ付けに手間取っている間に熱で樹脂部分が傷んでいたのか、プラグが壊れたので、P-3.5 SRLを出して眺めていて、ふと思いついて前のプラグに付いていたスプリングをぐいぐい押し込んでみたら、スプリングの外径がぴったり合うことが分かったので、これでやってみるかと作業開始。
黒のアースを付ける位置に迷ったが、フラックスを塗布しておくことでハンダ付けは問題なく終了。
と思ったら、かしめるためにケーブルをねじる途中で黒が切れたので付け直してから固定。ちなみに、現行製品とは端子の穴が違う。
よく見ればスプリングとはメッキの光沢が違うものの、コンパクトかつソリッドな外見で、断線防止のスプリングもあるという、個人的に理想のL型ミニプラグができた。
2021/11/14
Surface Pro 8にWindows 10をインストール
Surface Pro 8はSurface Proシリーズのユーザーが待ち望んでいた新機種ですが、発売タイミングの関係か、一般向けはWindows 11プリインストール機のみの販売となっています。
純粋に使うだけなら別にWindows 11でもいいですが、検証などを考えるとWindows 10の環境も当面必要なので、Windows 10をクリーンインストールしてみたところ、3点引っ掛かったことがあったので、メモしておきます。
1. インストール用USBメモリ
これはSurface Pro 8に特有の点ではないですが、Surface Pro 8のUSBコネクタはUSB-C(Thunderbolt 4)だけなので、インストール用USBメモリは、USB-Cのものを使うか、USB-CとUSB-Aの変換コネクタをかませる必要があります。
ここで、容量が大きめ(32GB=32768MB超)のUSBメモリを使おうとすると、フォーマットでファイルシステムが自動的にexFATになりますが、USBメモリからブートするにはFAT32である必要があるので、何らかの方法でFAT32にする必要があります。
ただ、この点はMicrosoftのメディア作成ツールでUSBメモリの作成までやってしまえば、自動的に32GBでFAT32のパーティションが作られるので、たいした問題ではありません。
2. 入力デバイス
インストール用USBメモリからブートすると、最初に言語や地域を設定する画面が出ますが、ここで本体のタッチスクリーンもSignatureキーボードも全く反応せず、何も操作できないので詰みます。
この原因が分からず、しばらく試行錯誤したのですが、ふと外付けUSBキーボードを繋いでみたら動きました。
つまり、タッチスクリーンにせよ、Signatureキーボードにせよ、これらのためのどこかのデバイスがインストーラーに含まれたインボックスドライバーでは動かないらしいというオチでした。これはOSのインストール後もWindows Updateをかけて各種ドライバーを更新するまで解決されないので、そういうことなのでしょう。
正攻法で行くならば、Surface Pro 8のドライバーパッケージ(後述)から該当するドライバーを探し出し、予めインストーラーに組み込んでおく方法で解決できるはずですが、USBキーボードを繋いだ方が百倍速いということで。
なお、使用したインストーラーは21H1のもので、Windows 11のインストーラーでも同じでしたが、いずれ修正されるかも。
3. 内蔵カメラ
OSのインストール後にWindows Updateをかければ、ほとんどのデバイスは使用可能になりますが、内蔵カメラだけは使えません。カメラが使えないということはWindows Helloの顔認証も使えないということで、実用上見過ごせない問題です。
デバイスマネージャーをWindows 11と見比べると、Windows 11では「カメラ」に存在する「Intel(R) TGL AVStream Camera」が存在せず、代わりに「ほかのデバイス」に「ISP Camera Device」があるので、これがそれらしいと目星はつきましたが、Windows Updateではドライバーが入りません。
しばらく探したところ、MicrosoftがSurface Pro 8のWindows 11用のドライバーパッケージを公開していました。
この中のWindows 10用(SurfacePro8_Win10_19042で始まるもの)をインストールし、展開された「SurfaceUpdate」フォルダーの中から「Cameras」フォルダーを指定して、「ISP Camera Device」のドライバーの更新をかけたところ、「Intel(R) TGL AVStream Camera」が出現し、カメラが使えるようになりました。これでWindows Helloの顔認証も問題なし。
以上で、とりあえずのところ、Windows 10の動作に支障は出ていません。
[追記]
11/19にWindows 10用のドライバーパッケージが追加されたので、Windows 11に一旦インストールする工程は不要になりました。
4. おまけ
今回のSurface Pro 8はi7のモデルを買いましたが、季節柄か普段使いではファンはほとんど回らないので静かです。
ストレージは512GBですが、ベンダーは予想外のKIOXIA。
型番のKBG40ZNSで検索してみると、BG4というシリーズのSSDのようです。ホワイトペーパーによると、CrystalDiskMark 6.0による計測でシーケンシャルリードが最大2,336MB/s、シーケンシャルライトが最大1,815MB/sということなので、以下のCrystalDiskMark 8.0の結果は大体こんなものかと思います。
SignatureキーボードはUS版をAmazon USから購入。色はSurface Pro 7で使ってきたプラチナという名のグレイの使用感が今一だったのでブラックにしましたが、地味だったかも。
純粋に使うだけなら別にWindows 11でもいいですが、検証などを考えるとWindows 10の環境も当面必要なので、Windows 10をクリーンインストールしてみたところ、3点引っ掛かったことがあったので、メモしておきます。
1. インストール用USBメモリ
これはSurface Pro 8に特有の点ではないですが、Surface Pro 8のUSBコネクタはUSB-C(Thunderbolt 4)だけなので、インストール用USBメモリは、USB-Cのものを使うか、USB-CとUSB-Aの変換コネクタをかませる必要があります。
ここで、容量が大きめ(32GB=32768MB超)のUSBメモリを使おうとすると、フォーマットでファイルシステムが自動的にexFATになりますが、USBメモリからブートするにはFAT32である必要があるので、何らかの方法でFAT32にする必要があります。
ただ、この点はMicrosoftのメディア作成ツールでUSBメモリの作成までやってしまえば、自動的に32GBでFAT32のパーティションが作られるので、たいした問題ではありません。
2. 入力デバイス
インストール用USBメモリからブートすると、最初に言語や地域を設定する画面が出ますが、ここで本体のタッチスクリーンもSignatureキーボードも全く反応せず、何も操作できないので詰みます。
この原因が分からず、しばらく試行錯誤したのですが、ふと外付けUSBキーボードを繋いでみたら動きました。
つまり、タッチスクリーンにせよ、Signatureキーボードにせよ、これらのためのどこかのデバイスがインストーラーに含まれたインボックスドライバーでは動かないらしいというオチでした。これはOSのインストール後もWindows Updateをかけて各種ドライバーを更新するまで解決されないので、そういうことなのでしょう。
正攻法で行くならば、Surface Pro 8のドライバーパッケージ(後述)から該当するドライバーを探し出し、予めインストーラーに組み込んでおく方法で解決できるはずですが、USBキーボードを繋いだ方が百倍速いということで。
なお、使用したインストーラーは21H1のもので、Windows 11のインストーラーでも同じでしたが、いずれ修正されるかも。
3. 内蔵カメラ
OSのインストール後にWindows Updateをかければ、ほとんどのデバイスは使用可能になりますが、内蔵カメラだけは使えません。カメラが使えないということはWindows Helloの顔認証も使えないということで、実用上見過ごせない問題です。
デバイスマネージャーをWindows 11と見比べると、Windows 11では「カメラ」に存在する「Intel(R) TGL AVStream Camera」が存在せず、代わりに「ほかのデバイス」に「ISP Camera Device」があるので、これがそれらしいと目星はつきましたが、Windows Updateではドライバーが入りません。
しばらく探したところ、MicrosoftがSurface Pro 8のWindows 11用のドライバーパッケージを公開していました。
この中のWindows 10用(SurfacePro8_Win10_19042で始まるもの)をインストールし、展開された「SurfaceUpdate」フォルダーの中から「Cameras」フォルダーを指定して、「ISP Camera Device」のドライバーの更新をかけたところ、「Intel(R) TGL AVStream Camera」が出現し、カメラが使えるようになりました。これでWindows Helloの顔認証も問題なし。
以上で、とりあえずのところ、Windows 10の動作に支障は出ていません。
[追記]
11/19にWindows 10用のドライバーパッケージが追加されたので、Windows 11に一旦インストールする工程は不要になりました。
4. おまけ
今回のSurface Pro 8はi7のモデルを買いましたが、季節柄か普段使いではファンはほとんど回らないので静かです。
ストレージは512GBですが、ベンダーは予想外のKIOXIA。
型番のKBG40ZNSで検索してみると、BG4というシリーズのSSDのようです。ホワイトペーパーによると、CrystalDiskMark 6.0による計測でシーケンシャルリードが最大2,336MB/s、シーケンシャルライトが最大1,815MB/sということなので、以下のCrystalDiskMark 8.0の結果は大体こんなものかと思います。
SignatureキーボードはUS版をAmazon USから購入。色はSurface Pro 7で使ってきたプラチナという名のグレイの使用感が今一だったのでブラックにしましたが、地味だったかも。
2021/10/08
Winget 1.1
CUIからソフトウェアパッケージのインストールができるWindows Package Manager、別名WingetのVer 1.1がリリースされています。
Wingetは活発に開発が進められていますが、今回の大きな変化としてMicrosoftストアのアプリにもアクセスできるようになっています。これがどういうことかというと、従来はアプリをWingetでインストールできるようにするには、Wingetのレポジトリに登録する作業が必要だったのですが、Microsoftストアにあるアプリはこれが不要になり、そのままでWingetから見えるようになりました。
したがって、Wingetが使える環境であれば、例えばMonitorianをインストールするのに、コマンドプロンプトから以下を実行するだけでできてしまいます。
超簡単! 便利! 楽!
まあ実用的に使うには、どうオプションを付けるか考えて詰める必要はありますが。
既存のChocolateyもありますが、追加的な手間がかからないというのは大きいです。
Wingetは活発に開発が進められていますが、今回の大きな変化としてMicrosoftストアのアプリにもアクセスできるようになっています。これがどういうことかというと、従来はアプリをWingetでインストールできるようにするには、Wingetのレポジトリに登録する作業が必要だったのですが、Microsoftストアにあるアプリはこれが不要になり、そのままでWingetから見えるようになりました。
したがって、Wingetが使える環境であれば、例えばMonitorianをインストールするのに、コマンドプロンプトから以下を実行するだけでできてしまいます。
winget install Monitorian
超簡単! 便利! 楽!
まあ実用的に使うには、どうオプションを付けるか考えて詰める必要はありますが。
既存のChocolateyもありますが、追加的な手間がかからないというのは大きいです。
2021/08/04
Microsoftストアからのアプリの更新
Microsoftストアで公開したアプリは、Desktop Bridgeの場合も含めて、新しいバージョンが公開されているときは「Microsoft Store」アプリでそのアプリのページを開くと自動的に更新がかかります。ただ、これは往々にしてエラーになり、一旦アンインストールしての再インストールを強いられたりします。
一方、ストアのAPIには、アプリからアプリ自身の更新ができるAPIが用意されています。
このAPIはてっきりUWP用かと思っていたのですが、Desktop Bridgeでも使えるようなので、試してみました。
上のページにあるサンプルを必須部分だけにして、Desktop Bridge用の処理を加えると以下のようになります。
見てのとおり、
1.は、常にパッケージ情報が1つ返ってくるが、このパッケージのバージョン(StorePackageUpdate.Package.Id.Version)は、新しいパッケージのバージョンではなく、現在実行中のパッケージのバージョンを示すので、新しいパッケージがあるかは判別できない。
2.は、このパッケージ情報を使って実行しても現在のパッケージが再インストールされるだけのようで、更新にならない。
これは使い物にならないかなと思いつつ、数少ない先例を見てみると、少し気になることが。
その結果、この状態であれば期待どおりに更新に使えることが分かりました。
1.は、新しいパッケージがないときはパッケージ情報が返ってこないので、その有無を捉えればよい。すなわち、以下のように、上のメソッドの前半だけで判別可能。
2.は、このパッケージ情報を使って実行すると新しいパッケージがインストールされる。
ということで、Desktop Bridgeでも使えることが確認できました。このAPIを利用すればアプリに手動/自動での更新機能を付けられるので便利、なのですが、デバッグを本番環境でやらなければならない、そのために修正の度にパッケージをSubmissonとして公開しなければならないのは、時間的に勘弁してほしいとこです。
一方、ストアのAPIには、アプリからアプリ自身の更新ができるAPIが用意されています。
このAPIはてっきりUWP用かと思っていたのですが、Desktop Bridgeでも使えるようなので、試してみました。
上のページにあるサンプルを必須部分だけにして、Desktop Bridge用の処理を加えると以下のようになります。
見てのとおり、
- StoreContext.GetAppAndOptionalStorePackageUpdatesAsyncメソッドで新しいバージョンのあるパッケージ情報(StorePackageUpdate)を取得して、この有無をチェックする
- この情報を使ってStoreContext.RequestDownloadAndInstallStorePackageUpdatesAsyncメソッドを実行する
1.は、常にパッケージ情報が1つ返ってくるが、このパッケージのバージョン(StorePackageUpdate.Package.Id.Version)は、新しいパッケージのバージョンではなく、現在実行中のパッケージのバージョンを示すので、新しいパッケージがあるかは判別できない。
2.は、このパッケージ情報を使って実行しても現在のパッケージが再インストールされるだけのようで、更新にならない。
これは使い物にならないかなと思いつつ、数少ない先例を見てみると、少し気になることが。
- GetAppAndOptionalStorePackageUpdatesAsync Still Broken
- How Can we Check the New Version of app update is available in store [UWP] programmatically.
その結果、この状態であれば期待どおりに更新に使えることが分かりました。
1.は、新しいパッケージがないときはパッケージ情報が返ってこないので、その有無を捉えればよい。すなわち、以下のように、上のメソッドの前半だけで判別可能。
2.は、このパッケージ情報を使って実行すると新しいパッケージがインストールされる。
ということで、Desktop Bridgeでも使えることが確認できました。このAPIを利用すればアプリに手動/自動での更新機能を付けられるので便利、なのですが、デバッグを本番環境でやらなければならない、そのために修正の度にパッケージをSubmissonとして公開しなければならないのは、時間的に勘弁してほしいとこです。
2021/05/30
タフな2.5インチドライブ用ケース
2.5インチドライブ用の外付けケースとして最もタフな部類に入るSilverStoneのSST-MMS01Bを使っていましたが、StarTech.comのS251BRU31C3に買い替えたので、記録として。
この2つ、ベンダーは違いますが、コントローラー基板以外の筐体は見たとおり全く同じなので、ODM元は同じなのでしょう。
インターフェイスとコネクタは以下のとおり。
筐体の中はどんなものかというと、ドライブはコネクタ以外の全方向がゴム素材で支えられる構造になっていて、縁には防水のパッキンがあります。
蓋は六角ネジで固定するようになっています。外側のゴムジャケットも合わせて厚みは30mmとなるので、ドライブが9.5mm厚として上下に10mmの緩衝スペースがある計算になります。見えませんが、ネジ穴部分の内側にワッシャー型のパッキンがあり、ネジ穴からの防水になっています。
コネクタにはパッキン付きの蓋があります。コネクタの貫通部はシールされているようには見えないので、蓋は閉めておかないと防水性は発揮されないかと。
一応性能確認のため、古いものですがSanDiskのExtreme Proを繋いでMBP2019からAmorphousDiskMarkで計測した結果。コントローラーはasmediaのASM235CMでした。
性能的には十分かと思います。
ということで、データを物理的要因から保護するケースとして現状不満点はないです。なお、難点というほどではないですが、アクセスランプはなく、HDDでも動作音はほとんど漏れてこないので、外からは動作状況が分からないのが注意点ではあります。
この2つ、ベンダーは違いますが、コントローラー基板以外の筐体は見たとおり全く同じなので、ODM元は同じなのでしょう。
インターフェイスとコネクタは以下のとおり。
- SST-MMS01B : USB 3.0 : Micro-B 3.0
- S251BRU31C3 : USB 3.1 : USB-C
筐体の中はどんなものかというと、ドライブはコネクタ以外の全方向がゴム素材で支えられる構造になっていて、縁には防水のパッキンがあります。
蓋は六角ネジで固定するようになっています。外側のゴムジャケットも合わせて厚みは30mmとなるので、ドライブが9.5mm厚として上下に10mmの緩衝スペースがある計算になります。見えませんが、ネジ穴部分の内側にワッシャー型のパッキンがあり、ネジ穴からの防水になっています。
コネクタにはパッキン付きの蓋があります。コネクタの貫通部はシールされているようには見えないので、蓋は閉めておかないと防水性は発揮されないかと。
一応性能確認のため、古いものですがSanDiskのExtreme Proを繋いでMBP2019からAmorphousDiskMarkで計測した結果。コントローラーはasmediaのASM235CMでした。
性能的には十分かと思います。
ということで、データを物理的要因から保護するケースとして現状不満点はないです。なお、難点というほどではないですが、アクセスランプはなく、HDDでも動作音はほとんど漏れてこないので、外からは動作状況が分からないのが注意点ではあります。
2021/05/04
Hello Switcherのサービス化
ノートやタブレットPCでWindows Hello対応の内蔵カメラがある場合、Windows Hello対応のWebカメラを接続しても、Windows Helloに使われるカメラを切り換えられない問題は、Microsoftでも認識されているようです。
最近ようやくというか、周辺機器メーカーから普及帯のWindows Hello対応Webカメラが出ましたし(エレコムのUCAM-CF20FBBK)、既にDellやLenovoからWindows Hello対応カメラ付きのモニターも出ています。中でもMicrosoft Teams専用機能を謳ったC2422HEについて、Dellのサポートに問い合わせてみたところ、やはりPC本体にWindows Hello対応カメラがある場合はモニターのカメラは使えないとの回答でした。この問題にぶち当たるケースが増えるにつれ、Microsoftでもいつまでも放置はされないかもと想像しています。
ともあれ、この問題を解決するためのHello Switcherですが、これまでの実績上、切換え機能自体には問題なさそうです。 一方で、ログイン後という起動タイミングに起因する問題は如何ともしがたく、未解決の問題として残っていました。すなわち、電源オフの間やサスペンド中にUSBカメラの着脱があった場合、その後のログイン前にカメラの切換えは当然できません。
試しにタスクスケジューラでの開始タイミングをスタートアップ時に変えてみましたが(この状態だとUIを出せないので、実用的ではない)、ログイン前にカメラの切換えが間に合う場合もあれば合わない場合もあり、解決策にはならず。
よって、Windowsサービスの実行ファイルも作成し、通常のアプリと併用する(アプリの実行中はサービスはPausedにしておく)方針に変えました。 この結果、切換えが間に合わなくなる場面はほぼなくなりました。ということで、ようやくアプリとして所期の要求を満たすようになりました、パチパチ。
実際、サービスとして動かしている限り、表に出ることもなく自動的に切り換えるので、OSの標準機能と変わりません。これで、この問題は実質的には解決かなと。
ともあれ、この問題を解決するためのHello Switcherですが、これまでの実績上、切換え機能自体には問題なさそうです。 一方で、ログイン後という起動タイミングに起因する問題は如何ともしがたく、未解決の問題として残っていました。すなわち、電源オフの間やサスペンド中にUSBカメラの着脱があった場合、その後のログイン前にカメラの切換えは当然できません。
試しにタスクスケジューラでの開始タイミングをスタートアップ時に変えてみましたが(この状態だとUIを出せないので、実用的ではない)、ログイン前にカメラの切換えが間に合う場合もあれば合わない場合もあり、解決策にはならず。
よって、Windowsサービスの実行ファイルも作成し、通常のアプリと併用する(アプリの実行中はサービスはPausedにしておく)方針に変えました。 この結果、切換えが間に合わなくなる場面はほぼなくなりました。ということで、ようやくアプリとして所期の要求を満たすようになりました、パチパチ。
実際、サービスとして動かしている限り、表に出ることもなく自動的に切り換えるので、OSの標準機能と変わりません。これで、この問題は実質的には解決かなと。
2021/05/03
Windowsサービスでデバイスイベントを捕捉する
実行ファイルをWindowsサービスとして動かすために.NETではSystem.ServiceProcess名前空間にServiceContollerとServiceBaseクラスが用意されていて、これらに則れば比較的容易にサービスを実装できますが、このServiceBaseの派生クラスからデバイスイベント(USBデバイスの着脱)を捕捉するにはどうすればいいか、鉄板的なものが見当たらなかったので、メモしておきます。
1. 基本
Win32的には、Windowsサービスは大体以下のような仕組みになっているようです。
2. 実装
デバイスイベントの捕捉については、ざっと探して以下の先例がありました。
このコードをダウンロードして見ると、ServiceBaseの派生クラス上で上記の3を行い、イベントを独自のコールバック関数で捕捉するようにしています。つまり、ServiceBase内と二重にRegisterServiceCtrlHandlerEx関数を実行しているわけですが、こうするとServiceBase内のコールバック関数へのポインターが上書きされるようで、ServiceBase内のサービスステータス管理用の処理が実行されなくなります。このため、独自のコールバック関数の方でSERVICE_CONTROL_STOPを捕捉してServiceBase.Stopメソッドを呼んでいます。
とりあえず確認したところ、デバイスイベントの捕捉は問題なくできましたが、致命的な問題が。サスペンド時(Windows 10では、標準では「シャットダウン」がサスペンドになる)にAccessViolationExceptionが発生します。これは少し確認したところ、RegisterServiceCtrlHandlerEx関数を実行しただけで起こり、たぶんアンマネージドなハンドル絡みだと思うので、ほぼ対処不能。
ではどうするかというと、既にServiceBase内にコールバックの仕組みはあるので、これを利用できないかとソースを改めて見ると、コールバック関数に来たコントロールコードは途中で捕捉されなければ最終的にServiceBase.OnCustomCommandメソッドに流れてくるので、これを捕捉すればよいと発見(LPHANDLER_FUNCTION_EXにおけるdwControl = ServiceBase.OnCustomCommandにおけるcommand)。カスタムコマンドは128から255までという決まりがあり、SERVICE_CONTROL_DEVICEEVENTは11なので、この範囲に入りませんが、わざわざフィルターしているわけでもないので。
ということで、これなら簡単に実装できます。デバイスイベントへの登録はWindowメッセージの場合とDEVICE_NOTIFY_SERVICE_HANDLE以外は同じ。
なお、OnStartでRegisterの前にUnregisterしているのは、OnStartの後に必ずOnStopが来るとは限らないため。
惜しむらくは、一緒に来るdwEventType(WM_DEVICECHANGEにおけるwParamと同じ)とlpEventData(同じくlParamと同じ)は流れてこないので、デバイスイベントが起きたことしか分からないことですが、イベントがあったことが分かればやりようはあるので。
このサンプルのレポジトリは以下。 以上で用には足りますが、ServiceBaseクラスは.NETでサービスを使うには必須の基底クラスなので、もう少し拡張にオープンにしてほしかったというのが率直な印象でした。
1. 基本
Win32的には、Windowsサービスは大体以下のような仕組みになっているようです。
- まずサービス名を指定してCreateService関数でサービスを生成する。
- このサービス名とコールバック関数を指定してRegisterServiceCtrlHandler関数を実行すると、サービス自体の管理用(開始、停止等)のコントロールコードがこのコールバック関数に流れてくるようになる。また、この関数の実行時にサービスステータスハンドルが返ってくるので、これをサービスステータスの管理等に利用する。
- または、このサービス名とコールバック関数を指定してRegisterServiceCtrlHandlerEx関数を実行すると、2のコントロールコードに加えて、デバイスイベントを含めたシステムイベントのコントロールコードも流れてくるようになる(デバイスイベントの場合は、さらにサービスステータスハンドルを指定してイベントへの登録が必要。この部分はWindowを持つアプリでWindowメッセージを処理するのと基本同じ)。具体的なイベントについては、このコールバック関数(LPHANDLER_FUNCTION_EX)を参照。
2. 実装
デバイスイベントの捕捉については、ざっと探して以下の先例がありました。
このコードをダウンロードして見ると、ServiceBaseの派生クラス上で上記の3を行い、イベントを独自のコールバック関数で捕捉するようにしています。つまり、ServiceBase内と二重にRegisterServiceCtrlHandlerEx関数を実行しているわけですが、こうするとServiceBase内のコールバック関数へのポインターが上書きされるようで、ServiceBase内のサービスステータス管理用の処理が実行されなくなります。このため、独自のコールバック関数の方でSERVICE_CONTROL_STOPを捕捉してServiceBase.Stopメソッドを呼んでいます。
とりあえず確認したところ、デバイスイベントの捕捉は問題なくできましたが、致命的な問題が。サスペンド時(Windows 10では、標準では「シャットダウン」がサスペンドになる)にAccessViolationExceptionが発生します。これは少し確認したところ、RegisterServiceCtrlHandlerEx関数を実行しただけで起こり、たぶんアンマネージドなハンドル絡みだと思うので、ほぼ対処不能。
ではどうするかというと、既にServiceBase内にコールバックの仕組みはあるので、これを利用できないかとソースを改めて見ると、コールバック関数に来たコントロールコードは途中で捕捉されなければ最終的にServiceBase.OnCustomCommandメソッドに流れてくるので、これを捕捉すればよいと発見(LPHANDLER_FUNCTION_EXにおけるdwControl = ServiceBase.OnCustomCommandにおけるcommand)。カスタムコマンドは128から255までという決まりがあり、SERVICE_CONTROL_DEVICEEVENTは11なので、この範囲に入りませんが、わざわざフィルターしているわけでもないので。
ということで、これなら簡単に実装できます。デバイスイベントへの登録はWindowメッセージの場合とDEVICE_NOTIFY_SERVICE_HANDLE以外は同じ。
なお、OnStartでRegisterの前にUnregisterしているのは、OnStartの後に必ずOnStopが来るとは限らないため。
惜しむらくは、一緒に来るdwEventType(WM_DEVICECHANGEにおけるwParamと同じ)とlpEventData(同じくlParamと同じ)は流れてこないので、デバイスイベントが起きたことしか分からないことですが、イベントがあったことが分かればやりようはあるので。
このサンプルのレポジトリは以下。 以上で用には足りますが、ServiceBaseクラスは.NETでサービスを使うには必須の基底クラスなので、もう少し拡張にオープンにしてほしかったというのが率直な印象でした。
2021/04/10
ストライプ付きプログレスバー
プログレスバーの最近の流行りは、コンテンツを邪魔しないように細くして、存在感を主張しないものだと思いますが、控えめにアクセントを付ける方法として、ストライプを付けるものがあります。それで、進行中はストライプをアニメーションさせると。
WPFというかXAMLのアニメーションはその辺柔軟なので、それほど難しくはないです。
ポイントとしては、連続して描画するタイプの要素をアニメーションさせるときは、その開始位置の値を変えていくようにすれば、比較的簡単にできます。上の例ではDrawingBrushをTileMode="Tile"を指定して敷き詰め、位置をViewportで決めていますが、このXの値を変えてアニメーションさせています。
ここでもう一つポイントとして、アニメーションにはプリミティブな値を変えるDoubleAnimationやColorAnimationをよく使いますが、Viewportの型はRectなので、この中のXはDoubleAnimationでは対象に指定できません。こういう場合は、複合的な値であるRectを変えるRectAnimationが用意されているので、これを使えばいいわけです。
同じようにThickness(Marginの型)を変えるThicknessAnimation、Pointを変えるPointAnimation、Sizeを変えるSizeAnimationもあるので、幾何学的に変化させるアニメーションは大体カバーできます。これら以外にも、AnimationTimelineの派生クラスを見ると、予め用意されているAnimationをチェックできます。
WPFというかXAMLのアニメーションはその辺柔軟なので、それほど難しくはないです。
ポイントとしては、連続して描画するタイプの要素をアニメーションさせるときは、その開始位置の値を変えていくようにすれば、比較的簡単にできます。上の例ではDrawingBrushをTileMode="Tile"を指定して敷き詰め、位置をViewportで決めていますが、このXの値を変えてアニメーションさせています。
ここでもう一つポイントとして、アニメーションにはプリミティブな値を変えるDoubleAnimationやColorAnimationをよく使いますが、Viewportの型はRectなので、この中のXはDoubleAnimationでは対象に指定できません。こういう場合は、複合的な値であるRectを変えるRectAnimationが用意されているので、これを使えばいいわけです。
同じようにThickness(Marginの型)を変えるThicknessAnimation、Pointを変えるPointAnimation、Sizeを変えるSizeAnimationもあるので、幾何学的に変化させるアニメーションは大体カバーできます。これら以外にも、AnimationTimelineの派生クラスを見ると、予め用意されているAnimationをチェックできます。
2021/02/11
マルチタッチによるクリックの判別
WPF上のタッチ操作でシングルタッチによるものか、マルチタッチによる(指を複数使う)ものかは、Manipulation系のイベントであれば直接判別できるようになっていますが、移動を伴わないTouch系のイベントのときは直接分かるものがないので、どうするか考えてみた話です。
そんなに難しいことでもなく、Touch系のイベントで来るTouchEventArgsのTouchDeviceがイベントを起こした個々のデバイス(指)を示すので、このIdを記録して、これが一連のイベントが終わるまでに一つしか来ていなければシングルタッチ、複数来ていればマルチタッチと判別できます。
以下のButtonの例では、PreviewTouchDownイベントごとにTouchDeviceのIdをHashSetに記録していき、Clickイベントのときに複数来ているか判別した後で、HashSetを初期化しています。なお、タッチ操作の終わりに常にClickイベントが来るわけではないので、PreviewTouchUpイベントを引っ掛けた上で、これはClickイベントより先に来るので、1秒の猶予をおいてから初期化するようにしています。
なお、一つのTouchDeviceがPreviewTouchDownで何回も来ることはないと割り切れば、単なるカウンターでも十分な気はします。
より実用的に、ClickイベントからBehaviorのCallMethodActionを実行するようにしている場合、そのIsEnabled依存関係プロパティとbindingを張ってもいいですが、そのために妙にコードが増えるのもうまくないので、CallMethodActionの分も含めてBehaviorにまとめたのが以下。
サンプル全体は以下。 以上でシングルタッチかマルチタッチかに応じて実行するメソッドを切り替えられるようになりましたが、実際に試してみると、2つの指を合わせて、それぞれ認識されるまでタッチしてから離す(完全に同時にタッチする必要はない)操作は慣れが必要で、タッチデバイスにもよるでしょうが、この操作の実用性自体が少し微妙なことに気づきました。
そんなに難しいことでもなく、Touch系のイベントで来るTouchEventArgsのTouchDeviceがイベントを起こした個々のデバイス(指)を示すので、このIdを記録して、これが一連のイベントが終わるまでに一つしか来ていなければシングルタッチ、複数来ていればマルチタッチと判別できます。
以下のButtonの例では、PreviewTouchDownイベントごとにTouchDeviceのIdをHashSetに記録していき、Clickイベントのときに複数来ているか判別した後で、HashSetを初期化しています。なお、タッチ操作の終わりに常にClickイベントが来るわけではないので、PreviewTouchUpイベントを引っ掛けた上で、これはClickイベントより先に来るので、1秒の猶予をおいてから初期化するようにしています。
なお、一つのTouchDeviceがPreviewTouchDownで何回も来ることはないと割り切れば、単なるカウンターでも十分な気はします。
より実用的に、ClickイベントからBehaviorのCallMethodActionを実行するようにしている場合、そのIsEnabled依存関係プロパティとbindingを張ってもいいですが、そのために妙にコードが増えるのもうまくないので、CallMethodActionの分も含めてBehaviorにまとめたのが以下。
サンプル全体は以下。 以上でシングルタッチかマルチタッチかに応じて実行するメソッドを切り替えられるようになりましたが、実際に試してみると、2つの指を合わせて、それぞれ認識されるまでタッチしてから離す(完全に同時にタッチする必要はない)操作は慣れが必要で、タッチデバイスにもよるでしょうが、この操作の実用性自体が少し微妙なことに気づきました。
2021/01/31
階層的なロケール
.NETアプリではリソースファイル(.resx)をロケールごとに用意しておけば、実行時にユーザーの表示言語に合ったリソースが自動的に選択されます。ロケールは基本的に[言語名]-[地域名]の構成ですが、中国語だけはこれが簡体字と繁体字のために階層的になっているので、確認してみました。
各ロケールのCultureInfoのParentプロパティを辿るとInvariantCultureに辿り着きますが、その一つ前までをまとめてMarkdownの表を生成するコードが以下のとおり。
これを.NET Framework 4.8の上で実行した結果。
自動選択では表示言語と同じリソースがあればそれが、なければ上に辿って存在するリソースが選択されるはずなので、簡体字の場合、表示言語がzh-CN(中国本土)のときはzh-CNのリソースがあればそれが、なければ(zh-CHSは古いものなのでスルーするとして)zh-Hansのリソースがあればそれが選択されることになります。ここで、簡体字なのは中国本土だけだろうと思っていたら、実はシンガポールも簡体字を使っていて、リソースをzh-CNで作成すると表示言語がzh-SGのときには選択されません。
同じように、繁体字の場合、表示言語がzh-TW(台湾)のときはzh-TWのリソースがあればそれが、なければ(zh-CHTはスルーするとして)zh-Hantが存在すればそれが選択されますが、リソースをzh-TWで作成すると香港かマカオで表示言語に繁体字を使っているときには選択されないことになります。
したがって、簡体字のリソースはzh-Hansで、簡体字のリソースはzh-Hantで作成するのが正解で、もし分ける必要が出てきた場合に、その下のロケールで該当部分を上書きすればいいわけです。
念のため、.NET 5.0の上で実行した結果。
これも古いzh-CHSとzh-CHTが消えた以外は同じですが、説明に簡体字か繁体字か明記していないのが不親切。
以上、中国語のロケールはそれぞれzh-Hansかzh-Hantにしておけばよい、という確認まで。
各ロケールのCultureInfoのParentプロパティを辿るとInvariantCultureに辿り着きますが、その一つ前までをまとめてMarkdownの表を生成するコードが以下のとおり。
これを.NET Framework 4.8の上で実行した結果。
自動選択では表示言語と同じリソースがあればそれが、なければ上に辿って存在するリソースが選択されるはずなので、簡体字の場合、表示言語がzh-CN(中国本土)のときはzh-CNのリソースがあればそれが、なければ(zh-CHSは古いものなのでスルーするとして)zh-Hansのリソースがあればそれが選択されることになります。ここで、簡体字なのは中国本土だけだろうと思っていたら、実はシンガポールも簡体字を使っていて、リソースをzh-CNで作成すると表示言語がzh-SGのときには選択されません。
同じように、繁体字の場合、表示言語がzh-TW(台湾)のときはzh-TWのリソースがあればそれが、なければ(zh-CHTはスルーするとして)zh-Hantが存在すればそれが選択されますが、リソースをzh-TWで作成すると香港かマカオで表示言語に繁体字を使っているときには選択されないことになります。
したがって、簡体字のリソースはzh-Hansで、簡体字のリソースはzh-Hantで作成するのが正解で、もし分ける必要が出てきた場合に、その下のロケールで該当部分を上書きすればいいわけです。
念のため、.NET 5.0の上で実行した結果。
これも古いzh-CHSとzh-CHTが消えた以外は同じですが、説明に簡体字か繁体字か明記していないのが不親切。
以上、中国語のロケールはそれぞれzh-Hansかzh-Hantにしておけばよい、という確認まで。
2021/01/28
Dellモニタースタンドの限界突破(下方向)
Dell U2415をサブモニターとして使っていますが、設置場所の関係でやや高い位置に置かざるを得ず、モニタースタンドの下限一杯にしてもモニターの位置が視線の高さに対して高くなるという問題がありました。
こういう場合の解決策としてモニターアームの使用が考えられますが、あれはあれで設置に手がかかり、かつ位置調整も全く融通無碍にできるわけではありません。そこでモニタースタンドの改造で何とかできないかと検討。
スタンドのモニターとの接続部のプレートを一旦取り外し、カバーを外して取り付け直したところ。
この左右の端の中央の高さにある横長の穴は、カバーのダボがはまっていた部分で、組み立て時の位置決め用と推測しますが、もしかしてこれにVESAマウントのネジを通せないかと思い付き、穴の間の距離を測ったところ、ネジの中心になる位置の間で101mm。VESAマウントは100mmなので、微妙に合いません。
穴をそれぞれ内側に削る手もなくはないですが、このスチールのプレートを手作業で加工するのは率直に言って苦行。どうしたものかと手持ちの金具を漁っていたら、ピカーンと。
モニターのVESAマウントのネジ穴に黒いクランク型の金具を少し傾けて取り付けることで、ネジ位置をスタンドのプレートの穴に合わせることができると。いずれにせよスペーサーが必要だったので、一石二鳥。何かの用に使おうと買ったまま長らく死蔵していたものですが、まさか役に立つ日が来ようとは、「こんなこともあろうかと」が本当にあるとは、自分でも少々びっくり。
とりあえずスタンドに取り付けてみたところ。横2点だけの固定なので縦の揺れはあるものの、厚みのあるスチールの金具なので、それ自体の強度には問題なさそう。
まあ大丈夫そうなので、根本のカバーを戻し、プレートの下型の爪の部分にゴムを挟んで揺れ止めにして、一応の完成。
この結果、モニターの位置を大きく4cm弱下げることに成功(スタンドの台座との隙間は8mm)。このスタンドのプレートの穴はU2720QMのスタンドにもあったので、Dellのモニターで割と汎用的に使えるテクではないかと思います。あくまで緊急避難的なものですが。
こういう場合の解決策としてモニターアームの使用が考えられますが、あれはあれで設置に手がかかり、かつ位置調整も全く融通無碍にできるわけではありません。そこでモニタースタンドの改造で何とかできないかと検討。
スタンドのモニターとの接続部のプレートを一旦取り外し、カバーを外して取り付け直したところ。
この左右の端の中央の高さにある横長の穴は、カバーのダボがはまっていた部分で、組み立て時の位置決め用と推測しますが、もしかしてこれにVESAマウントのネジを通せないかと思い付き、穴の間の距離を測ったところ、ネジの中心になる位置の間で101mm。VESAマウントは100mmなので、微妙に合いません。
穴をそれぞれ内側に削る手もなくはないですが、このスチールのプレートを手作業で加工するのは率直に言って苦行。どうしたものかと手持ちの金具を漁っていたら、ピカーンと。
モニターのVESAマウントのネジ穴に黒いクランク型の金具を少し傾けて取り付けることで、ネジ位置をスタンドのプレートの穴に合わせることができると。いずれにせよスペーサーが必要だったので、一石二鳥。何かの用に使おうと買ったまま長らく死蔵していたものですが、まさか役に立つ日が来ようとは、「こんなこともあろうかと」が本当にあるとは、自分でも少々びっくり。
とりあえずスタンドに取り付けてみたところ。横2点だけの固定なので縦の揺れはあるものの、厚みのあるスチールの金具なので、それ自体の強度には問題なさそう。
まあ大丈夫そうなので、根本のカバーを戻し、プレートの下型の爪の部分にゴムを挟んで揺れ止めにして、一応の完成。
この結果、モニターの位置を大きく4cm弱下げることに成功(スタンドの台座との隙間は8mm)。このスタンドのプレートの穴はU2720QMのスタンドにもあったので、Dellのモニターで割と汎用的に使えるテクではないかと思います。あくまで緊急避難的なものですが。
2020/12/31
アプリ実行エイリアス
Microsoftストアにアプリを出すときに、app package manifestで「アプリ実行エイリアス」というものを指定できます。この効能はストアからインストールしたアプリ(デスクトップアプリを含む)をコマンドプロンプトからファイルパスなしのファイル名だけで起動できるというものです。
一応OSの設定にも出てきます。
ストアからインストールしたアプリの実行ファイル等はOSが管理するので、アプリの起動は基本的にスタートメニューに作成されるアイコンからか、自動起動に登録するか以外にはできませんが、そのコマンドプロンプト向けの救済策のようなものです。
これだけならコマンドプロンプトを使わせたいケース以外には関係ない話ですが、Hash Padを開発しているときに別の利用法があるのを見つけました。すなわち、これを宛先に指定することでアプリを起動するショートカットを自由に作成できます。
このアプリ実行エイリアスは以下のパスに自動的に作成されるようです。
C:\Users\[ユーザー名]\AppData\Local\Microsoft\WindowsApps
タネ明かしとしては、PATHを一覧表示するとこのパスが入っているので、それでパスなして起動できるというわけですね。
これはフルパスとしては以下のコードで取得できます。 これ自体はエイリアスというかシンボリックリンクみたいなもので、実体のあるファイルではないですが、これから直接アプリを起動できるほか、ショートカットのターゲットパスに指定してアプリを起動することもできます。
もう一つ重要な点は、WinRTのAPIにはパッケージされたアプリからしか利用できないものがありますが、これから起動するとパッケージからの起動になることです。実行ファイルを探し出して直接起動した場合はパッケージからの起動にならないので、この点は大きな違いです。
というわけで、アプリ実行エイリアスを使うことでストアにアプリを出すときの難点の一つを解決できます。Hash Padでは、これによりコンテキストメニューの「送る」フォルダーにショートカットを作成しています。
これだけならコマンドプロンプトを使わせたいケース以外には関係ない話ですが、Hash Padを開発しているときに別の利用法があるのを見つけました。すなわち、これを宛先に指定することでアプリを起動するショートカットを自由に作成できます。
このアプリ実行エイリアスは以下のパスに自動的に作成されるようです。
C:\Users\[ユーザー名]\AppData\Local\Microsoft\WindowsApps
タネ明かしとしては、PATHを一覧表示するとこのパスが入っているので、それでパスなして起動できるというわけですね。
これはフルパスとしては以下のコードで取得できます。 これ自体はエイリアスというかシンボリックリンクみたいなもので、実体のあるファイルではないですが、これから直接アプリを起動できるほか、ショートカットのターゲットパスに指定してアプリを起動することもできます。
もう一つ重要な点は、WinRTのAPIにはパッケージされたアプリからしか利用できないものがありますが、これから起動するとパッケージからの起動になることです。実行ファイルを探し出して直接起動した場合はパッケージからの起動にならないので、この点は大きな違いです。
というわけで、アプリ実行エイリアスを使うことでストアにアプリを出すときの難点の一つを解決できます。Hash Padでは、これによりコンテキストメニューの「送る」フォルダーにショートカットを作成しています。
2020/10/14
GitHubのWikiブランチへのアクセス
特に難しい話ではないですが、GitHubのレポジトリでWikiを作成すると、wikiというブランチが作成されます。このブランチにリモートのWindowsからアクセスする方法としてはGitHub Desktopが手軽ですが、ぱっと見では分からなかったので、メモです。
初めにパスとしては、そのレポジトリのパスの.gitの前に.wikiを挿入したものになります。したがって、自分のMonitorianを例にとると、レポジトリ自体は
https://github.com/emoacht/Monitorian.gitなので、
https://github.com/emoacht/Monitorian.wiki.gitとなります。
後はGitHub DesktopのAddからClone repositoryを選んで、URLのタブで直接指定してしまいます。
これでクローンしてしまえば、後は普通のレポジトリと同じです。
GitHubの機能や他のサービスを活かしたレポジトリは機能的でいいのですが、それぞれノウハウがあってなかなか面倒です。
初めにパスとしては、そのレポジトリのパスの.gitの前に.wikiを挿入したものになります。したがって、自分のMonitorianを例にとると、レポジトリ自体は
https://github.com/emoacht/Monitorian.gitなので、
https://github.com/emoacht/Monitorian.wiki.gitとなります。
後はGitHub DesktopのAddからClone repositoryを選んで、URLのタブで直接指定してしまいます。
これでクローンしてしまえば、後は普通のレポジトリと同じです。
GitHubの機能や他のサービスを活かしたレポジトリは機能的でいいのですが、それぞれノウハウがあってなかなか面倒です。
2020/06/12
Lenovo 500 FHD Webcam
数少ないWindows Hello対応のUSBカメラの新製品であるLenovo 500 FHD Webcamが到着したので、レビューします。この製品に関しては、Lenovo公式から以外の情報があまりないので。
パッケージをLogicool C920sと並べたところ。店頭陳列用に派手なデザインのLogicoolに対して、色もサイズもおとなし目です。
最初にこの製品の名称ですが、Lenovo公式では「Lenovo 500 Full HD Windows Hello対応 Webカメラ」という、どこまでが製品名でどこからが機能説明なのか分からない表記になっていますが、パッケージにある表記が本来の名称なのでしょう。というわけで、「Lenovo 500 FHD Webcam」です。
Windows Hello対応のUSBカメラとしては、長らくマウスコンピューターのCM01とその後継のCM02が実質的に唯一の選択肢で(Logicool Brio Webcamはこれだけのためには高すぎ)、ようやく選択肢が増えたことになります。
DellのU2720QMの上に設置したところ。C920sはカメラ本体が台座の前にあるのに対して、500 FHDは台座の上にあるので、カメラの位置は少し奥になります。
デザイン的には、レンズとマイクのモチーフが盛り込まれたC920sとは対照的に、500 FHDは余分な装飾も凹凸も一切ないミニマルなデザインになっています。
高さはC920sは本来もっと低いのですが、台座のモニターの前に掛ける爪が長く、そのままだと表示域(縁から6mmぐらい)にかかってしまうので、3mmのゴムを挟んで上に上げています。これはC920sの元設計が古くてベゼルレスのモニターが考慮されてないのでしょう。500 FHDの方は台座の爪が短く、そのままで問題ありません。ちなみに、台座の幅はどちらもきっかり45mmです。
首振りは上下のみのC920sに対して、500 FHDはボール雲台式で自由度は高いです。ただ、C920sは俯角が大きく取れるようになっているので、それには及びませんが、台座自体の設置角でも調整幅は増やせるので(油気圧サスペンションの戦車の如く)、問題にはならないかなと。
上面にはLenovoのロゴがうっすら入っています。これは表面仕上げの違いでロゴだけツヤを付けて見せているだけなので、角度によって見えることがあるという程度です。
USBケーブルはC920sが直出しなのに対して、500 FHDはUSB-Cコネクタに挿す形式(USB-C to USB-Aケーブルが付属)で、この方が自由度は高いですが、ケーブルが宙を走ることになって収まりが悪い面もあり、良し悪しという気がします。
カメラには4つ窓があって、中央から左側に向かって普通のカメラ、赤外線カメラ、赤外線ライト、プライバシーライトです。右側にも何かありそうに見えますが、ここには中にプライバシーシャッターがあるので、センサーはないです。
このシャッターは上のつまみを押さえて横にスライドさせると、中のシャッターも動く仕組みです。
シャッターには赤丸があるので、よく見れば閉じているのが分かります。ただ、カメラに赤丸は一般的には録画中を示すサインなので、閉じている状態を示すにはUI的にどうかなという気がします。つまみの大きさから見て、頻繁に変えるというより念のために付いている感じですが。
普通のカメラの撮影中はプライバシーライトが点灯します。
Windows Helloの認識中は、赤外線ライトが点滅します。色はSurface Proと同じく赤ですが、光はもっと強いです。認識はうまく行けば一瞬なので、Surface Proと変わりません。
500 FHDの普通のカメラは、基本スペックとしてはFull HD(1920×1080)で、C920sの1080pモード、Surface Pro 4のフロントカメラと変わりません。
画質については……自分ではそれほど差が分からないというのが実際のところです。C920sはさすがに自動調整がうまく効いているぐらいは分かりますが……一番古いSurface Pro 4のカメラでも映りは悪くないと感じるので。試していて気づいたのは、むしろ映りにダイレクトに影響するのは、カメラというより照明の方かなと。
なお、LogicoolのLogi Captureのようなカスタマイズソフトは付属しません。余談ですが、Logi Captureは、使ってみるまで知らなかったのですが、カメラの設定ソフトではなく、それ自体がカメラ入力を受けて画像をリアルタイムに加工して他のソフトに出力するもので、当然リソースを結構使うのですよね。カメラ入力は他のソフトで直接受けられるので、画像にこだわりがなければ使わなくていいかなと。
試した範囲では、Microsoft Teams、Cisco Webex、Zoomで入力元に使えるのを確認しました。
なお、C920sとは違ってマイクはありませんが、個人的には別に求めていないので問題ありません。
自分は数年来、Surface Pro 4に外部モニターを接続して使っていますが、そのときにはSurface Pro 4の画面に被せる形にするので、Surface Pro 4に内蔵のWindows Helloカメラは使えなくなります。これが500 FHDを購入した理由ですが、実はWindows 10には複数のWindows Helloカメラを切り替える機能がないらしく、500 FHDを接続してもそのままではWindows Helloに内蔵カメラを使おうとします。
対処療法として、内蔵カメラをデバイスマネージャーで無効にしてしまえば、代わりに500 FHDが使われるようになるのが分かったので、500 FHDの有無に応じてこれを自動化するツールとしてHello Switcherを作成しました。 注意点として、OSのサインイン前には動作できないので、前回サインアウト時の最後の状態は次回サインイン前には変更できません。具体的なケースで言うと、前回サインアウト時に500 FHDがある状態だった場合、内蔵カメラは無効化されているので、次回サインイン時に500 FHDがない場合は、有効なWindows Helloカメラが存在しないことになり、Windows Helloが使えません。こういう場合はPIN認証などでサインインして下さい。サインイン後にこのツールが実行された際に内蔵カメラは有効化されます。
まとめると、良い点は以下のとおりです。
1. 外観
パッケージをLogicool C920sと並べたところ。店頭陳列用に派手なデザインのLogicoolに対して、色もサイズもおとなし目です。
最初にこの製品の名称ですが、Lenovo公式では「Lenovo 500 Full HD Windows Hello対応 Webカメラ」という、どこまでが製品名でどこからが機能説明なのか分からない表記になっていますが、パッケージにある表記が本来の名称なのでしょう。というわけで、「Lenovo 500 FHD Webcam」です。
Windows Hello対応のUSBカメラとしては、長らくマウスコンピューターのCM01とその後継のCM02が実質的に唯一の選択肢で(Logicool Brio Webcamはこれだけのためには高すぎ)、ようやく選択肢が増えたことになります。
DellのU2720QMの上に設置したところ。C920sはカメラ本体が台座の前にあるのに対して、500 FHDは台座の上にあるので、カメラの位置は少し奥になります。
デザイン的には、レンズとマイクのモチーフが盛り込まれたC920sとは対照的に、500 FHDは余分な装飾も凹凸も一切ないミニマルなデザインになっています。
高さはC920sは本来もっと低いのですが、台座のモニターの前に掛ける爪が長く、そのままだと表示域(縁から6mmぐらい)にかかってしまうので、3mmのゴムを挟んで上に上げています。これはC920sの元設計が古くてベゼルレスのモニターが考慮されてないのでしょう。500 FHDの方は台座の爪が短く、そのままで問題ありません。ちなみに、台座の幅はどちらもきっかり45mmです。
首振りは上下のみのC920sに対して、500 FHDはボール雲台式で自由度は高いです。ただ、C920sは俯角が大きく取れるようになっているので、それには及びませんが、台座自体の設置角でも調整幅は増やせるので(油気圧サスペンションの戦車の如く)、問題にはならないかなと。
上面にはLenovoのロゴがうっすら入っています。これは表面仕上げの違いでロゴだけツヤを付けて見せているだけなので、角度によって見えることがあるという程度です。
USBケーブルはC920sが直出しなのに対して、500 FHDはUSB-Cコネクタに挿す形式(USB-C to USB-Aケーブルが付属)で、この方が自由度は高いですが、ケーブルが宙を走ることになって収まりが悪い面もあり、良し悪しという気がします。
2. 機能
カメラには4つ窓があって、中央から左側に向かって普通のカメラ、赤外線カメラ、赤外線ライト、プライバシーライトです。右側にも何かありそうに見えますが、ここには中にプライバシーシャッターがあるので、センサーはないです。
このシャッターは上のつまみを押さえて横にスライドさせると、中のシャッターも動く仕組みです。
シャッターには赤丸があるので、よく見れば閉じているのが分かります。ただ、カメラに赤丸は一般的には録画中を示すサインなので、閉じている状態を示すにはUI的にどうかなという気がします。つまみの大きさから見て、頻繁に変えるというより念のために付いている感じですが。
普通のカメラの撮影中はプライバシーライトが点灯します。
Windows Helloの認識中は、赤外線ライトが点滅します。色はSurface Proと同じく赤ですが、光はもっと強いです。認識はうまく行けば一瞬なので、Surface Proと変わりません。
画質
500 FHDの普通のカメラは、基本スペックとしてはFull HD(1920×1080)で、C920sの1080pモード、Surface Pro 4のフロントカメラと変わりません。
画質については……自分ではそれほど差が分からないというのが実際のところです。C920sはさすがに自動調整がうまく効いているぐらいは分かりますが……一番古いSurface Pro 4のカメラでも映りは悪くないと感じるので。試していて気づいたのは、むしろ映りにダイレクトに影響するのは、カメラというより照明の方かなと。
なお、LogicoolのLogi Captureのようなカスタマイズソフトは付属しません。余談ですが、Logi Captureは、使ってみるまで知らなかったのですが、カメラの設定ソフトではなく、それ自体がカメラ入力を受けて画像をリアルタイムに加工して他のソフトに出力するもので、当然リソースを結構使うのですよね。カメラ入力は他のソフトで直接受けられるので、画像にこだわりがなければ使わなくていいかなと。
互換性
試した範囲では、Microsoft Teams、Cisco Webex、Zoomで入力元に使えるのを確認しました。
なお、C920sとは違ってマイクはありませんが、個人的には別に求めていないので問題ありません。
3. Windows Helloカメラの切換え
自分は数年来、Surface Pro 4に外部モニターを接続して使っていますが、そのときにはSurface Pro 4の画面に被せる形にするので、Surface Pro 4に内蔵のWindows Helloカメラは使えなくなります。これが500 FHDを購入した理由ですが、実はWindows 10には複数のWindows Helloカメラを切り替える機能がないらしく、500 FHDを接続してもそのままではWindows Helloに内蔵カメラを使おうとします。
対処療法として、内蔵カメラをデバイスマネージャーで無効にしてしまえば、代わりに500 FHDが使われるようになるのが分かったので、500 FHDの有無に応じてこれを自動化するツールとしてHello Switcherを作成しました。 注意点として、OSのサインイン前には動作できないので、前回サインアウト時の最後の状態は次回サインイン前には変更できません。具体的なケースで言うと、前回サインアウト時に500 FHDがある状態だった場合、内蔵カメラは無効化されているので、次回サインイン時に500 FHDがない場合は、有効なWindows Helloカメラが存在しないことになり、Windows Helloが使えません。こういう場合はPIN認証などでサインインして下さい。サインイン後にこのツールが実行された際に内蔵カメラは有効化されます。
4.評価
まとめると、良い点は以下のとおりです。
- ミニマルですっきりしたデザインがとても良い。
- Windows Helloカメラとして問題なく使える。
- 普通のカメラとしても使える。
- カスタマイズソフトは付いてこない。
- マイクはない。
2020/05/01
スマートフォンのモニター用マウント
スマートフォンをウェブカメラの代用としてモニターに固定する方法を思案して工作したところ、これが意外といい出来だったので残しておきます。
モニターはDellのU2720QMで、これにキングジムのDB-200から工作したマウンタを置いて、moto g7を固定したところ。
穴はg7がモニターの筐体のアールに合う位置にしてありますが、これは先に試して、このアールに合わせると角度的に丁度いいことが分かっていたので。
DB-200の足は角度を無段階に調整できるように見えますが、実際は中にラッチが仕込まれていて無段階ではなかったので、ゴムワッシャーを間に挟んで自由に調整できるようにしています。これでカメラの角度を多少調整することも可能という見込み。
正面からはこんな感じ。
カメラのモニター上端からの距離は22mm程度なので、ボール雲台式のウェブカメラと同程度です。位置をこれ以上下げるとカメラの視界にDB-200の前端が入ってくるので、DB-200を削る必要が出てきます。
なお、この状態でもあらかじめアイコンが上に出るよう配置しておけば基本的な操作は可能。
これでスマートフォンの固定自体は満足できる状態になりましたが、実際に使っているとスマートフォンを代用することによる遅延が気になってきたので(DroidCamXを720pで使用)、注文してあるウェブカメラが到着すれば使用終了の予定。
モニターはDellのU2720QMで、これにキングジムのDB-200から工作したマウンタを置いて、moto g7を固定したところ。
- DB-200の前面にある小物入れというか樋部分は、狭額縁のモニターだと表示域にかかり(サイトの説明では5mmとなっているが、実物は6.5mmあった)、かつ間に挟んで上にずらしても庇みたいになって邪魔なので、3mmぐらい残して切除。
- スマートフォンのカメラの位置をなるべく下げたかったので、g7に合わせて現物合わせで穴を開けて嵌め込むようにした。
- 固定はg7の軟質ケースの弾性による。
穴はg7がモニターの筐体のアールに合う位置にしてありますが、これは先に試して、このアールに合わせると角度的に丁度いいことが分かっていたので。
DB-200の足は角度を無段階に調整できるように見えますが、実際は中にラッチが仕込まれていて無段階ではなかったので、ゴムワッシャーを間に挟んで自由に調整できるようにしています。これでカメラの角度を多少調整することも可能という見込み。
正面からはこんな感じ。
カメラのモニター上端からの距離は22mm程度なので、ボール雲台式のウェブカメラと同程度です。位置をこれ以上下げるとカメラの視界にDB-200の前端が入ってくるので、DB-200を削る必要が出てきます。
なお、この状態でもあらかじめアイコンが上に出るよう配置しておけば基本的な操作は可能。
これでスマートフォンの固定自体は満足できる状態になりましたが、実際に使っているとスマートフォンを代用することによる遅延が気になってきたので(DroidCamXを720pで使用)、注文してあるウェブカメラが到着すれば使用終了の予定。
登録:
投稿
(
Atom
)











































