WSFファイルを1ファイルに結合する:wsfpack.wsf

wsf2jse.wsf」の改造版です。

wsfpack.wsf

WSFファイルを1ファイルに結合する。

wsfファイルのXMLを解析して、1つのwsfファイルに結合して出力するスクリプトです。ファイルを分割すると開発するには便利ですが、実用には不向きなため、1ファイルにまとめます。

説明

cscript wsfpack.wsf /?
WSF 1 File conversion tool.
使い方 : wsfpack.wsf path

オプション :

path : WSF file path
  • wsfファイル名に「.wsfpack.wsf」を追加したファイルを作成します
    • 既に存在する場合、上書きします
  • scriptタグにsrc属性とtext要素が両方存在する場合、動作を停止します
  • scriptタグのsrc属性のファイルが存在しない場合、動作を停止します
  • wsfファイルをドラッグ&ドロップすることでも実行できます

ソースコード

<?xml version="1.0" encoding="UTF-16" standalone="yes" ?>
<package>
  <job>
    <?job error="false" debug="false" ?>
    <runtime>
      <description>WSF 1 File conversion tool.</description>
      <unnamed name="path" many="false" required="true" helpstring="WSF file path"/>
    </runtime>
    <script language="JavaScript">
//<![CDATA[
/*!
 * wsfpack.wsf v3
 *
 * Copyright (c) 2019 toshi - https://www.bugbugnow.net/p/profile.html
 * Released under the MIT license.
 * see https://opensource.org/licenses/MIT
 */

/**
 * WSFファイルを1ファイルに結合する
 * wsfファイルのXMLを解析して、1つのwsfファイルに出力するスクリプトです。
 * WSFファイルに結合することで、VBScriptに対応します。
 * @requires    module:WScript
 * @auther      toshi(https://www.bugbugnow.net/p/profile.html)
 * @license     MIT License
 * @version     3
 * @see         1 - 20190525 - add - 初版
 * @see         2 - 20200114 - update - エラー関連を追記
 * @see         2 - 20200114 - update - DOMDocumentのsave関数を使用するように変更(UTF-8対応)
 * @see         2 - 20200114 - update - FileUtility.jsから分離(単独ファイル化)
 * @see         3 - 20200116 - update - src属性を削除ではなく、data-src属性として保持するように変更
 */
(function () {
  "use strict";

  var fs = new ActiveXObject('Scripting.FileSystemObject');
  var sh = new ActiveXObject('WScript.Shell');

  /**
   * PrivateUnderscore.js
   * @version   5
   */
  {
    function _Process_createActiveXObjects(progIDs) {
      for (var i=0; i<progIDs.length; ++i) {
        try {
          return new ActiveXObject(progIDs[i]);
        } catch (e) {
          if (i == progIDs.length - 1) {  throw e;  }
        }
      }
      return null;
    };
    function _Process_createDOMDocument() {
      return _Process_createActiveXObjects([
        'MSXML2.DOMDocument.6.0',
        'MSXML2.DOMDocument.3.0',
        'Msxml2.DOMDocument',
        'Msxml.DOMDocument',
        'Microsoft.XMLDOM']);
    };
    function _Process_getArguments() {
      var arg = [];
      for (var i=0; i<WScript.Arguments.Unnamed.length; i++) {
        arg.push(WScript.Arguments.Unnamed.Item(i));
      }
      return arg;
    };
    function _loadText(path, opt_charset) {
      var ret, fullpath, 
          charset = opt_charset,
          skip = false;

      if (charset == null) { charset = '_autodetect_all'; }
      charset = charset.toLowerCase();

      fullpath = fs.GetAbsolutePathName(path);
      if (!fs.FileExists(fullpath)) {
        // ファイルなし
        return null;
      } else if (fs.GetFile(fullpath).size === 0) {
        // 空ファイル
        return '';
      }

      var sr = new ActiveXObject('ADODB.Stream');
      sr.Type = 2;
      if (charset == '_autodetect_all' || charset == 'utf-16be') {
        // BOMを確認してUTF-8とUTF-16だけ、手動で判定する
        // UTF-16BEは、BOMあり時にBOM削除されないため、手動でスキップする
        var pre = new ActiveXObject('ADODB.Stream');
        pre.Type = 2;
        pre.Charset = 'us-ascii';
        pre.Open();
        pre.LoadFromFile(fullpath);
        var bom = [];
        bom.push(pre.EOS || escape(pre.ReadText(1)));
        bom.push(pre.EOS || escape(pre.ReadText(1)));
        bom.push(pre.EOS || escape(pre.ReadText(1)));
        if (charset == 'utf-16be') {
          if (bom[0] == '%7E' && bom[1]== '%7F') {
            skip = true;
          }
        } else if (bom[0] == 'o'   && bom[1]== '%3B' && bom[2]== '%3F') {
          charset = 'utf-8';
        } else if (bom[0] == '%7F' && bom[1]== '%7E') {
          charset = 'utf-16le';
        } else if (bom[0] == '%7E' && bom[1]== '%7F') {
          charset = 'utf-16be';
          skip = true;
        }
        pre.Close();
        pre = null;
      }
      sr.Charset = charset;

      // ファイルから読み出し
      sr.Open();
      sr.LoadFromFile(fullpath);
      if (skip) {
        // 先頭一文字(BOM)を空読み
        sr.ReadText(1);
        ret = sr.ReadText();
      } else {
        ret = sr.ReadText();
      }

      // 終了処理
      sr.Close();
      sr = null;
      return ret;
    };
  }

  function main() {
    // 引数
    var args = _Process_getArguments();
    var path = args[0];

    var fullpath = fs.GetAbsolutePathName(path);
    if (!fs.FileExists(fullpath)) {
      WScript.Echo('file not found.\n'+fullpath);
      return -1;
    } else if (fs.GetExtensionName(fullpath).toLowerCase() != 'wsf') {
      WScript.Echo('wsf file not found.');
      return -2;
    } else {
      // ルートディレクトリをパックファイルのパスに設定(相対パス対策)
      sh.CurrentDirectory = fs.GetParentFolderName(fullpath);

      // wsfを読込み
      var text = _loadText(fullpath);
      var doc = _Process_createDOMDocument();
      doc.loadXML(text);

      // wsfを解析
      var scripts = doc.selectNodes('//script');
      for (var i=0; i<scripts.length; i++) {
        var src = scripts[i].getAttribute('src');
        if (src == null) {
        } else if (scripts[i].text != '') {
          WScript.Echo('Both "src" and "text" are set.\n'+src);
          return -3;
        } else if (!fs.FileExists(fs.GetAbsolutePathName(src))) {
          WScript.Echo('file not found.\n'+src);
          return -4;
        } else {
          scripts[i].text = '\n' + _loadText(src) + '\n';
          scripts[i].removeAttribute('src');
          scripts[i].setAttribute('data-src', src);
          // 補足:text代入時に、XML使用不可文字はエンティティ参照に置き換えられる
        }
      }

      // ファイル出力
      var filename = fs.GetBaseName(fullpath);
      doc.save(filename+'.pack.wsf');

      WScript.Echo('complete.');
    }
    return 0;
  }

  main();
})();
//]]>
    </script>
  </job>
</package>

変更履歴

更新日 説明
2019/05/25 v1 - add - 初版
2012/01/14 v2 - update - エラー関連を追記
2012/01/14 v2 - update - DOMDocumentのsave関数を使用するように変更(UTF-8対応)
2012/01/14 v2 - update - FileUtility.jsから分離(単独ファイル化)
2012/01/16 v3 - update - src属性を削除ではなく、data-src属性として保持するように変更

コメント