2008年01月21日
川俣晶の縁側ソフトウェア技術雑記total 10956 count

Vista Sidebar GadgetのSystem.Shell.ItemオブジェクトでZIPフォルダを処理させない方法 【訂正版】

Written By: 川俣 晶連絡先

 これは「Vista Sidebar GadgetのSystem.Shell.ItemオブジェクトでZIPフォルダを処理させない方法」が誤っていたことに対応する訂正版です。

問題 §

 Vista Sidebar GadgetのSystem.Shell.Itemオブジェクトに含まれるSHFolder.Itemsを用いてファイルとディレクトリを列挙するとき、ZIPフォルダもアイテムのisFolderプロパティがtrueになり、その内部のアイテムも列挙できます。

 このことは、一般のアプリでは致命的な問題を引き起こします。シェルはZIPフォルダ内のファイルを問題なく扱えるとしても、一般アプリもそうとは限らないからです。そこで、通常のフォルダとZIPフォルダを区別するプログラミングが必要とされます。しかし、ZIPフォルダを明示的に区別するプロパティは見あたりません。

解決策その0・拡張子の判定 §

 拡張子.zipのフォルダを処理しない……という方法が最も容易です。

 しかし、この方法は以下の理由により不完全です。

  • シェルが処理する圧縮フォルダはZIPに限らず、CABやLZH(オプション)もある
  • 一般ユーザーが、通常のフォルダ名に"…….zip"という名前を付ける可能性がゼロではない

 以上の理由から、不特定多数の利用者が使うプログラムでは不十分であると考え、他の方法を模索しました。

解決策その1・FSO (FileSystemObject)を使う §

 WSH上のJScriptでしか確認を取っていませんが、FSOはシェルと直接関係がないのでZIPフォルダは単なるファイルとして認識されます。

サブフォルダの列挙でZIPファイルは出てこない §

   var fso, f, fc, s;

   fso = new ActiveXObject("Scripting.FileSystemObject");

   f = fso.GetFolder(".");

   fc = new Enumerator(f.SubFolders);

   s = "";

   for (; !fc.atEnd(); fc.moveNext())

   {

      s += fc.item();

      s += "<br>";

   }

   WScript.Echo(s);

ファイルの列挙でZIPファイルは出てくる §

   var fso, f, f1, fc, s;

   fso = new ActiveXObject("Scripting.FileSystemObject");

   f = fso.GetFolder(".");

   fc = new Enumerator(f.files);

   s = "";

   for (; !fc.atEnd(); fc.moveNext())

   {

      s += fc.item();

      s += "<br>";

   }

   WScript.Echo(s);

参考にしたURL §

JScript 8.0 ActiveXObject オブジェクト

Scripting ランタイム ライブラリ FileSystemObject の概要

解決策その2・isFileSystemを使う §

 Vista Sidebar GadgetのSystem.Shell.Itemオブジェクトに含まれるSHFolder.Itemsを用いてファイルとディレクトリを列挙する方法を踏襲します。このとき、isFileSystemプロパティは、ZIPフォルダ等のファイルシステム上のファイルではないアイテムの場合にfalseになります。

 このプロパティは、ZIPフォルダ内のフォルダではfalseになりますが、ZIPフォルダそのものはファイルシステム上のファイルであるためtrueになります。ですので、ZIPフォルダを弾く判定には使用できません。しかし、ZIPフォルダ内のファイルやフォルダを弾くためには使用できます。言い換えれば、ZIPフォルダ内を探索してしまうことは阻止できないものの、ZIPフォルダ内のファイルを拾い上げてしまうことは阻止できます。

 以下、コードの抜粋を以下に示します。

    var directoryItem = System.Shell.itemFromPath(path);

    var directoryFolder = directoryItem.SHFolder;

    var directoryCollection = directoryFolder.Items;

    for (var i = 0; i < directoryCollection.count; i++)

    {

        var item = directoryCollection.item(i);

        if( !item.isFileSystem ) continue;

感想 §

 JScriptからWin32 APIは叩けないようですが、COMオブジェクトは呼べます。

 おかげで、FSO経由という抜け道が見つかりました。

 時代遅れでもう使わないよ、などと思ってごめん。

 ありがとうFSO!

 ……しかしここまで調べておきながら、実際にAutumn's Random Music Playerの修正に使ったのは「解決策その2」の方だったという…… (汗。

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2008年
01月
27日
無駄にハンドルをガバガバ確保してシステムに過剰な負担を掛けるのはどいつだ!?
3days 0 count
total 6249 count
【技術雑記】の前のコンテンツ
2008年
01月
19日
freebsd-updateでFreeBSDのマイナーバージョンアップを行う際のメモ
3days 0 count
total 3154 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20080121140720
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.34 (Alpha-Test) Copyright (c) 2004-2018 Pie Dey.Co.,Ltd.