承認これくしょん

my black histories

問題ステップ記録ツールが出力するMHTMLからスクリーンショットを抽出する

問題ステップツールとは

Windows 7からは標準で「問題ステップ記録ツール」ことpsr.exeがインストールされている。
ユーザーのマウス操作などに応じて自動でスクリーンショットを撮ってくれるツールだ。
出力されるzipに入ってるMHTMLを展開してブラウザで開くとスクリーンショット付きのレポートが見られる。
以下のコマンドラインオプションを指定するとGUIを出さずに使えて便利。

記録開始
psr.exe /start /output (出力するzipのフルパス) /gui 0 /sc 1 /maxsc (撮影するスクリーンショットの上限)
記録終了
psr.exe /stop

7で試したらスクリーンショットの上限は100だったけど、8は999までいけるらしい。
上限に達した時点で撮影終了するのではなく、古いものから順に消えるので最大値を指定するのが無難。

スクリーンショットの抽出

開発環境が入れられない人でも安心のJScript
下記のスクリプトと同じフォルダに、ツールが出力した「psr.zip」が置いてある前提。
zipを自動で解凍してmhtを読み込み、記録日時を名前とするサブフォルダにスクリーンショットを抽出する。
処理実行後にzipとmhtを削除するので注意。

// 設定
var zipName = 'psr.zip'; // 問題ステップ記録ツールが出力するzip

// zip解凍
var fso = new ActiveXObject('Scripting.FileSystemObject');
var explorer = new ActiveXObject('shell.application');
var currentPath = String(WScript.ScriptFullName).replace(WScript.ScriptName,'');
var inputZip = explorer.NameSpace(currentPath + zipName);
var mhtName = inputZip.Items().Item(0).Name; // mhtファイル
var dirName = mhtName.replace(/Problem_|\.mht/g, ''); // 出力先フォルダ
var outPath = currentPath + dirName + '\\';
fso.CreateFolder(outPath);
var outputDir = explorer.NameSpace(outPath);
outputDir.CopyHere(inputZip.Items(), 0);
explorer = null;

// mht読み込み
var sr = new ActiveXObject('ADODB.Stream');
sr.Type = 2; //adTypeText
sr.charset = 'utf-8';
sr.Open();
sr.LoadFromFile(outPath + mhtName);
var xml = new ActiveXObject('Microsoft.XMLDOM');
var boundary; // boundary文字列
var fileName; // ファイル名
var fileContent = ''; // ファイル内容(Base64)

// 一行ずつ末尾まで読み込み
while (!sr.EOS) {
    var line = sr.ReadText(-2); // adReadLine
    // boundaryが未取得
    if (typeof boundary == 'undefined') {
        boundary = (line.match(/boundary=\"(\S+)\"/)||[])[1];
    // boundaryを含む行
    } else if (line.indexOf(boundary) != -1) {
        // ファイル名と内容が取得済み
        if (fileName && fileContent) {
            // Base64をバイナリに変換
            var node = xml.createElement(fileName);
            node.dataType = 'bin.base64';
            node.text = fileContent;
            // バイナリを保存
            var sw = new ActiveXObject('ADODB.Stream');
            sw.Type = 1; // adTypeBinary
            sw.Open();
            sw.Write(node.nodeTypedValue);
            sw.SaveToFile(outPath + fileName);
            sw.Close();
            sw = null;
        };
        // ファイル名と内容のクリア
        fileName = undefined;
        fileContent = '';
    // boundaryを含まない行
    } else {
        // ファイル名が未定義
        if (typeof fileName == 'undefined') {
            fileName = (line.match(/Content-Location: (\S+\.jpeg)/)||[])[1]; // ファイル名を取得
        // 出力ファイル名が定義済み
        } else {
            fileContent += line; // 出力ファイル内容に追記
        };
    };
};

xml = null;
sr.Close();
sr = null;

// ファイル削除
fso.DeleteFile(outPath + mhtName); // mhtファイル
fso.DeleteFile(currentPath + zipName); // zipファイル
fso = null;

これでExcelに貼り付けたりできますね!ちょっと画質悪いけど…