2013年01月29日

デバイスを引っこ抜いたらWindowsをシャットダウンするアプリ

 また、どこに需要があるのか不明なアプリを作ってしまったが…。デバイス接続状態を検出してWindowsを制御するアプリである。
これ

【そもそもは】
 携帯で再生した音楽を、WindowsPCのBluetoothでA2DPで受けて、スピーカーから再生するようにする(先日のやつを車から出してきて、シームレスに使おうという肚である)。で、使うと、間違いなくWindowsのシャットダウンを忘れて電気を無駄遣いするのが容易に予想される。そこで、Bluetoothのデバイスを監視して特定のペアリングが切れたらシャットダウンを発行するアプリがあればいいんじゃないかろうかと思いつく。で、探してみたけどどうもなさそうなので、じゃあ手っ取り早く作るかと思って、コードを書き始めた。
 だが、Bluetoothは(自作に)よくない。
 Bluetoothのスタックが何種類も(Microsoftのと、東芝のと、WIDCOMMのと、BlueSolielのと。他にもあるのかもしれん)あって、それぞれAPIもSDKも別である。簡単に使えるのはMSの標準で付いてるスタックだが、MSスタックではA2DPが食えない。家のはWIDCOMMスタックを入れてA2DPを動かしたが、当然MSのAPIでは扱えない。いちいちSDKをゲットしてドキュメントを読んで、結局WIDCOMM専用のアプリにしかならないと思うと気力が萎えて、沙汰止みとした。
 
【思い直した】
 単にデバイスがあるかどうかが取りたいだけなのにになんでこんなに困難なんだと思っていたが、後日気がついた。
 Blutoothとかは関係なく、Windowsに接続されているデバイスを直接見れば何とかなるんじゃない?それだとBluetooth以外のデバイスにも対応できるし、その方が汎用じゃない?
 具体的には、SetupDiEnumDeviceInfoしてSetupDiGetDeviceRegistryPropertyして、さっきと今を比べたら、デバイス引っこ抜いたのが分かるんじゃない?

 と、いうわけで、ざくざくとアプリを作ってみた。
 特定のデバイスを引っこ抜いたり、接続したりした時に、それに反応して、シャットダウン/ログオフ/サスペンド/休止状態/パワーオフまたはユーザー定義アプリを実行する。
 定期的にデバイス一覧を取っては比較、デバイスのユニークネスは、SPDRP_CLASSGUIDSPDRP_HARDWAREIDの0番目で見る。従って、着脱時にデバイスマネージャーに出没して、HARDWAREIDがユニークなデバイスなら、使用可能のはずである。例えばUSBメモリースティックとかね。


 携帯をBluetoothをA2DPでペアリングすると、音量とかを操作するヤツがHIDデバイスで出没するので、こいつを捉えて初期の目標を達成した。他にどんな使い道があるのか分からないが、せっかく作ったので公開しておく。

ByDHalt デバイス接続状態を検出してWindowsを制御


 誰かの役に立てば幸い。

posted by usoinfo at 17:28 | Comment(1) | 開発 | このブログの読者になる | 更新情報をチェックする

2013年01月11日

電源連動音楽プレーヤー

 自動車の運転中に音楽を流すのに、長いことWindowsCEベースのPDAを使い、GetSystemPowerStatusで給電が止まったらサスペンドする自作ソフトを走らせて、エンジンが止まったら再生が止まりエンジンを掛けたら止まったところから再開されるようにしていたのだが、そのPDAが壊れてしまった。もう古いアーキテクチャであるから、中古市場にも格安のWinCEベースのデバイスは出回っていないので、調達することもできない。
 そんな古いものをいつまでも使っていたのは理由があって、自動車内で普通のメモリプレーヤーを使おうとしても、これがなかなかうまくないからである。してほしいことは単純で、エンジン切ったら止まり、エンジン掛けたらそこから再生してくれればいいのであるが、電源が切れたら再生を中断するようなメモリプレーヤーは、全然ないのである。これでは車から降りるときいちいち停止ボタンを押さなくてはならない。当然のように押し忘れるので、再生位置をロストして悲しいことになる。
 じゃあというので、Androidのアプリでそういうものがないのかと探したが、探し方が悪いのか、あんなに山のようにアプリがあるのに、給電が切断されたら一時停止、という、ごく簡単な機能を持つプレーヤーのアプリがないのである(イヤホンジャックを抜くと一時停止、というのはある。VideoLAN for Androidとか。)
 
 こうなれば是非もない、ないのならば自分で作るほかあるまい、ということで、Android用の電源状態に連動する音楽プレーヤーアプリを作った。ごくシンプルなプレーヤーである。自動車内で触らずに音楽を流す、という用途しか考えていない。ボタンがやたらとデカいのは、運転席上での操作が前提だからである。

cap_jp_net_usost_einterlockplayer_free.png


 シガーソケットからUSBを取るやつと電源ケーブルをつないで再生して、エンジンを切ると給電がオンからオフになるので再生を停止する。エンジンを掛けるとオフからオンになるので再生を再開する。これで停止ボタン押し忘れの呪いから解放されるはずである。 
 せっかく作ったので、今回GooglePlayにデベロッパー登録してアプリを公開してみた。



 デベロッパー登録は、$25かかるのな。なんかでアプリで収益をあげて、せめて登録料分くらいは取り返したいものだが。
posted by usoinfo at 19:14 | Comment(1) | 開発 | このブログの読者になる | 更新情報をチェックする

PHPでそのホストで実行中のプロセス一覧を取得(Linux)

バックグラウンドで処理をさせていた時など、特定のコマンドやらpidやらのプロセスがあるかどうかを調べたい時があるので、ぱぱっと。
function Unix_GetPidArray()
{
$ret = array();
$cmd = "/bin/ps -e -o pid,args";
$fp = popen($cmd, "r");
while( ($line = fgets($fp)) != false ){
$line = ltrim($line);
$pos = strpos($line, " ");
$pid = intval(substr($line, 0, $pos));
$args = substr($line, $pos+1);
if( $pid <= 0 ) continue;
$ret[] = array(
'pid' => $pid,
'args' => $args,
);
}
fclose($fp);
return $ret;
}
実行結果例
$r	= Unix_GetPidArray();
echo var_dump($r);
--
Array
(
[0] => Array
(
[pid] => 1
[args] => /sbin/init
)
[1] => Array
(
[pid] => 2
[args] => [kthreadd]
)
[2] => Array
(
[pid] => 3
[args] => [migration/0]
)
[3] => Array
(
[pid] => 4
[args] => [ksoftirqd/0]
)
...略
ps -eを実行した結果をバラして格納しているだけである。/bin/ps -e -o pid,args を実行してみて、[プロセスID]半角スペース[コマンド....]の書式になればそのまま使用可能。違ったときは環境に合わせて$cmdを調整。
応用で、プロセスID(int値)を与えるとそのpidがあるかどうか(ps -ef|grep 1111|wc -l 的なもの)、文字列を与えるとその文字列を持つコマンドのプロセスIDを列挙(ps -ef|grep ahoaho 的なもの)の関数。
function Unix_IsPidExisted($pid)
{
$ret = false;
$cmd = "/bin/ps -e -o pid";
$fp = popen($cmd, "r");
while( ($line = fgets($fp)) != false ){
if( intval(trim($line)) === $pid ){
$ret = true;
break;
}
}
fclose($fp);
return $ret;
}

function Unix_GetPidStringMatched($str)
{
$ret = array();
$cmd = "/bin/ps -e -o pid,args";
$fp = popen($cmd, "r");
while( ($line = fgets($fp)) != false ){
if( strpos($line, $str) === FALSE ) continue;
$ret[] = intval(substr(ltrim($line), 0, strpos(ltrim($line), " ")));
}
fclose($fp);
return $ret;
}

/*
実行例:

$ret = Unix_IsPidExisted(4566);
// PID 4566 が存在すれば true が返る

$ret = Unix_GetPidStringMatched('httpd');
// args に httpd を含むPIDを列挙した配列が返る

*/

タグ:Linux PHP
posted by usoinfo at 09:28 | Comment(1) | 開発 | このブログの読者になる | 更新情報をチェックする