Division By Zero

ゼロで割る

WPFアプリケーションでバージョンを表示する

Visual C# 2010 Expressは無料で商用利用もできるので、ちょっとしたWindowsアプリを作るのに重宝している。

要件としては、WindowsフォームアプリとWPFアプリのどちらでもよかったのだが、せっかくなので新しい技術のありそうなWPFを選択した。途中、他社製のコンソールアプリを起動する必要があるので、SilverlightやWebアプリは除外。

ExpressにはInstallShieldが含まれていないので、インストーラーが必要なら、ClickOnceを利用することになる。ソリューションエクスプローラーでプロジェクトを選択して右クリック、プロパティを表示させ、「発行」タブで発行できる。ここの「バージョンの発行」にあるバージョン番号をアプリで表示する方法は以下の通り。

string version;
XmlDocument xd = new XmlDocument();
Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
string path = new Uri(a.GetName().CodeBase).LocalPath;

xd.Load(path + ".manifest");
if (xd.HasChildNodes)
{
    version = xd.ChildNodes[1].ChildNodes[0].Attributes.GetNamedItem("version").Value.ToString();
}

ここを参考にした。

なお、ClickOnceここが詳しい。

うまく表示できたので、今日はこれで終了!

CANバスについて調べてみた

ある車載装置のロガーを作りたいという要望があって、インタフェースはCAN(Control Area Network)だということで少し調べてみた際のまとめ。

CANバスというのは車載装置でよく使われているバスの仕様の一つである。業界標準らしいが、すべての車で利用されている、というわけではない。また、一つの車でバスが一つというわけではなく、たとえば、エンジンやABSなどで一つ、ドアやシートなどで一つ、窓やミラーなどで一つ(あるいは右、左で二つ)、オーディオで一つ、などのように、複数のネットワークがあり、それらはゲートウェイでつながっていたり、いなかったりする。また、これらがすべてCANバスで統一されているわけでもない。

電気的には差動式でノイズに強い。CSMA/CA方式を採っていて、EthernetCSMA/CDと異なり、衝突した場合には優先される側があらかじめ決まっている。

MCP2515 CANコントローラーとMCP2551 CANトランシーバーを使えば、CANバスとの通信はできそうだ。PICかAVRなどのマイコンと組み合わせて工作している事例もWebを探せば見つかる。

もっとも、よく見るのはODB2ポートへの接続例。これは自動車メーカーが故障診断のためのプローブを接続するポートで、CANバスに限らず、先述のいろいろなバスにアクセスできる。ただ、アクセスの方法や、流れるCANメッセージの仕様が公開されているわけではなく、みんな自前で解析して使っているようだ。

前述のように、一台の車に複数のバスがある。ODB2ポートがつながっているバス上のコントローラーに「エンジンの情報を教えて」というリクエストをCANプロトコルで送ると、コントローラーがゲートウェイの先のバスにつながった装置から情報を取得して流してくれる。したがって、コントローラーに対するリクエストメッセージの作り方とレスポンスメッセージの読み方がわからないことには何ともならない。それでも、みんな自分の車にアクセスしたくて頑張っているようだ。

今回対象となる予定の車載装置のCANメッセージの仕様は明らかだし、流れてくるメッセージを(必要なら)フィルタリングしてロギングするだけ。ODB2の作例そのままというわけにはいかないが、大差ない。多分、簡単に作れるんじゃないかな、と思えたところで、今日は終了!

廃棄PCのディスクを消去する

ノートPCも何年も使っていると調子が悪くなってくる。自分で使用する分には、パーツを購入してでも直して使うことが多いが、他の人に強要するつもりもなく、新しいPCを購入するのはいいとして、問題になるのが廃棄だ。

一応、業者を通して廃棄するわけだしHDD等の内容が漏えいすることはないはずだが、実際に漏えいするのも嫌なので、HDDだけは事前に消去している。

消去にはここにあるように、Windowsのcipherコマンドを使っている。

cipherコマンドは「削除済みのデータを上書き」するので、当該ドライブは事前に内容を消去(たとえば、クイックフォーマットするなど)しておく必要がある。USBケーブルなどで接続した当該ドライブがH:にマウントされているとすると、

cipher /w:h:

で消去される。

壊れていてマウントできないHDDもまれにあるが、これはドリルで穴をあけるしかないかな。

今日はこれで終了!

LinkStationにssh経由でrsync, tarを行う

sambaファイルサーバーのバックアップサーバーが壊れてしまった。OSをCentOS4から5にアップグレードしようとしていて、アップグレード自体は(多分)うまくいったのだが、ディスクを頻繁に書き換えたせいか、逝ってしまった。

Pentium4だし、DVD-RではなくCD-Rだし、OSアップグレードするまでもないとも思ったのだが、「使えるものを捨てる」ことに抵抗があり、もう少し使うことを試みたのだが、「もう引退させてください」と言っているようで、本体は廃棄することにした。ちなみに、データディスクは無事だし、起動ディスクも読み取り専用であればマウントできる。データは失っていない。

sambaファイルサーバーのファイルは、毎日一回、このバックアップサーバーに差分バックアップされ、さらにもう一つBuffaloのLinkStationにもコピーされる仕組みにしていた。LinkStationは、acp_commander.jarを使ってsshログインできるようにしておいてあった。

バックアップはrsyncを使っている。LinkStationはDebian化等をしなくても、rsyncがインストールされていて、バックアップはできる。tarのログで日本語が化けてしまうが、LANGをen_US.UTF-8と設定すればいい。勝手に環境変数を変えることで、LinkStationの元の動きが変わってしまうと面倒なので、tarをリモートで実行する際にLANGを直接指定するようにした。

今日はここで終了!

ファイルリポジトリw2boxを設定する

Webブラウザで利用できるWebDAVでないファイルアップローダーのようなものを探していたところ、w2boxというものが見つかった。10ユーロ以上の寄付をすれば、商用利用(法人での利用)も問題ないようだ。

インストールメモは以下。例によって、CentOS/Apache2.0を使用。

  1. zipを解凍して、オーナーをWebサーバーに変更(例:apache:apache)
  2. upload.cgiをCGIパス(例:/var/www/cgi-bin/)に移動
  3. upload.cgiの#!/usr/bin/perlを環境にあわせて変更
  4. SSLを使用する場合は、index.php内の自身を指す"http://"を"https://"に変更
  5. .htaccessの内容を/etc/httpd/conf.d/w2box.conf等に移す

 (httpd.confでAllowOverride Noneとしている場合)

  1. config.php内のupload_cgiscriptを/cgi-bin/upload.cgiに変更
  2. config.php内のupload_tmpdirを/tmp等に変更

その他、config.phpはお好みで変更。今回は下記を変更した。

  • w2box_title
  • max_filesize
  • allowed_ext
  • log
  • log_filename
  • upload_progressbar

設置して試してみると、きちんと動作はするのだが、Apacheのエラーログにいろいろ出てくる。こんな感じに。

[client X.X.X.X] PHP Notice: Undefined index: error in /var/www/html/w2box/index.php on line 194, referer: https://XXX/cgi-bin/upload.cgi?sid=XXXX&maxsize=2147483648
[client X.X.X.X] PHP Notice: Undefined variable: dirlevel in /var/www/html/w2box/index.php on line 251, referer: https://XXX/w2box/smas/
[client X.X.X.X] PHP Notice: Undefined variable: dir in /var/www/html/w2box/index.php on line 262, referer: https://XXX/w2box/smas/

どうもルート階層でのファイルアップロードや、フォルダ作成時に、いくつかの変数が未定義になるようだ。PHPに(も)詳しくないので、バージョンの違いなのかもしれない。とりあえず、以下のような感じで修正した。

<       if ($file['error']!=0) {
---
>       if (isset($file['error']) && $file['error']!=0) {

あとは、lang/ja.phpの「添付」を「アップロード」に変更したり、images/iconsにcsv.gifがなかったのでxls.gifからコピーした程度。

/etc/logrotate.d/w2boxを作成してログをローテートするようにしたところで、今日は終了!

Windows7をWebDAVクライアントにしたい

取引先とメールで交換しているExcelシートをインターネット経由のパスワード付き共有フォルダ等でのやりとりに変えたいというリクエスト。

いまあるApacheWebDAVを有効化するだけの話かと思ったが、うまくいかない。いろいろWeb上でも議論があるようだが、

  1. SSL有効化
  2. サーバー証明書はある(自己証明書ではない)

という条件であれば、うまくいきそうなのだが、うまくいかない。

そこでたどり着いた下記の記事に従って、ServerNotFoundCacheLifeTimeInSecを0にしてみた。

I scoured the Internet and read through numerous forums and through some trial and error and educated guessing I finally came up with a possible hack. I came up with it based on reading the descriptions of the registry entries that I found at http://learn.iis.net/page.aspx/386/using-the-webdav-redirector/

If you set the following registry entry to 0 (default is 60 or 3c in hex)

http://www.anyspeak.org/?p=137

OS再起動後、コンピュータ/ネットワークの場所を追加しようとすると、「入力したフォルダーは有効でないようです。...」と表示されるのは同じだが、前述のレジストリ変更でキャッシュされなくなったため、続けて何度も試すことができる。そのうち、BASIC認証のユーザ名とパスワードを聞かれて、入力すると無事に「ネットワークの場所」にWebDAVフォルダーができる。

しかしながら、下記のようにログアウトやOS再起動で接続が切れてしまうと使えなくなってしまう。

The caveat being that it fails to reconnect on logout or reboot but double clicking on the shortcut in Network Locations brings up the login prompt and once authenticated it works again for the current login session.

http://www.anyspeak.org/?p=137

毎回、このWebDAVフォルダーを作り直せばいいのだが、実際に作ってみると、便利すぎて取引先との間で使うのは危険だと感じた。もう少し面倒でも、意識してアップロードするほうがいい。

また、Digest認証だとうまくいかなかった。SSLなのでBasic認証でいいとは思うが。

ここまでは、Windows7 x64, Windows8 CP x64, Apache 2.0で試している。Apacheが古すぎるのが原因かもしれないが、別の用途で使っていて簡単にアップグレードできない。

取引先とのファイル共有する方法はもう少し考えてみる必要がある。今日はここで終了!

HD4350がマルチディスプレイでハングアップする

SAPPHIRE HD 4350 512MBをWindows 7 64bitで使用している。マルチディスプレイを使い始めたころから、頻繁に(二週に一回くらいか)ハングアップするようになり、どこかでドライバを更新したときからだったかと思い、一番古いものに戻して再現を待ち、再現のたびに順次更新していった。

最新版になってしまい、ビデオカードを変えようかと思っていた頃、12.6がリリースされて、一カ月安定して動いているので、メモしておく。また再現するようなら、このエントリに記録することにして、今日はこれで終了!