2007年12月28日金曜日

基になる RCW から分割された COM オブジェクトを使うことはできません.

 と言う、非常に分かりにくいメッセージに出くわす事がたまにありますが、未だにこの辺の仕組みが理解出来ていません orz

 このメッセージ、ExcelやWordなんかのCOMオブジェクトを使っていて、書き方を間違えると発生するものですが、以下の様な書き方をしなければ、なかなかお目にかかれません.
 いや、お目にかかりたくは無いんですけどねw

#region " USING "
using System;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
#endregion


namespace Com
{
    /// <summary>
    /// CExcel の概要の説明です。
    /// </summary>
    public class CExcel
    {
        /// <summary>
        /// 引数無しコンストラクタ
        /// </summary>
        public CExcel()
        {
        }

        /// <summary>
        /// デストラクタ
        /// </summary>
        ~CExcel()
        {
        }

        /// <summary>
        /// エラーを発生させてみるテスト.
        /// </summary>
        public void test()
        {
            // Local variable.
            ApplicationClass objExcel = new ApplicationClass();
            Worksheet objWorksheet = new Worksheet();

            // Workbook 追加.
            objExcel.Workbooks.Add(Type.Missing);

            // 1ページ目の Worksheet を取得(非常識な取得の仕方ですが)
            objWorksheet = (Worksheet)objExcel.Workbooks.get_Item(1)
                .Worksheets.get_Item(1);

            // Worksheet の名前を表示してみる.
            MessageBox.Show(objWorksheet.Name); // Sheet1

            /**
             * 本来必要は無いが、Worksheet を COM オブジェクトとしてを解放し
             * てみる.
             * 更に解放した Worksheet の Delete メソッドを呼び出してみる.
             * この時点では何故かエラーが出ない.
             * そして、Worksheet の名前を参照しようとすると
             *
             *  基になる RCW から分割された COM オブジェクトを使うことはできません
             *
             * と言う、非常に分かりにくいエラーメッセージが発生 orz
             * しかも、COM オブジェクト解放のみを実行した場合は、
             *
             *  オブジェクト参照がオブジェクト インスタンスに設定されていません。
             *
             * と言う見慣れた「ああ、インスタンス化してねーじゃん」と言うメッ
             * セージになり、Delete メソッドだけ実行した場合は、
             *
             *  HRESULT からの例外です : 0x800401A8。
             *
             * と言うエラーが参照段階で発生します.
             */
            this.releaseComObject(objWorksheet);
            objWorksheet.Delete();
            MessageBox.Show(objWorksheet.Name); // ここで例のエラーが発生.

            // Excel 終了.
            objExcel.Quit();

            /**
             * ここの COM オブジェクトリリースは必要.
             * 解放しない場合、プログラムが終了するまで Excel プロセスが継続.
             */
            this.releaseComObject(objExcel);
        }

        /// <summary>
        /// すべてのCOMオブジェクトが解放されるまで、繰り返し ReleaseComObject を
        /// 実行します。
        /// </summary>
        /// <param name="objInput">COMオブジェクト</param>
        public void releaseComObject(Object objInput)
        {
            while (System.Runtime.InteropServices.Marshal.
                ReleaseComObject(objInput) > 0);
            objInput = null;
        }

    } // CExcel
} // namespace
 ※見た通り、全く意味の無い適当な書き方です.
 ※参照追加でExcelのObjectLibraryを追加しないと動きません(念のため).

 参考に「相互運用機能アセンブリを使った複雑な COM オブジェクトの処理 - Office のメニュー ボタンが機能停止した場合の対策」と言うページも見たのですが、未だにピンと来ません.
 …私のレベルでは理解不能な話の様です orz

 嗚呼低次元低次元...

2007年12月25日火曜日

ActiveDirectoryのグループポリシー適用状況を確認.

C:\> gpresult


 gpupdate → gpresult でポリシーが適用されているか一目で分かる訳ですね.
 いや~これは便利なコマンドです.

 と言う、正に「そんな事も知らなかったのかよw」的なメモ orz


 さ、今日はクリスマスだし、更なる自虐的思想に陥る前にさっさと帰ろう.

電源設定.

 何を今更!?なメモ.

 ActiveDirectory環境でXPの電源設定周りを統一的に設定(要するにグループポリシーでゴニョゴニョ)出来ないものか、と言う話があったので調べてみましたが、どうやらXPでは無理(Vistaでは可能)な様で orz

 こんな方法でXPでも実現可能な様ですが、正直面倒この上ないので見なかった事にしたい気分ですw

 ついでに電源設定周りのレジストリ格納場所も探してる最中に見受けられたのでメモ.

 HKEY_CURRENT_USER\Control Panel\PowerCfg
 HKEY_USERS\[ユーザー]\Control Panel\PowerCfg

 と言うか、Powercfgと言うコマンド(ツール)がある事自体知りませんでしたから orz

2007年12月20日木曜日

唖然とする某システム.

 最近、某所にて某システムを触る機会がありました.
 …某某ばかりじゃ分からないけど orz
 その某システムが凄い訳です.

 PHPで書かれているんですが、まず、エラー画面にエラーハンドラで受け取ったエラー内容を「ほぼそのまま」表示します.
 ○○○.phpの○○行目で、○○関数の引数が○○だからエラーが出ましたよ、と(実際のメッセージは異なります).
 そりゃもう親切丁寧に教えてくれる訳ですよ orz

 更にエラーが発生した際、場合によってはクエリを画面に出力してくれます.
 まぁ!なんて親切なんでしょう♪ … orz
 ※これは多分意図した訳ではなく、デバッグ気分で echo ったであろうコードを削除し忘れているかと思われます

 とまぁ、致命的と思われる事はこの辺にしておき、一番衝撃的な事(いや、上のも十分衝撃的なんですが、自分でもやってしまいそうと言う意味での衝撃的)が、Ajax周りの挙動.
 私は余りそんな組み方をしませんが、

 1. 複数の選択欄(SELECT)がある
 2. 選択欄Aを選択するとAjaxが走り、サーバーへ選択欄Bのリストを取りに行く
 3. サーバーから取得したリストを選択欄Bへセットする
 (選択欄Dまで繰り返し...省略...)

 と言う「まぁ、やるっちゃーやるな」と言う処理なんですが(私は選択する度にトラフィックが発生するのが嫌で、余程膨大な選択種が無い限り最初に全部読み込みます)、今回出くわした環境がアナログ回線だったが為に、下の様な挙動を連発する訳です.

 選択欄Aで選択→選択欄Bが空欄のまま→ボーっと待つ→数秒後選択欄Bにリストがセットされる
 選択欄Aで内容1を選択→選択欄Aで内容2を選択しなおす→数秒後選択欄Bには選択欄Aの内容1に連動するリストがセット

 正直使う気が失せますね、これじゃ……
 良くAjaxでデータを読み込む時に、ローディング画像を表示しつつDIVなどで画面を保護する作りにしますが、選択欄を連動させるくらいでそんな保護しませんしねぇ.
 逆にいちいち選択内容変更する度に(選択欄を連動させる為だけに)ローディング画面になったら、Ajaxな意味が無くなるくらい煩わしくなりますし.

 まぁ、平成19年も師走を迎えた昨今、そんなWindows95を思い出す速度環境下なんて余り無いでしょうから、そんなに気にする必要も無いのかもしれませんけどw

 とは言いつつ、今回出くわした様な作りにはしない様に心掛けようと心底思った今日この頃.

/**
 * 追記.
 */
 この投稿書いてから、Gmailが高速化する手段として「メッセージをあらかじめ読み込んでおくため、メールを開くときにGoogleサーバにアクセスしなくてもよくなり、メールの表示が速くなる」(『@IT』より一部抜粋)方法を選んだ事を思い出しました.
 Ajaxも使い方次第では旧来よりユーザビリティを低下させるかもね、と.
 ※Gmailの場合、正確には「Ajaxなバックグラウンド処理で事前に読み込む」と言う方式らしい

2007年12月13日木曜日

MTOS: Movable Type オープンソース・プロジェクト.

 久々の投稿.
 仕事が忙しかった訳では無く、単に家で仕事をしていただけです.

 … orz

 そんなどうでもいい近況報告はおいておき、Movable Typeのオープンソース化プロジェクトが始まった様です.
 まぁ、前からソース確認出来てたみたいですけど、lightmaterialは余り興味が無く、一度も見た事がありませんでした.
 しかし「折角オープンソース化したんだしな」と、この機会にチラッと中身を覗いておこうと思い早速ダウンロード.

 さて、どこから見るかな~
 お!この「mtdb_base.php」って言うファイルは結構サイズがあるし、読み応えがありそうだ!
 どれどれ…


 ……ぎゃーーーー!!!
 き、き、き、汚ねぇよ!!! orz

 なんじゃこりゃ…
 いや、そりゃ読める範疇なんだけどもね.
 それにしたって、コメント全然無いし、トリッキー(初心者が見て理解不能な書き方. lightmaterialは一番嫌いです)だし、インデントがファイルによってタブ文字だったりスペースだったりするし、SQL文がコード中に直書き されてるし……

 有名所の会社でも、あんなコード書いてる所があるんだなぁ…と思い知った今日この頃.
 他の会社もあんなモンなんでしょうかね?
 ま、まさかね……w

/**
 * 追記
 */
 そう言えば、以前サクラエディタと言うソフトのソースを見た時も「色んな人が書いてるから読みにくいなぁ」と思ったものですが、私としてはMovable Typeの方がよっぽど読みにくいです(C++とPHP比較するのもアレですが).
 そんな感じです、はい.