2011/12/27(火).NETのSerialPortでケーブルを抜くと例外

.NET(WinXP, .NET 3.5で発生)のSerialPortクラスで、USB-Serial変換ケーブルを使用している際に起こる問題。このケーブルに紐づくCOMポートをOpen()後、Close()前にケーブルを抜くと例外が発生する。

原因は.NET側のバグ。ケーブルの挿抜というかCOMポートが消えることを考慮していない。

発生する例外は把握している限りで2種(UnauthorizedAccessException, ObjectDisposedException)。前者は、Dispose()中に発生する。後者は、SerialPort内部で動いてるThreadが出してくる。

UnauthorizedAccessExceptionはラッパークラスを作って、Dispose()をオーバーライドしtry~catchで囲ってやることで対処可能。以下を参照。簡単なのでコードは書かない。

街角のリブロガー: C# SerialPortのエラー「UnauthorizedAccessException」対策

ObjectDisposedExceptionの方はちょっと難しい。発生箇所は.NET内部の別スレッドのようで、捕まえられる場所を思いつかない(存在しない?)しタイミングも不定。Thread.GetDomain().UnhandledExceptionで発生タイミングはとらえられるが、ここではキャンセルできない。古い.NET、おそらく1.1以下だとこの手の例外は処理継続となるのだが、.NET 2.0以降はアプリが落ちてしまう(WinXP/Win7, .NET 3.5で確認)。

ということで、どうもコードでの容易な対処方法がないようだ。アプリケーション構成ファイルでの回避策があるらしいので以下を参照。

SerialPort Crashes after disconnect of USB COM port | Microsoft Connect

こんな感じでよい。

program.cs
[STAThread]
static void Main()
{
	...

	//メインスレッド以外の非ハンドル例外処理
	Thread.GetDomain().UnhandledException +=
		new UnhandledExceptionEventHandler(Application_UnhandledException);

	...
}

public static void Application_UnhandledException(
	object sender,
	UnhandledExceptionEventArgs e
){
	if( e.ExceptionObject != null &&
		e.ExceptionObject.GetType() == typeof(ObjectDisposedException)) {
		
		//.NET3.5のSerialPortのバグで、ケーブル挿抜後にハンドル不能の
		//ObjectDisposedExceptionが返ることがある。このため、未ハンドル例外処理にて
		//ObjectDisposedExceptionについてのみ無視する。

		//何もしない
	} else {
		//何かメッセージを出力
		
		Application.Exit();
	}
}
以下のアプリケーション構成ファイルをアプリケーションと同じディレクトリに置く(hoge.exeが実行ファイルなら、hoge.exe.configとなる)。

hoge.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<runtime>
		<legacyUnhandledExceptionPolicy enabled="1"/>
	</runtime>
</configuration>
構成ファイルを上記のように書くと、非ハンドル例外に関しては処理継続となる。釈然としないが、どうもこれが楽な方法らしい。

その他の非ハンドル例外を無視して良ければ、program.cs側の記述は不要。

.NETのバージョン変更、OSの変更で直る可能性有り。

2011/12/16(金)F904iの電話帳移行メモ

2011/12/16 15:00 PC(全般)
長らく使っていた、docomo F904iが故障してしまった。

故障状況はこの記事と直接関係ないのだが一応書いておこう。どうもアンテナ周りに問題が発生したらしく、屋外なら良いのだが屋内に入るとまず圏外になる。softbank,WiMAX,e-mobileが問題なく通信できる場所でもあっさり圏外になるのでdocomoと契約している意味がない。電池の消耗も異常に早い(電波を必死につかもうとするから?)。

同様の不具合は「F904i 圏外」で検索すればいくらでも出てくる。要は設計として部品耐久性に問題があったということのようだが、docomo側では使用3年超は無償での交換・修理は不可ということだった。

閑話休題。

今はdocomoガラケーとsoftbank iPhoneの2台持ち。状況を見極めつつ契約をスマートフォン1つに一本化したいのだが今は高速回線黎明期だったりしてタイミングが悪い。しゃーないので、確保してあった0円ガラケーことL-03Bに移行することにする。

前置きが長かったが、このとき電話帳を移行するのにちょっと手間だったのでメモ。

何が手間だったかというと、docomoの汎用Datalinkソフト(ドコモケータイdatalink(データリンク) | NTTドコモ)がF904iを認識してくれない。対応機種表にはあるのにだ。メーカのdatalinkソフト(携帯電話(データリンクソフト) ダウンロード - FMWORLD.NET(個人) : 富士通)からは認識できるし、こっちのページにはF905i以降は~docomoのでと書かれているから汎用datalink側の対応機種表が間違っているのだろう。L-03Bは汎用datalinkソフトで認識した。

ということで、メーカのdatalinkソフトで電話帳を抽出することにした。この時フォーマットの選択肢がcsvとvcf(vCard)とあるのだが、csvで吸うとグループが取得できない。グループが維持されないと大変困るのでvcfで吸ったのだが、今度は汎用datalinkでL-03Bに転送する際にこのvcfを取り込む方法がない。

ということで、自前スクリプトでvcf→csvに変換し、これを汎用datalinkソフトに取り込んでL-03Bに転送した。

iPhoneだとvcfをメールに添付→端末側で開く、でも移送可能(グループは消えるし、変なメモが作られるけど)なので、もっと簡単な方法もあるに違いない。まあ、とりあえずこれでできたということだけメモ。

素直にdocomoショップ行くのとどっちが早かったか…

2011/12/16(金)ICQのログ発掘

2011/12/16 14:24 PC(全般)
かなり今更だが、ICQのログを参照する機会があったのでちょっとメモ。

ICQは各バージョンデータの保持形式が違う上、少なくとも2003bくらいまではログの書き出し機能もなければプラグイン等での対応もできなかった(はず)。ログを参照するだけならICQをインストールし直せば見られるのだが、日付からの検索ができるだけで一括エクスポートなんかができない。

ということで何らかの方法で抽出しないといけない。サーベイするとだいたい候補が2つ。

ICQ バックアップ

Belkasoft ICQ Analyzer

上は無料、対応バージョンが限定(完全に確認してないが99~2001(2002も?)と思われる)。ICQがインストールされている必要がある。使い方が難しい。

下は有料、簡単、対応バージョンはたぶんすべて。チャットログ以外に、承認要求やファイル転送ログもとれそうだ(ただし一部文字化けするっぽい)。ICQのインストール不要。

他に、ABC Amber ICQ Converterというのもあったのだが、Belkasoftに機能面で負けてそうなので割愛。

今回取り出したいのは、99b~2001bとちょうどICQバックアップの対象範囲に合致したので、とりあえず上で試すことにした。

ICQバックアップはICQがインストールされている必要があるので、まずICQをインストールする。ただしバージョンに制約があるので注意。2003とかだとうまく抽出ができない。なんとかICQ2001b辺りを探して来てインストール。

次に、抽出したいログを含む
  • アカウント番号.dat (cf. 11111111.dat)
  • アカウント番号.idx (cf. 11111111.idx)
を含む2001aだとかDb99bとかのフォルダをインストールした場所に全部突っ込む。

これでICQバックアップを立ち上げると、自動認識して対応範囲のバージョンのログは抽出できる…はず。

やってみたところ、だいたい問題なくとれたようなのでこれで良しとする。

なんかめんどくさかったのでおとなしくあきらめるとか、Belkasoftに金払った方がよさそう(ICQ History Extractorという旧製品もあり、こちらはAnalyzerよりだいぶ安い。まだPurchaseできるならこちらか)。

2011/12/09(金)TVTestが終了時に落ちてその後の録画に失敗する

2011/12/09 16:54 PC(全般)
TVTestが原因と思われる録画失敗が多発しているため、前回の残件も含めてちょっと調査してみた。
[状況]
  • TvRock0.9u2 + TVTest0.7.23(Win7 x64) + PT2
  • 特定の入力デバイス(地デジ1なら地デジ1)に割り付けられた予約がある時刻から失敗している。
  • 確認してみると、TVTestが不応答状態で残っている(そのデバイスに割り付けられたもの)。
  • 録画ファイルが生成されていない(0bytesですら残っていない)
調査対象はTVTest0.7.15, 0.7.17, 0.7.18r3, 0.7.20, 0.7.21r2, 0.7.22r2, 0.7.23

まず、先日と同じく、コマンドラインは
>tvtest.exe /rec /recfile "test%test.ts"
で調査する。

[1]録画ファイル化けの問題。
  • 0.7.15-0.7.20は"test%test.ts%"になり化ける。
  • 0.7.21r2-0.7.23は"test%test.ts"になり正常。
[2]TVTest落ちの問題。
ドライバも何もない状態で起動し、数秒後に録画停止ボタンを押して録画停止する。
  • 0.7.15-0.7.17は正常に停止する。
  • 0.7.18r3-0.7.23は異常終了(ハンドルされていないWin32例外)する。
ここで、異常終了するケースで色々試してみると、
  • "/recexit"オプションを付けると異常終了しない。
  • ファイル名に"%"を含まない場合は異常終了しない。
"%"については残件調査のつもりで始めたのだが、ここで原因が確定してしまった。"%"を含むファイル名で録画すると、TvRockからTVTestの終了に失敗する。そうすると、手動でこのプロセスを落とすまで以降このTVTest側に割り付けられた予約がすべて失敗するということのようだ。具体的には前回と同じく、"うたの☆プリンスさまっ♪マジLOVE1000%"が原因で、その後に来た"UN-GO"と"ギルティ クラウン"が失敗したということになる。この話どうでもいいな。

"/recexit"を付けるとなんか改善するのは現行TVTest/RecTestの常っぽい(RecTestでも類似バグがあった)。

運用に関してはとりあえず/recexit付けて様子を見ることにする。改善要望出して、ソース読める時間とれたらもうちょっと解析してみよう。DirectX SDKとDirectShowのBaseClasses入れないといけない……

2011/12/06(火)HSV解析メモ

2011/12/06 9:32 PC(全般)
画像をHSV値で眺めたり分析したりしたいときがある。
その際使用するツールとかのメモ。
  • 各画素値を取るなら
    • 自前で書く。
  • ヒストグラムを見たいなら
    • PaintStar(DPExの方が見やすいけどシェアウェア)
  • チャンネル毎に分解したいなら
    • GIMPで色→色要素→チャンネル分解
  • 色のピックアップ
    • Photoshopでも何でも。
なお、自前で書く際に.NETを使用する場合、GetPixel()が天地を貫くほど遅いので、
Mr.Exception 画像処理にGetPixel/SetPixelを使っていませんか?
などを参考とすること。

OpenCV周りもそろそろ触らないとなあ。

チャンネル分解でHレイヤーに色つけてくれるツール募集中(ImageNosでできそう?)。

2011/12/01(木)awstatsの更新がおかしい

2011/12/01 22:13 PC(Linux)
メールをよみがえらせてみたら、こんなメッセージが山ほど来ていた。
Create/Update database for config "/etc/awstats/awstats.conf" by AWStats version 6.95 (build 1.943)
From data in log file "/var/log/apache/access.log"...
Error: Couldn't open server log file "/var/log/apache/access.log" : Permission denied
Setup ('/etc/awstats/awstats.conf' file, web server or permissions) may be wrong.
Check config file, permissions and AWStats documentation (in 'docs' directory).
うへえ、awstatsの更新が死んでる。……あれでもおかしい、awstats自体はちゃんと最新のデータを取ってきてる。しかしメールは続々来る。なんだこれはと調べてみたら、/etc/cron.dと/etc/cron.hourlyにそれぞれawstatsのスクリプトがあった…… orz。

片方が成功、片方が失敗して正常な更新とエラーメール(受け取れてなかった)を延々続けていたのか。なんだそれ!

awstatsは確か当初ソースから入れたので残っていたのかもしれない。パッケージに切り替えたときに旧cron設定を消し忘れたのだろう。

ということで、
$ dpkg -L awstats
で調べつつ、
cron.hourlyの古いスクリプトを消し、パッケージから入っていると思われるcron.d側を残した。

この状態でまだエラーメールが来るので、/etc/cron.d/awstats中のユーザ指定をaccess.logのユーザに書き換え。

更新成功し、エラーメールもなくなった。

2011/12/01(木)メールがローカルに配信されない

2011/12/01 14:01 PC(Linux)
しばらくほったらかしにしてたメールを久々に触ってみようと思ったら、何かとんでもないことになっていた。
# qmail-qstat
messages in queue: 54682
messages in queue but not yet preprocessed: 54680
最初はすわ不正中継爆弾? とか思ったのだが、
# cat /var/log/mail.log
1218742:Dec  1 10:19:04 debian qmail: 1322702344.535144 warning: unable to create local/8/1656100
...
おおう、これはローカルへの配信ができずに延々ループしてるっぽい。そしてmail.logのサイズがどんどんふくらんでいる。そこで、/var/spool/qmail/local/をのぞいてみたら、

空っぽ!

え、分割ディレクトリはどこへ行ったの?

分割ディレクトリを自動的に作る機能はなさそう…… しかし、分割ディレクトリがないのが原因っぽい。

ということで、分割ディレクトリを標準の23作成する。
# mkdir 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
して、chmod,chown,chgrpしたところ…… 動き出した。
ログをチェックして、warningが消えたことを確認

えー、なんだこれ。手で消した記憶はないので、update時に何かが消してしまったのかqmailの仕様が変わったのか。

うーん原因までは追えなかった。

一応解決。

2011/12/01(木)/dev/sdaが無い!

2011/12/01 11:37 PC(Linux)
起動時にデバイスノード/dev/sda, /dev/sda1, /dev/sda2が作成されない問題。

環境を整理すると、
kernel: 2.6.34.1(自分でコンパイル)
udev: 164-3
HDD: SATA HDD(内蔵)

/sys/block/sda/, /sys/block/sda/sda1/, /sys/block/sda/sda2/はできており、fstabsでのマウントも成功している。

これなら起動時にデバイスノードが自動的に作成されることを期待するのだが、なぜか作成されない。デバイスノードがないとfdiskとかできないので大変にまずい。

どうも1月にsqueezeに入れ替えたときから発生していたような気配だ。fstabsはUUIDで書いていたので、今まで問題が起こらなかった(もしくは気づかなかった)。

さて、squeezeからデバイス割り当ての仕組みがudevに変わっている。この移行に関しては注意書きが手順書に書かれるくらいなので大きな変更なのだが、一応これは気をつけてカーネルを作り直したつもり。起動はするし、警告も出てる気配がないのでこれはudevとsysfsの連携が単にうまくいっていない。

で、調べてみると、
[Sorcerer-admins] udev does not create sda, sdb and md0
完全に追えてないのだが、以下自分の解釈。udevの元々の仕組みはデバイスのモジュール組み込みを想定しているためモノリシックカーネルの対応が不十分な場合があるとのこと。あちこち回ってみると、udevのバージョン変更で直った例が多いようなのだが、debianは相変わらずtesting=unstableだし、依存関係がもうすンごかったので断念。うーん、推奨環境(カーネルもdebianのものを使用)じゃないのでバグ報告がためらわれる。しょうがないので、まずはコマンドラインで、
# cat  /sys/block/sda/dev /sys/block/sda/sda1/dev /sys/block/sda/sda2/dev
8:0
8:1
8:2
としてメジャー・マイナー番号を調べ
# mknod /dev/sda b 8 0
# mknod /dev/sda1 b 8 1
# mknod /dev/sda2 b 8 2
とした。

で、これを起動スクリプトに追加。
$ cat /etc/init.d/mk_sda_node
#!/bin/sh

if ! [ -e /dev/sda ]; then
        mknod /dev/sda b 8 0
        mknod /dev/sda1 b 8 1
        mknod /dev/sda2 b 8 2
fi

exit 0
雑にこんなんでいいや。すでにデバイスノードが存在してればmknodは特に問題は起こさないようだし。ずれることもないだろう(udevを頭から否定)。
update-rc.d mk_sda_node start 15 1 2 3 4 5 .
debian流で登録。single user modeでもあった方がいいでしょ。
update-rc.d: warning: /etc/init.d/mk_sda_node missing LSB information
update-rc.d: see <http://wiki.debian.org/LSBInitScripts>
 Adding system startup for /etc/init.d/mk_sda_node ...
   /etc/rc1.d/S15mk_sda_node -> ../init.d/mk_sda_node
   /etc/rc2.d/S15mk_sda_node -> ../init.d/mk_sda_node
   /etc/rc3.d/S15mk_sda_node -> ../init.d/mk_sda_node
   /etc/rc4.d/S15mk_sda_node -> ../init.d/mk_sda_node
   /etc/rc5.d/S15mk_sda_node -> ../init.d/mk_sda_node
LSBがらみは今度調べよう。

再起動してデバイスノードがあることを確認。うーん、次期wheezyまでこれでしのぐか…

2011/11/15(火)PDF内の画像フォーマット

2011/11/15 15:26 PC(全般)
前記事の付随記事。
画像で構成されたPDF内の画像フォーマットを調べたい。

なんとAcrobat X Proでは表示する方法がない(!?)。

現状これができるツールがみつけられなかったが、とりあえず調べ方はわかった。
テキストエディタでPDFの中をのぞく。
<< /Type /XObject /Subtype /Image /Name /Obj4 /Width 1811 /Height 2365 
/BitsPerComponent 8 /ColorSpace /DeviceRGB
/Filter /DCTDecode /Length 634114 >> 
stream
こういったエントリがあるので/Filterのところをチェック。こいつはDCTDecodeなので結局JPEG。うーん、FlateDecode(可逆圧縮)を期待していたのだが……

他のフォーマットは、ここでも参照してほしい。

さて、この場合Acrobat X Proで名前をつけて保存->画像->JPEGとやると、品質設定如何に関わらずオリジナルのJPEG(上記の場合1811x2365 634114bytes)のファイルを抽出できる。

かなりブロック・モスキートノイズが飛んでいる。このJPEG、品質はどれくらいで作られたのか調べたい。量子化テーブルの話なので、逆算は必ずしも正確ではないだろうが大まかの当たりをつけたい。

info_JPEGというソフトで調べられるという話なのでこれを使用。品質は60だった。

このソフトを信じるならこの数字。自分の見た目としての実感も60~70くらいかなという感じなので、大きく外してはいないだろう。

なお、GhostScriptを経由したIrfanView等では、この画像サイズがとれないのか出力指定解像度でしか抽出できなかった。安定してやるならAcrobatでやるのが良い。

2011/11/15(火)ブックメンテナンス秋葉原に行ってきた

2011/11/15 14:52 PC(全般)
ブックメンテナンス秋葉原に2回ほど行ったので、機材のクセや使用方法について思うところをメモしておこうと思う。

今回の目的は自宅にあるA4超サイズ雑誌切り抜き(2000年以前)のデジタル化。現時点(2011/11/15)で、この作業においてライセンス&法律に抵触することはないと理解している。

ブックメンテナンス秋葉原は基本的にレンタル機材サービスをしている店だ。使用料を払って機材を一定回数、もしくは一定時間借りる。機材を使用するのは基本的に客であるが、店員がガイドあるいは手伝いをしてくれるときもある。機材としてはドキュメントスキャナが主体であるが、紙揃えや裁断機等々機材の種類も多くちょっと変わったラインナップになっている。性質としてはKinko'S等に近いものがあり、コピーサービスの特殊拡張と思うとわかりやすい感じだろうか。価格設定はかなり高めだが業務用高級機がそろっており、ここのバランスをどう見るかは人次第であろう。特にA3ドキュメントスキャナはコンシューマー用製品がほとんど無いため、これを使える点はメリットとなる。

今回この店を使用することにしたのは、A4超の切り抜きが大量発掘されてしまったことに端を発する。自宅にあるドキュメントスキャナ(fi-6130)ではA4までしか対応しておらずどうしようかと思案していたのだが、ちょうどこの店の話を聞きつけたので話の種に使ってみることにした。

料金表は店のHPを見て欲しい。ただ、説明不十分なところが多々あるため疑問点は電話で確認しておくといいだろう。

自分が使ったサービスでいうと紙揃え(空流で紙をそろえる)(無料。裁断の100円に含まれると理解)。裁断(手動)(1回100円)。スキャン(低速)(10分500円)。

紙揃えは店員がやってくれ、裁断はセットまでやってもらった。基本的には慣れるまでは手伝ってもらう形になると思う。裁断機はレジ付近にあるので、中身を見られたくない人は裁断は自前でやった方が良いかもしれない。これらの支払いは直接レジに現金で支払う。

低速スキャンブースはPC+コインタイマー+ドキュメントスキャナの組み合わせ。低速ブースでもCanon DR-9080CというA3対応業務機(定価100万円以上)がおいてある。事前にCapturePerfectのマニュアルくらいは読んでおいた方が良いかもしれない。スキャンブースは狭く、しかも足下にスキャナが置いてあるため蹴らないように注意。スキャン物を入れるためのかごを店内で貸してもらえるが、サイドに置くと隣のスペースに侵犯するため混んでるときはどうするのか疑問。荷物があるともうどうしようもない気がする。

PCからUSBの挿入口(メス)が机の上に取り回されているので、そこにUSBメモリやUSB HDDを挿すことができる。スキャンしたデータはそこから持ち帰ることになる。何度か使ってみて考えたのだが、(電源容量が足りれば)USB HDDを持って行くのがベストのようだ。標準では書き出し先がマイドキュメントになっているのだが、PC自体のスペックが余り高くないようでマイドキュメントから移そうとするとかなり時間がかかる。持ち込んだメディアに直接出力するのが良い。フラッシュメモリ系だと転送速度に足を引っ張られるため、その分時間ロスになることに留意しておこう。

スキャン設定は前使用者の設定が残っている可能性もある(日によって初期状態が違った)。そういじるところはないがチェックしておこう。基本はdpi、カラー/グレースケール、片面/両面、保存形式(bmp/jpg/pdf/tif)、出力先フォルダ、マルチページ/シングルページくらいをチェックでよいと思う。

設定について。tifはまず非可逆圧縮の設定ができないため除外(BMP相等とjpg相等しか作れない)していい。大容量メディアを持ち込んだ場合は原版としてBMPで取り込むのもいいだろう。もちろんこの場合、転送速度と空き容量に気を配る必要がある。jpgの場合、圧縮率をきちんと設定すること。この後で加工の予定がある場合、品質95以上にするのが望ましいと思われる。PDFの場合、いきなり出力できるのはメリットだが、自分の場合PDF出力(モード:標準)を選んだ際に、品質60相等のjpgで固められてしまったので注意。何か設定が必要だったのかもしれない。解像度は300dpiか200dpiあたりが一般的か。そこはお好みで。

初回は上記の使い方について店員からガイダンスを受けることになる。作業後にマイドキュメントからファイルを消すように説明されるが、通常の削除を実行してしまった場合ゴミ箱への移動だけで数分費やす羽目になるので注意。完全削除(Shiftキー押しながら削除)をするようにしよう。

スキャンのみ支払い方法が異なり、PC横のコインタイマーに500円硬貨を放り込んで一定時間(低速なら10分)使う形になる。従って、10分は厳密に10分なので注意。何度か使う予定があるなら、まずは低速で慣れた方が良いだろう。5分だと初回のガイダンスだけで終了してしまう恐れがある。時間切れ後3分(と説明を受けた)はリコイン可能時間で、この間はコイン投入を促す画面に強制的に切り替わる。この間バックグラウンドでプロセスは動いているようなので、転送最後数秒とか言う状態ならおそらくだが転送完了まではこぎ着ける。ただ操作はできないため、「安全な取り外し」はできないだろう。リコインすれば復帰し、リコイン猶予時間が終わると初期画面に戻る。初期画面に戻ると、作業中データはすべて消える(と説明を受けた)。

なお、このコインタイマーはどうやら500円しか受けつけない。店内には100円両替機と500円両替機があるが、引っかからないようにしよう。

この記事は2011/11月末くらいまで随時更新するかもしれない。
OK キャンセル 確認 その他