2008年1月31日 木曜日 23:01:58

7-zipで選択中のファイル(またはフォルダ)を圧縮するMDIE用スクリプト「select2zip.js」

MDIE,javascript,プログラム,日記 [ by Mizugame ]

200801311.jpg
久々にMDIEスクリプトを書いてみました。

フォルダ単位で圧縮をかけたいときに、いちいち圧縮が終わるのを待って次のを圧縮する・・・といった地道な作業をしていました。
これが結構面倒くさいので、一覧を渡して圧縮してくれるといいな・・・と思っていたんですが。

意外と「これだ!」っていうソフトってないんですよねぇ。
(いいのを知っている人がいたら、ぜひ教えてください!)

7-zipがコマンドラインに対応していたので、MDIE用に選択中のファイルを1個につき、1つの圧縮ファイルを作成するスクリプトを書いてみました。
2008-12-20時点で更新しました。

今回は圧縮プログラムに「7-zip」を利用していますので、別途入手する必要があります。

というわけで、とりあえず以下がスクリプト。

/*** 設定開始 ***/
/*
 * [zipExeDir] string
 * 7z.exeをインストールしたフォルダ
 * フォルダセパレータは\\\\で記述
 * 最後は\\\\で閉じておく
 *
 * 例:
 * var zipExeDir = "C:\\\\Program Files\\\\7z\\\\"
 *
 * ※環境変数のパスに通している場合は空で良い
 */
var zipExeDir = "";
/*
 * [targetType] object
 * 圧縮対象にフォルダ、またはファイルを入れるかどうかのフラグ
 *   targetType
 *     'dir':  フォルダを圧縮対象に入れるか[true,false]
 *     'file': ファイルを圧縮対象に入れるか[true,false]
 *
 *     true :対象にする
 *     false:対象にしない
 */
var targetType = {
    'dir':true,
    'file':true
};
/*
 * [logMode] boolean
 * 圧縮状況のログを書き込むかどうか
 * true :残す
 * false:残さない
 */
var logMode = true;
/*
 * [exitMode] boolean
 * ユーザが圧縮プロンプトを終了させた場合、
 * 残りのファイル、またはディレクトリの圧縮を継続するか
 * true :継続する
 * false:継続しない
 */
var exitMode = false;
/*** 設定終了 ***/

/*** dir2zip method ***/
var $select2zip = {
    'fso':  new ActiveXObject("Scripting.FileSystemObject"),
    'shell':new ActiveXObject("WScript.Shell"),

    /**
     * getDateFormat(now)
     *
     *   @param object now:Date Object
     *   @return yyyy年m(m)月d(d)日 hh:mn:ss
     */
    'getDateFormat':function (now) {
        return now.toLocaleString();
    },
    /**
     * getTimeFormat(now)
     *
     *   @param object now:Date Object
     *   @return hh:mn:ss.milliseconds
     */
    'getTimeFormat':function (now) {
        return now.getHours() + ":"
                + now.getMinutes() + ":"
                + now.getSeconds() + "."
                + now.getMilliseconds();
    },
    /**
     * getLogFile(path)
     *
     *   @param object fso:Scripting.FileSystemObject
     *   @param string path:log faile path
     */
    'getLogFile':function (path) {
        if (this.fso.FileExists(path)) {
            return this.fso.GetFile(path).OpenAsTextStream(8);
        } else {
            return this.fso.CreateTextFile(path, false);
        }
    },
    /**
     * getArchiveName(path)
     *
     *   @param string path:log faile path
     */
    'getArchiveName':function (path) {
        var name = "";

        if ($select2zip.fso.FolderExists(FolderView.Items(i).Path) && targetType.dir == true) {
            name = this.fso.GetFileName(FolderView.Items(i).Path);
        } else {
            if ($select2zip.fso.FileExists(FolderView.Items(i).Path) && targetType.file == true) {
                if (!(name = this.fso.GetBaseName(FolderView.Items(i).Path))) {
                    name = this.fso.GetFileName(FolderView.Items(i).Path);
                }
            }
        }
        return name;
    },
    /**
     * uniqueFilePath(path)
     * // pathのファイルがすでに存在する場合、番号を振ったファイル名の作成を試みる
     *
     *   @param string path:string file path
     *   @return string path:unique file path
     */
    'uniqueFilePath':function (path) {
        // パスを分解
        var parent = this.fso.GetParentFolderName(path),
            name   = this.fso.GetBaseName(path),
            ext    = this.fso.GetExtensionName(path);

        if (this.fso.FileExists(path)) {
            for (var j=1; j< =100; j++) {
                uniquePath = parent + "\\\\" + name + "(" + j + ")." + ext;
                if (!this.fso.FileExists(uniquePath)) {
                    return uniquePath;
                }
            }
        } else {
            return path;
        }
    },
    /**
     * exitMessage(code)
     *
     *   @param string code:exit code
     *   @return code:exit message
     */
    'exitMessage':function (code) {
        switch (code)
        {
            case 0:
                $property.count.success++;
                return "圧縮完了。";
                break;

            case 255:
                return "ユーザによって実行がキャンセルされました。";
                break;

            default:
                $property.count.failure++;
                return "圧縮に失敗しました。(不明な終了コード:" + code +")";
                break;
        }
    },
    /**
     * cmdThrow(zip, path)
     *
     *   @param string zip:create file name
     *   @param string path:press file or folder
     *   @return exit code
     */
    'cmdThrow':function (archive, path) {
        return this.shell.run('"' + zipExeDir + '7z.exe" a -tzip'
                             + ' "' + archive + '" "' + path + '"', 7, true);
    }
}
/*** end method ***/

/*** begin property ***/
$property = {
    'path':{
        'parentDir':$select2zip.fso.GetParentFolderName(FolderView.Items(0).Path) + "\\\\",
        /*
         * ログファイルのパス
         * MDIEのインストールフォルダに、ログを残す場合は下記に変更。
         * 'logFile':$select2zip.fso.GetParentFolderName(MDIE.exePath) + "\\\\" + "select2zip.log"
         */
        'logFile'  :$select2zip.fso.GetParentFolderName(FolderView.Items(0).Path) + "\\\\" + "select2zip.log"
    },
    'count':{
        'Items': FolderView.count,
        'success':0,
        'failure':0
    }
}
/* log file stream */
if (logMode == true) {
    $property.objLog = $select2zip.getLogFile($property.path.logFile);
    $property.objLog.WriteLine(">> die2zip start: " + $select2zip.getDateFormat(new Date));
}
/*** end property ***/

/*** begin main script ***/
// zip圧縮部分
press: {
    for (var i = 0; i < $property.count.Items; i++) {

        if (FolderView.Items(i).Selected) {

            var archiveName = $select2zip.getArchiveName(FolderView.Items(i).Path);

            if (archiveName) {
                var archivePath = $select2zip.uniqueFilePath($property.path.parentDir + archiveName + '.zip');

                // 開始ログ
                var logs = "  " + FolderView.Items(i).Path + " > " + archivePath + "\\r\\n"
                         + "    [" + $select2zip.getTimeFormat(new Date) + "] 圧縮開始。\\r\\n";

                // シェルから7zを起動
                var exitCode = $select2zip.cmdThrow(archivePath, FolderView.Items(i).Path);

                // 終了ログ
                logs += "    [" + $select2zip.getTimeFormat(new Date) + "] " + $select2zip.exitMessage(exitCode);

                if (logMode == true) {
                    $property.objLog.WriteLine(logs);
                }

                if (exitMode == false && exitCode == 255) {
                    if (logMode == true) {
                        $property.objLog.WriteLine("    実行を中止しました。");
                    }
                    break press;
                }
            }
        }
    }
}

if (logMode == true) {
    // 結果を書き込む
    if ($property.count.success == 0 && $property.count.failure == 0) {
        $property.objLog.WriteLine("  圧縮対象が見つかりませんでした。");
    } else {
        var logs = "  " + $property.count.success + "個のファイルを圧縮をしました。";
        if ($property.count.failure != 0) {
            logs += "(" + $property.count.failure + "個のファイルの圧縮に失敗。)";
        }
        $property.objLog.WriteLine(logs);
    }
}
/*** end main script ***/

// 終了をアラート
if ($property.count.success == 0 && $property.count.failure == 0) {
    MDIE.echo("圧縮対象が見つかりませんでした。");
} else {
    MDIE.echo("select2zipを終了しました");
}

今回は珍しく、結構コメントを入れたので、比較的わかりやすくなったと思っているんですが。

まずは、簡単に導入手順を。

  1. まず、7-zipのダウンロードページから7-zipを入手します。
    (インストーラー版でも、zipを解凍するだけの方でもどっちでもいいです)
  2. 7-zipをインストールします。
    (zip版をダウンロードした場合は、解凍後に任意のフォルダに入れるだけです。)
  3. 次に、select2zip.zipをダウンロードします。
  4. ダウンロードしたファイルを解凍して、MDIEのインストールフォルダにあるscriptフォルダ内に移動
    (任意のフォルダに入れてもいい)
  5. select2zip.jsをエディタで開き、3行目からの「/*** 設定開始 ***/」から「/*** 設定終了 ***/」までを、環境にあわせて修正します。
    コメントを入れているので大丈夫かと思いますが、設定がわからない場合は、このページのコメント欄などでお知らせください。
  6. MDIEを起動してメニューの「ツール」から「拡張」→「スクリプトに追加」でselect2zip.jsを登録
  7. MDIEのメニューのツールからキーボードショートカットやマウスジェスチャに登録

以上で、選択中のファイルやフォルダを、1個づつZIPファイルにしてくれます。

ザックリと現在の仕様を説明

スクリプトファイルから7z.exeにコマンドを送った際、コマンドプロンプトをタスクバーに最小化して残しています。
なのでコマンドプロンプトを終了させることで、実行を強制終了させることもできます。

あと、設定の中にあるexitModeをfalseに設定することで、強制終了時に圧縮対象のファイルが残っていても、処理を終了できるようになります。
(大きなファイルを大量に送っていた場合などで、ユーザ側でコマンドプロンプトを終了させ続ける手間が回避できます。)

フォルダやファイルの圧縮ですが、選択中のファイルやフォルダが

  • C:\\hoge\folder\
  • C:\\hoge\hoge.txt
  • C:\\hoge\hogehoge.mov

だった場合は

  • C:\\hoge\folder.zip
  • C:\\hoge\hoge.zip
  • C:\\hoge\hogehoge.zip

のようにZipファイルが作成されます。

今のところ、ファイルだった場合は拡張子を外してzp拡張子をつけるので、選択中のファイルが

  • C:\\hoge\hoge\
  • C:\\hoge\hoge.txt
  • C:\\hoge\hoge.mov

だった場合、

  • C:\\hoge\hoge.zip
  • C:\\hoge\hoge(1).zip
  • C:\\hoge\hoge(2).zip

のようになります。

・・・拡張子を残すかどうかも、フラグにした方がいいかなぁ。

あと、今のところ選択中のファイルにzipが含まれても、圧縮をスルーするような処理は入れていません。
なので、2重、3重にzipされていくこともあります。

圧縮ファイルを作成後、自動で元ファイルを消すなんて処理も入れていません。
(完了フォルダに自動で移動するくらいは、追加してもいいかもしれない。)

もうちょっと、やりたい事があるので、もしかしたらバージョンアップをするかもです。

いつもどおり、このスクリプトを利用して発生した損害につきまして、一切責任は負いません。
自己責任でお使いください。

以下、スクリプトを確認した環境です。

  • Windows XP sp2
  • MDIE Ver 0.3.0.0 RC6

関連情報:
選択フォルダの階層構造をテキストファイルに出力するMDIE用スクリプト
拡張子ごとにフォルダ振り分けを行うMDIE用スクリプト
カスタマイズ性の高い高機能ファイラ「MDIE」

コメント (0) »