Hatena::Groupmoz-addon

Ci.nsIZIGOROu

2007-11-01風邪治らない

COMの列挙再び

| 04:38 |  COMの列挙再び - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  COMの列挙再び - Ci.nsIZIGOROu

幾つか方法がある。

WMIのWQLを使う

var locator = new ActiveXObject("WbemScripting.SWbemLocator");
var service = locator.ConnectServer(null, "root\\cimv2");
var rs = service.execQuery("SELECT * FROM Win32_ClassicCOMClassSetting WHERE ProgID <> NULL");

WScript.Echo(rs.count);

var rsEnum = new Enumerator(rs);

for (; !rsEnum.atEnd(); rsEnum.moveNext()) {
  WScript.Echo(rsEnum.item().ProgId);
}

ちなみにこの時取れるカラムは以下のとおり。

  • AppID
  • AutoConvertToClsid
  • AutoTreatAsClsid
  • Caption
  • ComponentId
  • Control
  • DefaultIcon
  • Description
  • InprocHandler
  • InprocHandler32
  • InprocServer
  • InprocServer32
  • Insertable
  • JavaClass
  • LocalServer
  • LocalServer32
  • LongDisplayName
  • ProgId
  • SettingID
  • ShortDisplayName
  • ThreadingModel
  • ToolBoxBitmap32
  • TreatAsClsid
  • TypeLibraryId
  • Version
  • VersionIndependentProgId

このカラム名も取得できます。

var pEnum = new Enumerator(rsEnum.item().Properties_);
for (; !pEnum.atEnd(); pEnum.moveNext()) {
  WScript.Echo(pEnum.item().name);
}

ただどういう訳か、一部列挙出来ない物があるみたい。

WMIのセキュリティ設定が云々っぽぃんだけど謎。

WMIからRegStdProvオブジェクトを使う

serviceの取得手順がちょっと違う。

// これ専用、Array.prototype.forEachがあればウマーなんだけどな
Enumerator.prototype.toArray = function() { 
  var result = []; 
  this.moveFirst(); 
  for (; !this.atEnd(); this.moveNext()) {
    result.push(this.item().name); 
  } 
  this.moveFirst(); 
  return result; 
};

var locator = new ActiveXObject("WbemScripting.SWbemLocator"); // [object SWbemLocator]
var service = locator.ConnectServer(null, "root\\default"); // [object SWbemServicesEx] 第二引数の値が違う
var srp = service.Get("StdRegProv"); // [object SWbemObjectEx]

// メソッド名列挙
var mEnum = new Enumerator(srp.Methods_);
WScript.Echo(mEnum.toArray().join(","));
// CreateKey,DeleteKey,EnumKey,EnumValues,DeleteValue,
// SetDWORDValue,GetDWORDValue,SetStringValue,GetStringValue,
// SetMultiStringValue,GetMultiStringValue,SetExpandedStringValue,
// GetExpandedStringValue,SetBinaryValue,GetBinaryValue,CheckAccess

var method = srp.Methods_.item("EnumKey"); // [object SWbemMethod]
var params = method.InParameters.SpawnInstance_(); // [object SWbemObjectEx]

// メソッドのパラメータ列挙
var pEnum = new Enumerator(params);
WScript.Echo(pEnum.toArray().join(","));
// hDefKey,sSubKeyName

params.hDefKey = 0x80000000; // HKEY_CLASSES_ROOTの値
params.sSubKeyName = "CLSID";

var rs = srp.execMethod_(method.name, params); // [object SWbemObjectEx]

WScript.Echo(rs.ReturnValue);
WScript.Echo(rs.sNames.toArray()); // これでCLSIDが全部列挙される

が、しかしWMIを使うとどうしても列挙出来ない奴がある。(MSWInsock.Winsockとか)

あとEnumerator使いまくると便利。

予めEnumerator, Array辺りはprototype拡張必要かも。

具体的には、

params.sSubKeyName = "MSWinsock.Winsock\\";

として実行するとCLSIDとかキー名が列挙出来てもいいはずなんだけど出来ない。

一方で、WScript.ShellのRegReadすると見事に取れる。

var wshell = new ActiveXObject("WScript.Shell"); 
WScript.Echo(wshell.RegRead("HKCR\\MSWinsock.Winsock\\CLSID\\"));
// {248DD896-BB45-11CF-9ABC-0080C7E7B78D}
WScript.Echo(wshell.RegRead("HKCR\\CLSID\\{248DD896-BB45-11CF-9ABC-0080C7E7B78D}\\VersionIndependentProgID\\"));
// MSWinsock.Winsock

なんでやねん!!!

ZIGOROuZIGOROu2007/11/03 04:15RegSrvc.Registry

ZIGOROuZIGOROu2007/11/03 04:29COMAdmin.COMAdminCatalog

ZIGOROuZIGOROu2007/11/03 04:32TxCTx.TransactionContextEx

ZIGOROuZIGOROu2007/11/03 04:47COMSVCSLibがあつそうだ

ZIGOROuZIGOROu2007/11/03 04:49COMCRFLibはパーサー用っぽぃな

ZIGOROuZIGOROu2007/11/03 04:51COMEXPSLibはメニューとかかな

MatwoonryMatwoonry2019/07/29 00:11Viagra For Less Pharmacy Rx One Review Viagra Prescription <a href=http://etrobax.com>where to buy cialis online safely</a> Come Comprare Viagra Senza Ricetta Medica

MatwoonryMatwoonry2019/07/31 19:38Levitra 10mg Generique Worldwide Pharmacy Ventalin <a href=http://cheapcheapvia.com>viagra</a> Cialis Discount Coupon Generic Prevacid Online

MatwoonryMatwoonry2019/08/03 21:44Determining Correct Amoxicillin Dosage Cephalexin For Dog Tadalafil 5 Mg Best Price Usa <a href=http://genericcial.com>cialis for sale</a> Viagra 50mg Wirkung

MatwoonryMatwoonry2019/08/06 16:27When Will Alli Be Back In Stock Cialis Prix France Pharmacie <a href=http://drugs20.com>cialis from canada</a> Zithromax Zpak Cialis Fast Delivery

2007-10-23

WMI (1)

| 04:20 |  WMI (1) - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  WMI (1) - Ci.nsIZIGOROu

とりあえず

var locator = new ActiveXObject("WbemScripting.SWbemLocator");
var service = locator.ConnectServer(null, "root\\cimv2"); // ここまでおまじない
var com = service.execQuery("SELECT * FROM Win32_ClassicCOMClassSetting WHERE ProgID <> NULL AND TypeLibraryId <> NULL");

このいかにもSQLちっくな奴はWQLと言うらしい。ってかほぼSQLです。w

LIKE句も使えた。

このテーブルもどきみたいな奴は、no title辺りから漁れるみたい。

ちなみにWQL使った検索、めちゃくちゃ早い。Registryなんて見ちゃダメだたね。



WMIとProgIDメモ

| 03:39 |  WMIとProgIDメモ - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  WMIとProgIDメモ - Ci.nsIZIGOROu

  1. WbemScripting.SWbemDateTime
  2. WbemScripting.SWbemLastError
  3. WbemScripting.SWbemLocator
  4. WbemScripting.SWbemNamedValueSet
  5. WbemScripting.SWbemObjectPath
  6. WbemScripting.SWbemRefresher
  7. WbemScripting.SWbemSink

むぅ、多いなぁ。

参考

  1. no title
  2. no title

覚えておくと便利なActiveXコントロール集

| 21:53 |  覚えておくと便利なActiveXコントロール集 - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  覚えておくと便利なActiveXコントロール集 - Ci.nsIZIGOROu

あとは自分のこのブログでの検索。

随時追加する。

ScriptX.Factory
本来プリンタ云々の為に使うらしいけどEventSinkでキモいCOMイベントに対してハンドラを追加出来るようになる。(Download: Home page - ScriptX)
ScriptControl
任意のスクリプトエンジンを動的に組み込む為のコントロール
MSWinsock.Winsock
ネットワーク系コントロールとしては最も低レベルなコントロール。大概これでネットワークスクリプトは書ける
TLI.TLIApplication
TypeLibをinspectするコントロール。素敵。恐らくVisual Studioが入って無いと存在しない。
Shell.Application
Windowsの簡易操作、Explorer/Internet Explorerの管理など
Scripting.FileSystemObject
FileSystemを扱うコントロール
WbemScripting.SWbemLocator
WMIを扱うコントロール、schema指定もあるけどどう違うか分からない。そのうち詳細に。
InternetExplorer.Application
IEの画面そのもの。メニューバーとかコンテキストメニューとかは含まない。端的に言えばWebControl
Scriptlet.TypeLib
TypeLibの生成、GUIDの生成、DHTML Behavior Componentの何か。*1
htmlfile
JSで言うならdocumentオブジェクト相当。IEのレンダリング部。IHTMLDocumentインターフェースかな。
Scripting.Dictionary
Hash的な使い方が出来る。
ADODB.Stream
IStreamを実装したコンポーネント。バイナリ処理する時も必要。

TODO

  • MSXML系
  • ADODB系
  • htmlfilemshtml

他なんかあったかな。忘れた。

*1:Behaviorの方は多分知らなくて良いw

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

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直下のレジストリのキーを列挙出来る。

この辺りを参考にした。