Hatena::Groupmoz-addon

Ci.nsIZIGOROu

2007-08-08一度痛い目に遭った方がいい

続・COMの列挙

| 21:33 |  続・COMの列挙 - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  続・COMの列挙 - Ci.nsIZIGOROu

CLSID, Interfaceからcomponent, interfaceを全部レジストリから取ってきて、それをjson化しておく。

そのjsonを吐き出すスクリプトと、jsonを読んでXPConnect風味なオブジェクトを作るライブラリをそれぞれ作る。

ってかレジストリの総当り読み込み凄い重たい事が分かった。

COMの列挙

| 20:16 |  COMの列挙 - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  COMの列挙 - Ci.nsIZIGOROu

そろそろビリヤードに行くのでソースだけ貼り付ける。

var inspect = function(obj, maxDepth, name, curDepth) {
    var crop = function(string, max) {
        string = string.match(/^(.+?)(\n|$)/m)[1];   
        max = max || 70;
        return string.length > max - 3 ? string.slice(0, max - 3) + "..." : string;
    };

    if (typeof name == "undefined") {
        name = "<" + typeof obj + ">";
    }
    if (typeof maxDepth == "undefined") {
        maxDepth = 0;
    }
    if (typeof curDepth == "undefined") {
        curDepth = 0;
    }
    if (typeof maxDepth != "undefined" && curDepth > maxDepth) {
        return;
    }

    var i = 0;
    
    for (var prop in obj) {
        try {
            i++;

            if (typeof obj[prop] == "object") {
                if (typeof obj.length != "undefined") {
                    WScript.Echo(name + "." + prop + "=[probably array, length " + obj[prop].length + "]");
                } 
                else {
                    WScript.Echo(name + "." + prop + "=[" + typeof obj[prop] + "]");
                }

                arguments.callee(obj[prop], maxDepth, name + "." + prop, curDepth + 1);
            }
            else if (typeof obj[prop] == "function") {
                WScript.Echo(name + "." + prop + "=[function]");
            }
            else {
                WScript.Echo(name + "." + prop + "=" + obj[prop]);
            }
        };
        catch (e) {
            WScript.Echo(name + "." + prop + " - Exception while inspecting.");
        }
    }
    if (!i) {
        WScript.Echo(name + " is empty");
    }
};

var Components_Class = function(name, number) {
    this.name = name;
    this.number = number;
};

Components_Class.prototype = {
    name: null,
    number: null,
    toString: function() {
        return this.name;
    }
};

var Components_Classes = function() {
};

var Components = {
    registry: null,
    classes: null,
    interfaces: null,
    init: function() {
        this.classes = new Components_Classes();

        this.registry = (new ActiveXObject("WbemScripting.SWbemLocator")).ConnectServer(null, "root\\default").Get("StdRegProv");

        var HKCR = 0x80000000;
        var subKeyName = "CLSID";
        var clsid = this.getRegistryKeys(HKCR, subKeyName);
        var regex = /(\.\d+)+$/;

        for (var i = 0, l = clsid.length; i < l; i++) {
            var progIDKey = ([subKeyName, clsid[i], "ProgID"]).join("\\");
            var progID = this.getRegistryStringValue(HKCR, progIDKey, null);

            this.classes[progID] = new Components_Class(progID, clsid[i]);

            if (regex.exec(progID)) {
                var sprogID = progID.replace(regex, "");
                this.classes[sprogID] = new Components_Class(sprogID, clsid[i]);
            }
        }
    },
    getRegistryStringValue: function(defKey, subKeyName, valueName) {
        var result = this.callRegistryMethod("GetStringValue", {
            hDefKey: defKey,
            sSubKeyName: subKeyName,
            sValueName: valueName
        });
        
        return result.sValue;
    },
    getRegistryKeys: function(defKey, subKeyName) {
        var result = this.callRegistryMethod("EnumKey", {
            hDefKey: defKey,
            sSubKeyName: subKeyName
        });

        return result.sNames.toArray();
    },
    callRegistryMethod: function(methodName, args) {
        var method = this.registry.Methods_.Item(methodName);
        var params = method.InParameters.SpawnInstance_();

        for (var name in args) {
            params[name] = args[name];
        }

        return this.registry.ExecMethod_(method.Name, params);
    },
    inspect: inspect
};

Components.init();
Components.inspect(Components.classes);

WSHを使ってRegistryのキーを列挙する

| 17:44 |  WSHを使ってRegistryのキーを列挙する - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  WSHを使ってRegistryのキーを列挙する - Ci.nsIZIGOROu

WScript.Shellを使うと特定のレジストリの値の読み込み、書き込み、削除は出来るんですが、列挙が出来ない。

そこでWMIを使うと。

ここら辺の技術背景は良く分からないので、あとで書く。

var locator = new ActiveXObject("WbemScripting.SWbemLocator");
var server = locator.ConnectServer(null, "root\\default");
var registry = server.Get("StdRegProv");

var method = registry.Methods_.Item("EnumKey");
var iParams = method.InParameters.SpawnInstance_();

iParams.hDefKey = 0x80000000; // HKEY_CLASSES_ROOT
iParams.sSubKeyName = ""; 

var result = registry.ExecMethod_(method.Name, iParams);
var keys = result.sNames.toArray();

for (var i = 0, l = keys.length; i < l; i++) {
    WScript.Echo(keys[i]);
}

こんなスクリプトでHKEY_CLASSES_ROOT直下のレジストリのキーを列挙出来る。

この辺りを参考にした。

StdRegProv.EnumKey()で使うRegistryのルート

| 17:24 |  StdRegProv.EnumKey()で使うRegistryのルート - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  StdRegProv.EnumKey()で使うRegistryのルート - Ci.nsIZIGOROu

NameValue
HKEY_CLASSES_ROOT 2147483648, 0x80000000
HKEY_CURRENT_USER 2147483649, 0x80000001
HKEY_LOCAL_MACHINE 2147483650, 0x80000002
HKEY_USERS 2147483651, 0x80000003
HKEY_CURRENT_CONFIG 2147483653, 0x80000005
HKEY_DYN_DATA 2147483654, 0x80000006

RegistryとCOMのメモ

| 15:37 |  RegistryとCOMのメモ - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  RegistryとCOMのメモ - Ci.nsIZIGOROu

  • HKEY_CLASSES_ROOT
  • HKEY_LOCAL_MACHINE\SOFTWARE\Classes
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole

参考 : http://www.atmarkit.co.jp/fwin2k/operation/wsh03/wsh03_02.html