htaでローカルファイルをインクリメンタルサーチ

ローカルの指定ディレクトリをインクリメンタルサーチしたかったんで作ってみた。動画やmp3ディレクトリみたいなものすごくファイル数の多いディレクトリからファイルを探す際に使うことを想定してます。ちょっと強引だけど右クリックから起動できるようにしたので何かと結構便利。検索結果をクリックするとエクスプローラーで開きます。

特徴(気にしたところ)

  • 負荷軽減のため検索ディレクトリの内容をキャッシュ
  • キャッシュの内容は対象ディレクトリの変更日時を見て更新します。
  • ダブルクリックで起動した場合htaファイルのあるディレクトリが検索対象になります。
  • 引数をつけ起動した場合引数のディレクトリが検索対象になります。
  • 引数が取れるので右クリックから起動可能
  • 正規表現で検索可能

実行方法:以下ソースを「IncrementalSearch.hta」という名前で保存して適当なディレクトリに配置してダブルクリック。(http://www.prototypejs.org/:prototype.jsがないと動かないのでDLして同じディレクトリに配置しておく)

<html>
<head>
    <title>インクリメンタルサーチ</title>
    <hta:application id="gara" maximizebutton="no" selection="yes"
                 navigable="yes" scroll="yes" singleinstance="yes" />
    <meta http-equiv="MSThemeCompatible" content="yes">
    <style>
        ul { list-style-type:none; margin:1px; }
        li { cursor:pointer; width:100%; border:3px double; margin:3px; font-size:12px }
    </style>
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript">
    var targetDir = ".";
    var lastModDate;
    var localFiles;
    var serchResultFiles;
   
    onLoad = function( link ) {
        resizeTo( 500, 800 );
        showList();
    }
   
    showList = function() {
        var arg = argsArray(gara.commandLine);
        tempDir = arg[1].replace(/^\s+|\s+$/g, "");
        if (tempDir != "") {
            targetDir = tempDir;
        }
        $( "dir" ).innerHTML = targetDir;
        //ファイル一覧取得
        searchFlvFiles();
        // 検索
        var keyword = $F( "keyword" );
        serchResultFiles = localFiles.findAll( function( file ) {
            return RegExp( keyword, "i" ).test( file.Name );
        } );
        // リストクリア
        var ul = $( "target" );
        $A( ul.childNodes ).each( function( child ) {
            ul.removeChild( child );
        } );
        
        // リスト追加
        serchResultFiles.each( function( file, index ) {
            var li = document.createElement( "li" );
            li.setAttribute( "onclick", new Function( "openExploler( \'" + index + "\' );" ) );
            file.Name.match( /(.*)$/ );
            var text = document.createTextNode( RegExp.$1 );
            li.appendChild( text );
            ul.appendChild( li );
             
        });
    }
   
    searchFlvFiles = function() {
        var fs = new ActiveXObject( "Scripting.FileSystemObject" );
        var orgfiles = fs.GetFolder( targetDir ).Files;
        var modDate = fs.GetFolder( targetDir ).dateLastModified;
        fs.close;
        fs = null;
        if (null == lastModDate) {
        } else if (modDate <= lastModDate) {
            return;
        }
        lastModDate = modDate;
        if( !localFiles ) {
            localFiles = $A();
        } else {
            localFiles.clear();
        }
        var files = new Enumerator( orgfiles );
        while( !files.atEnd() ) {
            localFiles.push( files.item() );
            files.moveNext();
        }
    }

    execBuildupCommand = function( argument ) {
        var shell = new ActiveXObject( "WScript.Shell" );
        shell.Run( "explorer.exe /e,/select," + argument , 1, true );
        shell = null;
    }

    openExploler = function( index ) {
        execBuildupCommand( "\"" + localFiles[index].Path + "\"" );
    }

    argsArray = function (strArgs) {
        var fQuoting = false;
        for(var i=0;i<strArgs.length;i++){
              var code = strArgs.charCodeAt(i);
              if(code==32) if(!fQuoting) break;
              if(code==34) fQuoting=!fQuoting;
        }
        var args=new Array();
        args.push(strArgs.substr(0,i));
        args.push(strArgs.substr(i+1));
        return args;
    }

</script>
</head>
    <body onload="onLoad();">
        検索ディレクトリ=[<span id="dir"></span>]<br>
        検索<input type="text" id="keyword" onkeyup="showList();" />
    <ul id="target" />
    </body>
</html>