九月の日記/メモ

 

2010.09.20(月) 21:15:34 System.ApplicationUserModel.ID

5月から自宅の主力マシンでWindows7を使っていて、どうせ何も考えずに作っていてどうにもならないのだろうなぁと思っていた事に解決方がある事を知った。

以下のページがそれ。

Emacs (NTEmacs) 23.1 をWindows 7上で少し快適に使う - Part.2
http://blog.lifeflow.jp/2009/12/emacs-ntemacs-231-windows-7-part2.html
Emacs を Windows 用にビルドした emacs.exe は、コンソールアプリになっているので、直接起動すると要らないコンソールウィンドウが表示されて邪魔になる。それを避けるために、スタートメニューに登録されるショートカットは runemacs.exe という別のプログラムでコンソールを表示しない設定を適用しつつ emacs.exe を起動するという事になっている。
起動した Emacs をタスクバーにピンすると、emacs.exe の方が登録されるので次にタスクパーから Emacs 起動すると余計な窓が表示されるという事になってしまう。一方手動で runeamcs.exe の方をタスクバーにピンしてやると、今度は Emacs を起動した時にタスクバーの Emacs のアイコンが分裂してしまう。これは runemacs.exe と emacs.exe が別物として扱われるからである。
で、どうしたら同じものとして扱われるようにすることが出来るかというのが問題で、上のページにもあるように、マイクロソフトのページ(アプリケーション ユーザー モデル ID (AppID) にヒントがある。※このページを見ても既に分かっていない限り説明としてはほとんど理解不能だと思われる。

つまりショートカットに System.AppUserModel.ID とやらを設定すればよい。のだが、 どういう訳かこれをするためのUIも設定プログラムも用意されていないらしい。

上述のページにGUIなツールがあるのでCUIなツールを作った。
バイナリ:appumid.exe ソース:appumid.cpp
Emacs/NTEmacs の場合は、GNU.Emacs と設定すればよい。 タスクバーにピンしたアイコン(ショートカット)は、 %USERPROFILE%\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar にある。
※しかし、何でこんなパスになってしまったのか不思議。Microsoft\Windows\TaskBar でいいじゃないか。

もう一つの例は、gdipp というアプリケーションのフォントのレンダリングを改善するソフトと Firefox の組み合わせ。
gdipp の gdipp_loader_32.exe をロンチャとして firefox.exe を起動する必要があるのだが、ここで上と同じ問題(アイコンが分裂する)が起きる。

Firefox の場合はインストール時に適切に作成されたショートカットには、AppID が設定されているので、それをドラッグして来てタスクバーに登録すれば問題ない。はずだが、アップデート時に正しく更新されない事がある様子。

Firefox の AppID は、インストールディレクトリにある application.ini ファイルに定義されている Vendor, Name, Version を . で区切って連結したものになっている。 例えば Firefox 4.0b6 の場合、Mozilla.Firefox.4.0b6 となっている。

実は Emacs についても、gdipp を使った方が字が綺麗になるのだが以下の問題がある。
gdipp_loader_32.exe → runemacs.exe → emacs.exe とすると gdipp が効かないし、
runemacs を改造して runemacs.exe → gdipp_loader_32.exe → emacs.exe とすると、余計な窓が表示されてしまう。
仕方がないので runemacs.exe と gdipp_loader_32.exe のソースを用意して、runeamcs で CreateProcess() に渡している引数を gdipp_loader_32.exe の方にコピペして emacs.exe 起動用の改造版 gdipp_loader_32.exe を作成して解決した。

残る課題はAdobe AIRなアプリケーションのAppIDを調べる方法を見つける事。
SHGetPropertyStoreForWindow() では他のプロセスのウィンドウから値を取得できない様子だった。なにか呪文が足りないのかも知れない。

ところで、System.AppUserModel.ID なんて名前の割に .Net や WSH でちゃちゃっと変更できるようにはなっていないのだろうか? 探した範囲では見つからなかった。

2009年十一月の日記/メモ