« インターナショナル | トップページ | そういえば »

2006.01.24

今日のコード

PathAddBackslash()を使わなかったのは、「貧民的プログラミング」の悪影響ですな。

“パス\0ファイル1\0ファイル2\0\0”の「パス」にPathAddBackslash()すると“パス¥ファイル1\0ファイル2\0\0”になるし。
つまり、「パス」と「ファイル2」をコンカチネーションすると“パス¥ファイル1ファイル2”になる。

もちろん、パス向けで別にエリア設ければ良いんだけど、そこが「貧民的プログラミング」ってヤツすよw。

という事で、通常は「パス」を意味するデータの終端はPathAddBackslash()してますのでご安心を。
(INIファイルとかに設定としてパスを吐く時はPathRemoveBackslash()した値にしているけど。)
(↑終端が‘¥’で終わってると、何か見た目が美しくなく感じるから。←こういう所に拘ってしまう。)

しかし、「nFileExtensionが0かどうかで判定するのは正しくない。」は辛いなぁ。
つーか、該当部分のMSDNの記述は「nFileExtensionで判断せよ」ってナナメ読みしてたよw。
英語だから、ナナメ読みは危険だったなぁ。

という事で、ますます面倒な仕様だという事が判明しました。
そのうちカイゼンしよう。

てか、GORRY氏のソースもナナメ読みなのでアレですが、
> // 単一ファイル選択ならすぐ終了
> if ( ( !(ofn.Flags && OFN_ALLOWMULTISELECT) ) ||
この行変な気が。

修正されたようです

で、これらのプログラムは「たった2ヶ月くらいしか」使われないツールを3日間くらいででっちあげたものだ。
何かというと、「基本は」Windows上でcompress/uncompressするGUIツール。
そう、古くからUNIX系OSで使われている、あの、ファイル圧縮形式のアレだ。

「エンドユーザはコンソールアプリなんて使えない」と客が言うので、作ったのだ。

子プロセスでcomp16.exeとかいうDOSアプリ(当然16bitアプリ)を呼んでも良かったのだが、何となくOpenBSDのソースツリーからcompressのソース盗ってきて、例によってWindows向けに書き換えた。
そーゆーソースなので公開。
ダウンロード zfile.h (2.1K)
ダウンロード zfile.c (21.6K)
comp16.exeもソース盗ってきて、32bit版(&ファイル名制限撤廃)作ったけど、何か気に入らんかったし。
まぁ、フツーはWinZip使うよね。


ツール機能に対して「基本は」と書いたのには理由があって、何だかんだで、そのツールを使うような場面で必要な機能は全部入れる事になった。
それは…
・いくつかのファイルをパッケージ化して自己伸張圧縮ファイルにする。
・100MB以上の大きさのファイルを分割する(ファイルスライス)。
・分割したファイルを結合するバッチファイルも生成する。

下二つは別に難しくも何ともないのだが、1件目スよ。

これも、別途、最近のWindowsには標準でインストールされているIExpressというツールを子プロセスとして呼び出す処理書いてあったので、それを使った。

んでもって、試しに240MBくらいのファイルを圧縮してみたら20分くらいかかるんだよねw。
(三河地方のCADデータは250MBくらいあります。主にCATIA V5のデータですが。)

IExpress自体もmakecabというコンソールアプリを子プロセスとして呼んでるんだけど、これ単体だともっと圧縮速度速かった。

これまた色々試すと、CreateProcess()APIのdwCreationFlagsにCREATE_NO_WINDOWやDETACHED_PROCESSを指定してmakecabを実行すると、すこぶる動作がのろい事が判った。
上記のフラグは、要はmakecabのコンソールウィンドウを表示しない設定で、反対に0を指定したりしてコンソールウィンドウが出るならノロノロ動作がカイゼンする事が判明。

しかし、コンソールウィンドウが出るのも格好悪い。
アイコン化したってタスクバーに出るし。

とか思いながらPlatformSDKヘルプ見てたら、lpStartupInfoに指定するSTARTUPINFO構造体のwShowWindowメンバに設定できる値に「SW_FORCEMINIMIZE」とかゆーの発見。
(ちなみに、SW_HIDEはノロノロモードで動いた)

試したらタスクバーにも出ない。
OKOK!

…って、IExpressのソースが公開されてるワケじゃないし。
(というか、IExpressはコンソール表示しているけど遅い。)

仕方ないからIExpressモドキ作りましたさ。

「自己伸張実行ファイルの作り方」のセオリーが有るのかどうか知らんけど、これもテキトーに解決。

自分自身からCABファイルのヘッダ見つけて、それ以降をテンポラリファイルに出力。
それをFDI(File Decompress Interfaceとか何とか)を使って伸張。
後から見つけたサイトでは、リソースに自分自身(EXE本体)のサイズを外部から書き込んでおいて、プログラムはそのサイズまでファイルポインタを進めろとあった。

まぁ、別にCAB形式使うぶんには今のままの仕様でいいや。
(ここも貧民的なコードになっているw)

ちなみに、CAB形式のヘッダは“MSCF\0\0\0\0”で始まっていると決め打ちでコード書きまスた。

つーかさ、FDI使ってCAB伸張するなら、圧縮もFCI使えよな>俺。

|

« インターナショナル | トップページ | そういえば »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/65113/8319792

この記事へのトラックバック一覧です: 今日のコード:

« インターナショナル | トップページ | そういえば »