2009-10-30 :-)
_ 朝ッ
0530 起床
_ 仕事
0830 出勤
_ Windows で CD-ROM ドライブを eject する
Python で → 残高照会メモ: pythonでCDをイジェクト
VBS で → わがため - cygwin のコマンドラインからディスクトレイの開閉を行う
Ruby で → rbcd
_ [ruby][CD-ROMドライブ]ruby で CD-ROM ドライブを eject する
環境
- cygwin
- ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
準備
rbcd を使う。
ライブラリは Windows 用バイナリがあるらしい。rbcd-0.2.0.tar.gz と cdrom-cygwin-20001030.zip を貰う。
rbcd-0.2.0.tar.gz を展開して ~/usr/local/lib/ruby/rbcd.rb に置く。
cdrom-cygwin-20001030.zip を展開して ~/usr/local/lib/ruby/cdrom.so に置く。
CD-ROM デバイスはどれかな...と
% ls /dev fd@ stderr@ stdin@ stdout@
はい?
なお、Cygwinでは「ls /dev」を実行しても、/dev の内容は表示されません。
CD-ROM ドライブは、一番目のドライブが「scd0」、二番目が「scd1」として、「scd15」までが利用可能です。マイナー番号は 16 から 31 の範囲を取ります。
へえ
% ls /dev/scd0 /dev/scd0
ナルホディウス
実行
#!/usr/bin/ruby -Ks require 'rbcd' cd = CDROM.new( '/dev/scd0' ) cd.eject cd.inject
とりあえず実行してみる。
% ruby cdrom0.rb /cygdrive/c/home/miwa/usr/local/lib/ruby/cdrom.so: No such file or directory - /cygdrive/c/home/miwa/usr/local/lib/ruby/cdrom.so (LoadError) from /cygdrive/c/home/miwa/usr/local/lib/ruby/rbcd.rb:9 from cdrom0.rb:3:in `require' from cdrom0.rb:3
はい?
% ldd ./cdrom.so zsh: command not found: ldd
はい?
Linux 等では「ldd ファイル名」を使いますが, Cygwin では「cygcheck プログラム名」を使います
ふむ。
% cygcheck ./cdrom.so .\cdrom.so C:\WINDOWS\system32\WINMM.dll C:\WINDOWS\system32\ADVAPI32.dll C:\WINDOWS\system32\KERNEL32.dll C:\WINDOWS\system32\ntdll.dll C:\WINDOWS\system32\RPCRT4.dll C:\WINDOWS\system32\Secur32.dll C:\WINDOWS\system32\GDI32.dll C:\WINDOWS\system32\USER32.dll Error: could not find cygwin-ruby16.dll
おいー
仕方ないのでビルドする。
% cd ~/usr/local/lib/ruby/rbcd-0.2.0/cdrom % ruby extconf.rb && make checking for mciSendCommand() in -lwinmm... no checking for linux/cdrom.h... no checking for sys/cdio.h... no checking for libcdaudio >= 0.99.0... no checking for which CD-ROM driver is used... dummy checking for the default device... q: creating Makefile gcc -I. -I. -I/usr/lib/ruby/1.8/i386-cygwin -I. -g -O2 -DDEFAULT_DEVICE=\"q:\" -c cdrom.c gcc -I. -I. -I/usr/lib/ruby/1.8/i386-cygwin -I. -g -O2 -DDEFAULT_DEVICE=\"q:\" -c cdrom-dummy.c gcc -shared -s -o cdrom.so cdrom.o cdrom-dummy.o -L. -L/usr/lib -L. -Wl,--enable-auto-image-base,--enable-auto-import,--export-all -lruby -ldl -lcrypt
CD-ROM driver is used... dummy とか言ってるんですけど。
cdrom-dummy.c を眺める。
: void rbcd_open(union rbcd_device *cdrom, const char *device) { } void rbcd_close(union rbcd_device cdrom) { } void rbcd_inject(union rbcd_device cdrom) { } void rbcd_eject(union rbcd_device cdrom) { } :
oh yeah
extconf.rb のここが通らないので結局 dummy にされてるらしい。
if driver.nil? then case CONFIG['host_os'] when 'cygwin', 'mingw32', 'mswin32' then if have_library('winmm', 'mciSendCommand') then driver = 'win32' end end end
ruby extconf.rb したときに言われたここ
checking for mciSendCommand() in -lwinmm... no
-lwinmm は winmm.dll を使う。
winmm.dll は C:\WINDOWS\system32\winmm.dll にある。winmm.dll が見付からないのか?
これを extconf.rb に書いてためす。
if have_library('winmm') then
よよい
checking for main() in -lwinmm... yes
見付かった。
ということで winmm.dll に mciSendCommand が見付からないようだ。
あるよなあ。
結局分からなかったのでこうしちまった。
if driver.nil? then case CONFIG['host_os'] when 'cygwin', 'mingw32', 'mswin32' then - if have_library('winmm', 'mciSendCommand') then + if have_library('winmm') then driver = 'win32' end end
えい
% ruby extconf.rb checking for main() in -lwinmm... yes checking for which CD-ROM driver is used... win32 checking for the default device... q: creating Makefile
ふむ
make する。
% make gcc -I. -I. -I/usr/lib/ruby/1.8/i386-cygwin -I. -g -O2 -DDEFAULT_DEVICE=\"q:\" -c cdrom-win32.c cdrom-win32.c:25: error: parse error before "NORETURN" cdrom-win32.c:25: warning: data definition has no type or storage class cdrom-win32.c:173:11: warning: multi-character character constant cdrom-win32.c: In function `rbcd_open': cdrom-win32.c:173: warning: overflow in implicit constant conversion make: *** [cdrom-win32.o] Error 1
cdrom-win32.c のここ
static void mci_error(const char *command, int line, DWORD e) NORETURN; void mci_error(const char *command, int line, DWORD e)
NORETURN ってなに
手元では gcc 使ってるから __attribute__((noreturn)) でいいのかなあ。たんに削除してもよさそうだけど。
static -void mci_error(const char *command, int line, DWORD e) NORETURN; +void mci_error(const char *command, int line, DWORD e) __attribute__((noreturn)); void mci_error(const char *command, int line, DWORD e) { char buf[128];
make する
% make gcc -I. -I. -I/usr/lib/ruby/1.8/i386-cygwin -I. -g -O2 -DDEFAULT_DEVICE=\"q:\" -c cdrom-win32.c cdrom-win32.c:173:11: warning: multi-character character constant cdrom-win32.c: In function `rbcd_open': cdrom-win32.c:173: warning: overflow in implicit constant conversion gcc -shared -s -o cdrom.so cdrom.o cdrom-win32.o -L. -L/usr/lib -L. -Wl,--enable-auto-image-base,--enable-auto-import,--export-all -lruby -lwinmm -ldl -lcrypt
ふむ
インストールしちゃえ
% make install /usr/bin/install -c -m 0755 cdrom.so /usr/lib/ruby/site_ruby/1.8/i386-cygwin
~/usr/local/lib/ruby/cdrom.so は削除しておく。
では実行してみる
% ruby cdrom0.rb cdrom0.rb:5:in `new': invalid device name `/dev/scd0' (TypeError) from cdrom0.rb:5
はい?
/dev/scd0 じゃなくて D: などと書けばいいらしい。
#!/usr/bin/ruby -Ks require 'rbcd' cd = CDROM.new( 'd:' ) cd.eject cd.inject
ok
_ [cdbiff]Windows で cdbiff
cdbiff: メールの到着を CD-ROMドライブでお知らせ
環境
- Becky! 2.50
- cygwin Ruby 1.8.7
- rbcd をインストール済み
やってみよう
eject させるコマンドはこれ。eject させっぱなし。
#!/usr/bin/ruby require 'rbcd' cd = CDROM.new( 'd:' ) cd.eject
実行
cdbiff.rb -f ~/Mail/B2.num -c eject.rb
ok