Vista SP1 RC ダメでした

快適になったような気がしたのですが、Firefox を使用していて2回も突然クラッシュしたので、やっぱり SP1 RC をアンインストールしました。

やれやれ。よいお年を。。

治す人と壊す人

今年の8月から Windows Vista を使うようになり、不満ばかりを感じていたのですが、自分が素直なユーザだったかと言われると、そうではなかったように思います。

確かに「Vistaに未対応」という手持ちのアプリケーションをいくつもインストールしては「うまく動く」「ちょっと画面が崩れる」など試行錯誤を続けていたのも事実です。

たぶん Vista の Microsoft Update は私のような試行錯誤的な使い方を想定していないので、だんだん挙動がおかしくなっていったのでしょう。

仕組みがある程度分かっていれば「マニュアルに書いてないけど、この使い方はできるだろう」といった予想ができるようになります。コンピュータに慣れていない人はそれができないから、何をするにもまずマニュアルを探そうとして、欲しい情報を見つけることができなくて戸惑うわけです。

しかし最近「熟練者の罠」とでも呼ぶべき状況を頻繁に感じるようになりました。

つまり「いままで使ってきたシステムではこうだったから、新しいシステムもこうだろう」という思い込みが原因で、不適切な判断につながる場合がある、と気づいたわけです。

先日のプリンタのトラブルも「マニュアルに書かれていないことをどう判断するか」で私が経験に頼ったことも一因のように思います。

最近は Linux をいじっていても経験を過信したことが裏目に出てヒヤリとすることがあります。

おそらく「日々ちょっとずつ変化する技術」を積み重ねていくうちに、気づいたら大きな「不連続な変化」になっていくのでしょう。

それに気づかず「ちょっとしか変化していないはずだから、自分の経験で使いこなせるはずだ」という思い込みをしてしまうのだと思います。

続編ではない方の映画「三丁目の夕日」には、故障したテレビを修理しようとするエピソードが出てきますが、私は最近うっかり「あれ」にならないように自制することが多くなりました。

人はこうして「新しいものを学習する能力の衰え」を自覚していくのでしょうか。だとすれば身につけていくべきは「もっと別の能力」です。そう、時間をおいて頭を冷やすとか、適切な相手に連絡したり相談したり任せたりするとか。。

そして今回のService Pack 1のように「泥沼をリセットしてくれるパラダイムシフト」を見極めていく必要もありそうです。

Vista SP1 RC

あらためて KB941649 の問題について検索していたら、

に SP1 RC のインストールで解決、ということをお書きになっていたので、私も試してみました。

とりあえず寝ている間に無事にインストールが終わったところです。

未適用の Microsoft Update はなくなりました。「インストールされた更新プログラム」によると「KB936330のService Pack」が適用されたことになっています。

画面の右下には「評価コピー。ビルド6001」という文字が出てきます。

アプリケーションの起動など、以前よりも動作が速くなったような気がしますが、きちんと計ったわけではありません。

「VistaはSP1を待たなくても大丈夫」という記事が以前ありましたが、やはりSP1を待つべきだろう、と思います。それよりも Windows XP の方が無難、という状況はなんとかならないでしょうか。

CodeGear RAD Studio Update ふたたび

先日私の Vista 環境でうまくいかないと御報告した CodeGear RAD Studio Dec2007 Update に再挑戦。

今度は RAD Studio そのものをアンインストールして、再度インストールして、Update をやり直しました。アンインストールにも相当な時間がかかり、まるまる1日近い作業になりましたが、無事に完了。

ついでに(本当はVista非対応だった)Borland Developer Studio 2006 と関連ランタイムをアンインストールしたところ Windows Update も正常終了しました。まだ KB941649 は未適用ですが。。。

RAD Studio Dec2007 Update

リリースされたので早速アップデートを試みたのですが、Windows Vista の場合は3時間以上かかる場合があります、というリリースノートの警告通りでした。

しかも「インストールを検証しています」の後でエラーが発生してアップデートに失敗。

アンインストールして入れ直した方がいいかも知れません。

今年は8月からVistaに本格的に乗り換えようとして、苦労ばかりした1年でした。

さっさと XP にダウングレードすればよかったと後悔しています。

来年はもっと快適な仕事環境に恵まれますように。

HP Photosmart A716

先日 HP インクジェットプリンタ Photosmart A716を購入しました。

普段自宅では白黒のレーザプリンタを使っているので、写真や葉書を印刷できるコンパクトなカラープリンタが欲しいと思い、有楽町ビックカメラで選びました。

ところが、数枚の写真を印刷した後、葉書印刷のリハーサルをやろうとして普通紙を入れたら紙詰まりが起きて回復不能に。本体は低価格でしたが、すでにフォトペーパーやインクカートリッジに追加投資しているので、諦めるわけにもいかず、メーカーに問い合わせたら「クイックエクスチェンジ」で対応していただき、電話した翌日に宅配業者が来て代替品と交換してもらえました。

これからは気をつけて使いたいと思います。

Delphi + PHP

Delphi 2007 の Indy コンポーネントを使い、ファイルを HTTP 経由でアップロードし、PHP5 でダウンロードする動作を確認しました。下記のサンプルをそのまま実行しようとしたら、PHP5 で動かなかったことと、Delphi 側も多少の手直しが必要でした。

<?php
$upload_dir = '/data/www/html/uploader/data';
$maxfilesize = 1024000; // up to 1MB
$send = $_POST['send'];
$userfile = $_FILES['userfile'];
$phpself = $_SERVER['PHP_SELF'];
if(isset($send)) {
if(is_uploaded_file($userfile['tmp_name'])) {
if($userfile['size'] <= $maxfilesize) {
if (move_uploaded_file($userfile['tmp_name'],
$upload_dir.'/'.$userfile['name'])) {
echo '<p>upload ok</p>';
} else {
echo '<p>upload error</p>';
}
}
}
}
?>
<form action="<?php echo $phpself; ?>" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $maxfilesize; ?>">
<input type="file" name="userfile">
<input type="submit" name="send" value="send">
</form>

Delphi の Form1 には IdHTTP1, Button1, Memo1 を貼り付けました。

implementation
{$R *.dfm}
uses IdMultipartFormData;
procedure TForm1.Button1Click(Sender: TObject);
var
ResponseStream: TMemoryStream;
MultiPartFormDataStream: TidMultiPartFormDataStream;
begin
MultiPartFormDataStream := TidMultiPartFormDataStream.Create;
ResponseStream := TMemoryStream.Create;
try
IdHttp1.Request.ContentType :=
MultiPartFormDataStream.RequestContentType;
MultiPartFormDataStream.AddFile(
'userfile', 'c:\test.jpg', 'multipart/form-data');
MultiPartFormDataStream.AddFormField('send', 'send');
MultiPartFormDataStream.Position := 0;
IdHTTP1.Post('http://server/uploader/’,
MultiPartFormDataStream, ResponseStream);
Memo1.Lines.Append('[upload ok]');
finally
MultiPartFormDataStream.Free;
ResponseStream.Free;
end;
end;
procedure TForm1.IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;
const AStatusText: string);
begin
Memo1.Lines.Append(AStatusText);
end;

バージョンアップ

Eclipse ベースの Ruby on Rails 開発環境である CodeGear 3rdRail の 1.01 がリリースされました。

オープンソースの音声認識エンジンである Julius 4.0 がリリースされました。

詳細は近々レビューしたいと思います。

世の中は仕事納めが近づいているのでしょうか。。私も昨日、まだ世界中にユーザが一人しかいない某ツールのバージョンアップをしましたが、仕事納めはなかなかやってきません。。

未踏オフ会

古川亨さんの講演を聴きたかったので、天才プログラマーではない私も未踏オフ会に行ってきました。

「自分が作ったものを使ってくれる人の喜んでいる顔が見たい」

その思いが、いまの自分にとって、やっぱり大切である、ということを再認識しました。

プログラマー定年説の35歳のときに未踏ソフトに応募して、運良く採択され、運悪くいろいろな障害に遭遇しましたが、自分の弱点や限界を認識できたし、自分の情熱も確認できました。

あれから2年、やっぱりプログラミングが楽しくて、だからこの分野で仕事を続けているのだと思います。そのわりには微妙に職種を選び間違えた気もしますが。。

人と出会うことの大切さや可能性も再認識しました。

そろそろ私は自分がスーパークリエーターになるのではなく、若くて能力がある人をサポートをするための能力を身につけたい、と思います。かつてのアスキーでの古川氏のように。

でも並行して、自分が楽しむためのプログラミング技術を持ち続けたい、そして最後まで「自分が作ったものを・・・」という夢を持ち続けたい、とも思っています。

NVDA + GalateaTalk

昨日の日記の続きです。gtalk.pyは今日はこんな感じになってます。

class SynthDriver(silence.SynthDriver):
name = "gtalk"
description = "galatea talk (experimental)"
def initialize(self):
os.chdir("c:\\work\\istc\\SSM\\gtalk")
cmd = "gtalk -C ssm-win.conf"
(self.cout, self.cin) = popen2.popen4( cmd )
self.cin = codecs.getwriter('shift_jis')(self.cin)
self.cin.write("prop Speak.text = NoAutoOutput\n")
self.cin.write("prop Speak.pho = NoAutoOutput\n")
self.cin.write("prop Speak.dur = NoAutoOutput\n")
self.cin.write("prop Speak.stat = NoAutoOutput\n")
self.cin.write("prop Speak.len = NoAutoOutput\n")
self.cin.write("prop Speak.utt = NoAutoOutput\n")
self.cin.write("set AutoPlay = YES\n")
self.cin.flush()
self.frame = SynthFrame()
return True
def speakText(self,text,wait=False,index=None):
self.cin.write("set Text = " + text + "\n")
self.cin.flush()
if wait:
s = "[speak wait]"
else:
s = "[speak]"
self.frame.textCtrl.AppendText(s + text + "\n")
def cancel(self):
self.cin.write("set Speak = STOP\n")
self.cin.flush()
self.frame.textCtrl.AppendText("[cancel]\n")
def terminate(self):
self.cin.write("set Run = EXIT\n")
self.cin.flush()
if not self.frame:
return
self.frame.Close()
self.frame.Destroy()
self.frame = None
def getVoiceName(self,num):
return "gtalk voice"

で、今度は5~6行くらいは読み上げるようになりました。カーソルで行を移動すると「音切れ」もちゃんと実現されています。ちょっと反応が遅く感じるのは GalateaTalk の処理時間の問題でしょう。

数行読み上げるとやがて止まってしまうのは GalateaTalk のコンソール出力をちゃんと読み出ししていないから不安定なのかも知れません。

そもそも cout の読み出しをどうやればいいのでしょう。別スレッドを回して non-blocking I/O でcoutを読み出して捨てる必要があるのですが、まだ Python に慣れていない私はそこでつまづいています。

ところで GalateaTalk の README には

各スロットは、プロパティとして AutoOutput か NoAutoOutput のどちらかの
値をとり、それぞれ自動出力する、自動出力しないを表す。
プロパティの値を変更するには、
prop Text.text = NoAutoOutput
prop Text.text = AutoOutput
のように prop コマンドによって行なう。
初期値としては、全て AutoOutput が設定されている。

と書かれているのですが、サンプルのPerlスクリプト(RUN)は

print OUT "prop Text.text = NoAutoOutput\n";
print OUT "prop Text.pho = NoAutoOutput\n";
print OUT "prop Text.dur = NoAutoOutput\n";

になっています。これ Text.text ではなくて Speak.text じゃないでしょうか?

今日はここまで。