• jscriptから WMIを使ってレジストリキー/値列挙

    regコマンド+query操作の方が手っ取り早くはある。。。

    ↓のページに書かれているように、VBScriptだとStdRegProvオブジェクトにEnumKey/EnumValuesなどのメソッドが生えているが、jscriptからだとこれらがない。
     Writing WMI Scripts in JScript (Windows)

    StdRegProvをGetして、
    var locator = new ActiveXObject("WbemScripting.SWbemLocator");
    var server = locator.ConnectServer(computer, "root\\default");
    this.stdregprov = server.Get("StdRegProv");

    呼び出したいメソッド用の入力パラメータを入れる箱のインスタンスを取得して、呼び出したいメソッド用のパラメータ設定をし、
    var in_param = this.stdregprov.Methods_.Item(method_name).InParameters.SpawnInstance_();
    in_param.hDefKey = hkey;
    in_param.sSubKeyName = key;

    StdRegProvにメソッドを呼び出してもらい、
    var out = this.stdregprov.ExecMethod_(method_name, in_param);

    呼び出したメソッドに合わせて結果を取り出す(EnumKeyの例)
    var names = [];
    if(out_param.sNames != null)
    {
    names = out_param.sNames.toArray();
    }
    return names;


    WMIを経由したことでリモートコンピュータに対しても同じコードで処理出来るのはメリットかも。
    しかし、
    •  regコマンドqueryでもリモートコンピュータのキーを列挙できる
    •  リモートコンピュータに対してレジストリ参照するには、当該コンピュータでWindows RPCが動作していて、なおかつWindows Firewallにはじかれないこと
    ので注意。ちまちまと複数のキーを列挙しないといけない状況で外部コマンドをぽこぽこ起動したくない or 一時ファイルを作りたくない、とするならばjscriptで完結するのはいいかもしれない。

    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall配下を列挙するサンプル。
    例によって無保証です。利用は自己責任で。
    WScript.Echo()しているのでcscript.exeで実行を推奨。

    (function() {

    var Registry = function () {
    this.initialize.apply(this, arguments);
    };

    Registry.prototype = {
    initialize: function(computer) {
    var locator = new ActiveXObject("WbemScripting.SWbemLocator");
    var server = locator.ConnectServer(computer, "root\\default");
    this.stdregprov = server.Get("StdRegProv");

    this.HKCR = 0x80000000; // HKEY_CLASSES_ROOT
    this.HKCU = 0x80000001; // HKEY_CURRENT_USER
    this.HKLM = 0x80000002; // HKEY_LOCAL_MACHINE
    this.HKUS = 0x80000003; // HKEY_USERS
    this.HKCC = 0x80000005; // HKEY_CURRENT_CONFIG

    this.REG_SZ = 1;
    this.REG_EXPAND_SZ = 2;
    this.REG_BINARY = 3;
    this.REG_DWORD = 4;
    this.REG_MULTI_SZ = 7;
    },

    do_method: function(method_name, hkey, key, value_name) {
    var in_param = this.stdregprov.Methods_.Item(method_name).InParameters.SpawnInstance_();
    in_param.hDefKey = hkey;
    in_param.sSubKeyName = key;
    if(value_name != null)
    {
    in_param.sValueName = value_name;
    }
    var out = this.stdregprov.ExecMethod_(method_name, in_param);
    return out;
    },

    EnumKey: function(hkey, key) {
    var out_param = this.do_method("EnumKey", hkey, key);
    var names = [];
    if(out_param.sNames != null)
    {
    names = out_param.sNames.toArray();
    }
    return names;
    },

    EnumValues: function(hkey, key) {
    var out_param = this.do_method("EnumValues", hkey, key);
    var value_names = [];
    if(out_param.sNames != null)
    {
    value_names = out_param.sNames.toArray();
    }
    var value_types = [];
    if(out_param.Types != null)
    {
    value_types = out_param.Types.toArray();
    }

    return {
    Names: value_names,
    Types: value_types
    };
    },

    GetStringValue: function(hkey, key, name) {
    // REG_SZ
    var out_param = this.do_method("GetStringValue", hkey, key, name);

    // 値が存在しない場合null
    return out_param.sValue;
    },

    GetExpandedStringValue: function(hkey, key, name) {
    // REG_EXPAND_SZ
    var out_param = this.do_method("GetExpandedStringValue", hkey, key, name);

    // 値が存在しない場合null
    return out_param.sValue;
    },

    GetDWORDValue: function(hkey, key, name) {
    // REG_DWORD
    var out_param = this.do_method("GetDWORDValue", hkey, key, name);

    // 値が存在しない場合null
    return out_param.uValue;
    }
    };

    var enum_installs = function(reg, base_key)
    {
    var names = reg.EnumKey(reg.HKLM, base_key);
    for(var i = 0 ; i < names.length; i++)
    {
    WScript.Echo(names[i]);

    var sub_key = base_key + "\\" + names[i];
    var values = reg.EnumValues(reg.HKLM, sub_key);

    var value_names = values.Names;
    var value_types = values.Types;

    for(var j = 0 ; j < value_names.length; j++)
    {
    var value_name = value_names[j];
    var value_type = value_types[j];
    var val = "";
    switch(value_type)
    {
    case reg.REG_SZ:
    val = reg.GetStringValue(reg.HKLM, sub_key, value_name);
    break;
    case reg.REG_EXPAND_SZ:
    val = reg.GetExpandedStringValue(reg.HKLM, sub_key, value_name);
    break;
    case reg.REG_DWORD:
    val = reg.GetDWORDValue(reg.HKLM, sub_key, value_name);
    break;
    }

    if(val == null)
    {
    val = "";
    }

    // 改行をつぶしちゃう
    val = val.toString().replace(/[\x0a\x0d]/g, " ");
    WScript.Echo(["", value_name, value_type, val].join("\t"));
    }
    }

    };

    var computer = WScript.Arguments.Named("computer");
    if(!computer)
    {
    computer = ".";
    }

    var reg = new Registry(computer);

    enum_installs(reg, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
    enum_installs(reg, "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"); })();

    環境:
    Windows XP Professional SP3
    Windows Vista Ultimate SP2 x64
    Windows Server 2008 SE x64

  • 複数の.pptを 一括して.ppsで保存する

    複数の.pptをスライドショー形式(.pps)にぽちぽち名前をつけて保存する、を一括して実行するマクロなjscript。

    • 指定されたpptをスライドショー(pps)で書き出す。
    • エクスプローラ上でpptまたはフォルダをjsにドロップするか、コマンドプロンプトから実行
    • フォルダを指定した場合、同フォルダ内(直下)の*.pptを処理対象にする。
    • ファイル名.ppt→ファイル名.pps、同名のppsが既に存在する場合、問答無用で上書き
    • 実行は自己責任で行ってください。いかなる結果にも責任を負いかねます。

    cscript save_as_pps.js /out:出力ディレクトリ {入力ppt|入力フォルダ}...
      - 出力先明示
    cscript save_as_pps.js {入力ppt|入力フォルダ}...
      - 元pptと同じフォルダに出力

    ちらっとgoogle先生に聞いてみたら、2003以前だと拡張子をppsにするだけでいいらしい。。。

    ■手元の環境
    Windows XP Pro SP3 + MS Office 2003 Professional SP3
    Windows Vista Ultimate SP1 x64 + MS Office 2007 Standard SP1
    ■save_as_pps.js
    /**
    * 指定されたpptをスライドショー(pps)で書き出す。
    * エクスプローラ上でpptまたはフォルダをjsにドロップするか、
    * コマンドプロンプトから実行
    *
    * cscript save_as_pps.js /out:出力ディレクトリ {入力ppt|入力フォルダ}...
    * - 出力先明示
    *
    * cscript save_as_pps.js {入力ppt|入力フォルダ}...
    * - 元pptと同じフォルダに出力
    *
    * フォルダを指定した場合、同フォルダ内(直下)の*.pptを処理対象にする。
    *
    * My env.
    * - Windows XP Pro SP3 + MS Office 2003 Professional SP3
    * - Windows Vista Ultimate SP1 x64 + MS Office 2007 Standard SP1
    */


    // PowerPoint
    var PpSaveAsFileType= {
    ppSaveAsPresentation: 1,
    ppSaveAsPowerPoint7: 2,
    ppSaveAsPowerPoint4: 3,
    ppSaveAsPowerPoint3: 4,
    ppSaveAsTemplate: 5,
    ppSaveAsRTF: 6,
    ppSaveAsShow: 7,
    ppSaveAsAddIn: 8,
    ppSaveAsPowerPoint4FarEast: 10,
    ppSaveAsDefault: 11,
    ppSaveAsHTML: 12,
    ppSaveAsHTMLv3: 13,
    ppSaveAsHTMLDual: 14,
    ppSaveAsMetaFile: 15,
    ppSaveAsGIF: 16,
    ppSaveAsJPG: 17,
    ppSaveAsPNG: 18,
    ppSaveAsBMP: 19
    };


    // --------------------------------------------------------------


    /**
    * pptファイルをppsでsaveasする
    *
    */
    function SaveAsPPS() {
    this.initialize.apply(this, arguments);
    }

    SaveAsPPS.prototype = {
    initialize: function() {
    this.fso = WScript.CreateObject("Scripting.FileSystemObject");
    },

    /**
    * 1ppt分の処理
    *
    */
    saveOne: function(app, options, fn_ppt) {
    var dir_out;
    if(options.samefolder) {
    // 元pptと同じフォルダに出力
    dir_out = this.fso.GetParentFolderName(fn_ppt);
    } else {
    // 出力先が明示されている
    dir_out = options.out;
    }

    if(!this.fso.FolderExists(dir_out)) {
    this.fso.CreateFolder(dir_out);
    }

    var prs = app.Presentations.Open(fn_ppt, true, true, false);

    try {
    var fn_out = this.fso.BuildPath(dir_out, this.fso.GetBaseName(fn_ppt) + ".pps");
    prs.SaveAs(fn_out, PpSaveAsFileType.ppSaveAsShow, options.embedfont);
    } catch(ex) {
    throw ex;
    } finally {
    prs.Close();
    }
    },

    /**
    * main
    *
    * @param argv WScript.Arguments
    */
    main: function(argv) {
    // オプション
    var opt = argv.Named;

    var options = {
    // 出力先フォルダ
    out: ".",
    // 保存先を元pptと同じにするflag
    samefolder: true,
    // フォントを埋め込むかどうか
    embedfont: true
    };

    if(opt.Item("nofont")) {
    options.embedfont = false;
    }

    if(opt.Item("out")) {
    options.out = opt.Item("out") ;
    options.samefolder = false;
    }
    options.out = this.fso.GetAbsolutePathName(options.out);

    var ppt_app = new ActiveXObject("PowerPoint.Application");

    try {
    // 引数
    var args = argv.Unnamed;
    for(var i = 0 ;i < args.length; i++) {
    var fn_ppt = this.fso.GetAbsolutePathName(args(i));
    if(this.fso.FolderExists(fn_ppt)) {
    // 引数がフォルダなら、当該フォルダ内のpptを処理対象に
    var folder = this.fso.GetFolder(fn_ppt);
    for(var it = new Enumerator(folder.Files); !it.atEnd(); it.moveNext()) {
    var file = it.item();
    if(file.Name.match(/\.ppt$/i)) {
    fn_ppt = file.Path;
    this.saveOne(ppt_app, options, fn_ppt);
    }
    }
    } else if(this.fso.FileExists(fn_ppt)) {
    // 引数がファイルの場合
    this.saveOne(ppt_app, options, fn_ppt);
    } else {
    WScript.echo("*** ppt not found: " + fn_ppt);
    return false;
    }

    }

    } catch(ex) {
    throw ex;
    } finally {
    ppt_app.Quit();
    }

    }
    }

    // --------------------------------------------------------------

    var app = new SaveAsPPS();
    app.main(WScript.Arguments);


  • jscriptで utf8なファイル出力

    ADODB.Streamを使うと、SJIS以外のエンコードに変換可能。
    て、ことが以下のURLに書いてある。
    ADODB.Stream を使ったファイルの読み書き - by AOK
    こんな方法があるとはな~。

    こっちはさらに、utf-8出力時のBOMをどう除去するか、という話
    JavaScriptでファイルの書き込みをUTF-8で行う(htaまたは、wsh用) - jiroの日記
    ADODB.Streamを2つ使い、Positionを移動することでBOMをskipして出力。なるほどなー。

    とりあえずSJIS出力で我慢しといて、iconvで変換するか、とか考えたけど、最初からutf-8で書き出せれば便利だ。


    /* ADODB.Stream - SaveOptionsEnum */
    var adSaveCreateOverWrite = 2;

    /* ADODB.Stream - StreamTypeEnum */
    var adTypeBinary = 1;
    var adTypeText = 2;

    /* ADODB.Stream - StreamWriteEnum */
    var adWriteChar = 0;
    var adWriteLine = 1;

    var st = new ActiveXObject("ADODB.Stream");
    st.type = adTypeText;
    st.charset = "utf-8";
    st.open();

    st.WriteText( なにか出力 , adWriteLine );

    st.Position = 0;
    st.Type = adTypeBinary;
    st.Position = 3; ←utf8なら3
    var bin = st.Read();
    st.Close();

    var stw = new ActiveXObject("ADODB.Stream");
    stw.Type = adTypeBinary;
    stw.Open();
    stw.Write( bin );
    stw.SaveToFile( 出力ファイル , adSaveCreateOverWrite );
    stw.Close();