スポンサーリンク

WSHのCreateObject関数の引数のCOM識別子「ProgID」「CLSID」(GUID)とは何なのか解説。Windows内のActiveXオブジェクトを一覧表示して確認するコマンド

WSHなどのWindowsプログラミングでよく使う「CLSID」「ProgID」について解説。


WSHで,CreateObject() の引数を不思議に思ったことはあるだろうか?

"InternetExplorer.Application" とか "Excel.Application" など,

別のアプリ(自動操作したいCOMオブジェクト)を特定するための文字列が入り,これを ProgID と呼ぶ。

(1)「CLSID」や「ProgID」を一覧表示するコマンド

まずWindowsで,PC内に存在する「ProgID」や「CLSID」をすべて一覧表示して確認するコマンドがある。


コマンドプロンプトですぐに実行して確認できる。

レジストリの内容をリストアップしているだけだが。


ProgIDを一覧表示するコマンド:

reg query HKEY_LOCAL_MACHINE\Software\Classes\


.Application という文字列を含むようなProgIDだけを列挙するコマンド:

reg query HKEY_LOCAL_MACHINE\Software\Classes\ | findstr \.Application | more


上記のコマンドの実行結果の例:

HKEY_LOCAL_MACHINE\Software\Classes\InternetExplorer.Application
HKEY_LOCAL_MACHINE\Software\Classes\InternetExplorer.Application.1
HKEY_LOCAL_MACHINE\Software\Classes\iTunes.Application
HKEY_LOCAL_MACHINE\Software\Classes\iTunes.Application.1
HKEY_LOCAL_MACHINE\Software\Classes\MMC20.Application
HKEY_LOCAL_MACHINE\Software\Classes\MMC20.Application.1
HKEY_LOCAL_MACHINE\Software\Classes\Shell.Application
HKEY_LOCAL_MACHINE\Software\Classes\Shell.Application.1
HKEY_LOCAL_MACHINE\Software\Classes\System.ApplicationException
HKEY_LOCAL_MACHINE\Software\Classes\System.Runtime.Hosting.ApplicationActivator
HKEY_LOCAL_MACHINE\Software\Classes\System.Security.Policy.ApplicationDirectoryMembershipCondition
HKEY_LOCAL_MACHINE\Software\Classes\System.Security.Policy.ApplicationTrust
HKEY_LOCAL_MACHINE\Software\Classes\WindowsLiveWriter.Application
HKEY_LOCAL_MACHINE\Software\Classes\WindowsLiveWriter.Application.1


CLSIDを一覧表示するコマンド:

reg query HKEY_CLASSES_ROOT\TypeLib\

(2)ProgIDの具体例

ProgIDのわかりやすい例は,

"InternetExplorer.Application" とか "Excel.Application" など。


このような ProgID は,WSHなどのプログラム中で,他のアプリケーションを呼び出すために使う。

たとえば,WSHから IE を呼び出したり, Excelを自動操作したりできる。

そのために,CreateObject関数にProgIDを引数として渡すのだ。

ブラウザのビジー状態を判定するための,より良い方法 (WSHでIEを自動操作する際,COMのアプリケーションイベントを利用する)
http://language-and-engineering.hatenablog.jp/entry/20100410/p1

  • CreateObjectメソッドには、
    • ProgIDを指定する第1引数のほかに、
    • イベントを監視するためのプリフィックス(接頭辞)を指定する、省略可能な第2引数が存在する


マイクロソフト製品の ProgID の特徴は,"~.Application" という形式をしていることだ。

そのようなProgIDを使ったコードのサンプル:

JScript / VBScript (WSH)で,IEを自動操作しよう
http://language-and-engineering.hatenablog.jp/entry/20090713/p1

  • CreateObject("InternetExplorer.Application")


バッチで,Word文書の内容を読み取ろう (WSH/JScriptでWordファイルを操作する方法)
http://language-and-engineering.hatenablog.jp/entry/20101105/p1

  • CreateObject("Word.Application")


JScript/WSH で,Excelファイルを読み書きしよう
http://language-and-engineering.hatenablog.jp/entry/20090717/p1

  • CreateObject("Excel.Application")


WSH/JScriptで,Outlookを操作しよう (受信メール内からURLを抽出してみる)
http://language-and-engineering.hatenablog.jp/entry/20100324/p1

  • CreateObject("Outlook.Application")


ほかの有名どころの ProgID も一覧表示してみよう。

C:\Users\user>reg query HKEY_LOCAL_MACHINE\Software\Classes\ | findstr XMLHTTP |
 more
HKEY_LOCAL_MACHINE\Software\Classes\Microsoft.XMLHTTP
HKEY_LOCAL_MACHINE\Software\Classes\Microsoft.XMLHTTP.1.0
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.ServerXMLHTTP
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.ServerXMLHTTP.3.0
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.ServerXMLHTTP.4.0
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.ServerXMLHTTP.6.0
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.XMLHTTP
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.XMLHTTP.3.0
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.XMLHTTP.4.0
HKEY_LOCAL_MACHINE\Software\Classes\Msxml2.XMLHTTP.6.0


C:\Users\user>reg query HKEY_LOCAL_MACHINE\Software\Classes\ | findstr Wbem | more
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemDateTime
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemDateTime.1
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemLastError
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemLastError.1
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemLocator
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemLocator.1
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemNamedValueSet
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemNamedValueSet.1
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemObjectPath
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemObjectPath.1
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemRefresher
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemRefresher.1
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemSink
HKEY_LOCAL_MACHINE\Software\Classes\WbemScripting.SWbemSink.1


上記の ProgID (COM)を使ったスクリプトのサンプル:

コマンドプロンプトを,Webブラウザとして使おう (WSH・JScriptでXmlHttpRequest)
http://language-and-engineering.hatenablog.jp/entry/20100806/p1

  • CreateObject("MSXML2.XMLHTTP")


メモリ・CPUなどハードウェアの構成情報を,バッチで取得しよう (WSH/JScriptでWMIを使う方法)
http://language-and-engineering.hatenablog.jp/entry/20100906/p1

  • CreateObject("WbemScripting.SWbemLocator")


バッチで,画像を生成・加工・一括処理しよう (WSH/JScriptでImageMagickを呼び出す方法)
http://language-and-engineering.hatenablog.jp/entry/20111019/p1

  • CreateObject("ImageMagickObject.MagickImage.1")


また,OpenOffice のProgIDも一覧表示してみよう。

これはPC内にインストールされていないと何も出てこないが。

C:\Users\user>reg query HKEY_LOCAL_MACHINE\Software\Classes\ | findstr sun | more
HKEY_LOCAL_MACHINE\Software\Classes\com.sun.star.ServiceManager
HKEY_LOCAL_MACHINE\Software\Classes\com.sun.star.ServiceManager.1


その ProgID を使ったコードの例:

VBScriptで外部からCalcを使う - Excel VBAプログラミング
http://guajumal.wiki.fc2.com/wiki/VBS...

  • CreateObject("com.sun.star.ServiceManager")


VBScriptでOpenOffice.org Calcを操作する - yakmi
http://qinmoksay.blog72.fc2.com/blog-...

  • CreateObject("com.sun.star.ServiceManager")


VBからOpenOffice.orgを操作する (トピック) • OpenOffice.org コミュニティーフォーラム
https://forum.openoffice.org/ja/forum...

  • CreateObject("com.sun.star.ServiceManager")


ここまでで,

  • ProgID の具体例や,
  • その一覧表示の方法

がよくわかっただろう。

(3)ProgIDとは「アプリの識別子」のこと

ProgID とは「アプリケーションの識別子」である。

これは,レジストリ内にまとめて格納されている。


ProgIDは,基本的にアプリのバージョンに依存しない。

たとえば "InternetExplorer.Application" というProgIDは,

IEのバージョンに関係なく,どのバージョンでも統一して呼び出せる。

レジストリの直接編集によるファイルの拡張子と関連づけ - Glamenv-Septzen.net
http://www.glamenv-septzen.net/view/1...

  • HKEY_LOCAL_MACHINE(HKLM)\SOFTWARE\Classes
  • 「ProgID」とも呼ばれる「アプリケーション識別子」が登録されています


Office アプリケーションのパスを調べる方法
http://support.microsoft.com/kb/24079...

  • ProgID は、バージョンに依存しません。
    • アプリケーションには、バージョン固有の ProgID も存在します。
    • たとえば、Microsoft Excel には、バージョンに依存しない "Excel.Application" という ProgID と、"Excel.Application.8" や "Excel.Application.9" など、バージョン固有の ProgID も存在します。


ActiveXは,やはりProgIDを持っている。

ActiveXはCOMの情報を自動的にレジストリに書き込んで更新する機能を持つ。

COM(Component Object Model)
http://page.freett.com/mnbvcxz/progra...

  • ActiveXとはCOMを使ったプログラムのこと
    • ActiveXとCOMの唯一の違いは,自らレジストリにCOMの情報を登録する機能をもっているか否かである。
  • ActiveXは,自らレジストリにCOMの情報を登録する機能をもっている。
    • そのため,たとえば,Internet ExplorerなどActiveXに対応したWebブラウザは,インターネットからActiveXコントロールをダウンロードしたのち,システムのレジストリにそれを登録して,即座に使うことができる。


ProgIDは,別名AppIDとしても使われる。

進め!中級プログラマー
http://www.asahi-net.or.jp/~gv4j-sgur...

  • CLSID.....COMクラスの識別子(GUID)
  • AppID.....アプリケーションを表す文字列で、ProgIDと同じ用途で使用される( ProgIDと同じ物を与えても構わない)
  • ProgID....CLSIDを参照する文字列("{プログラム名}.{コンポーネント名}.{バージョン番号}"の形式)

(4)ProgIDは,OS内部では「CLSID」として処理される

ProgIDは,人間が見てわかりやすいような名前が付けられている。

おかげでプログラムのソースコードの可読性が上がる。


しかし,OSの内部では,ProgID は別の形式で処理されている。

これが「CLSID」(CLASS ID)だ。


ProgIDも,CLSIDも,役目は同じ。

COMコンポーネントを一意に識別すること。


人間に読みやすいのが ProgID, OS内部で扱いやすいのが CLSID ということになる。

もちろん,人間が CLSIDを使っても構わないんだけど。

CLSID
http://exlight.net/devel/windows/term...

  • CLSID:
    • COM コンポーネントを識別するための ID.
    • Class ID を略して CLSID と表記するようになった.


CLSID | Definition | Trend Micro Threat Encyclopedia
http://about-threats.trendmicro.com/d...

  • Windowsのアプリケーションコンポーネントを識別するために、各コンポーネントごとに付加された識別子を指す。


CLSIDのことを,GUIDとも呼ぶ。


厳密に言えば,GUIDの中には「IID」と「CLSID」の2種類があるのだが。

CLSIDはGUIDである,と簡略化して考えても構わない。

COM の基礎
http://chokuto.ifdef.jp/urawaza/com/c...

  • COMでは、さまざまなものの識別のためにGUID(Globally Unique Identifiers)と呼ばれる識別子を使用します。
    • GUIDは、16バイト(128ビット)の値によって識別するものです。
  • GUIDはオブジェクトやインターフェースの識別にも使われ、
    • 特にCOMオブジェクトを識別するGUIDをクラスID(CLSID)、
    • インターフェースを識別するGUIDをインターフェースID(IID)といいます。


COM を学ぶ(4) : ProgID から CLSID を求める。 - sirocco の書いてもすぐに忘れるメモ
http://d.hatena.ne.jp/sirocco/2010052...

  • CLSID は GUID の別名として定義されています。


CLSIDとは
1.windows の クラスid (CLSID) とはどういうものなのでしょうか?regedit で...
http://detail.chiebukuro.yahoo.co.jp/...

  • 世界中の開発者がCOMコンポーネントを作ってもそのIDが絶対にかぶらないようにこのような長い暗号のようなID(Guidといいます)になっています。
    • 直接人間のわかる文字列に変換することはできません
  • が, ものによってはProgIDという人が読めるIDがついている場合もあります。


CLSIDはレジストリ内にも格納されているが,DLL内にも含まれている。

COMの実態は特定のDLLであり,

その中に自分自身を識別するための情報も含まれているということ。

COM DLL の CLSID(クラスID)を調べる方法 - メモ帳
http://d.hatena.ne.jp/parasporospa/20...

  • クラスIDは DLL ファイル内に埋め込まれている。


CLSID(GUID)は,Windows内でオブジェクトを識別するために頻繁に用いられる。

たとえば,「ゴミ箱」などの特殊フォルダを一つ一つ識別・区別するためにもGUIDを使う。

特殊フォルダ・プログラムのCLSID・アイコン一覧
http://pasofaq.jp/windows/mycomputer/...

  • ごみ箱 CLSID {645FF040-5081-101B-9F08-00AA002F954E}


COMの場合,ProgIDは「CLSID」に関連付けられている。

<ProgID> Key (COM)
http://msdn.microsoft.com/ja-jp/libra...

  • A programmatic identifier (ProgID) is a registry entry that can be associated with a CLSID.
  • Like the CLSID, the ProgID identifies a class but with less precision because it is not guaranteed to be globally unique.

(5)ProgIDからCLSIDに変換し,それをさらにDLLのファイルパスに変換する

まず,ProgID → CLSID という変換について。

人間が書くプログラムではProgIDを使うが,

OSの内部では CLSID に変換して処理されている。



ProgIDからCLSIDに変換できるよう,

この対応付けがレジストリ内に格納されている。



次に,CLSID → DLLのファイルパス という変換について。

CLSIDを指定すると,それに対応するDLLのファイルパスもわかる。

この情報も,レジストリ内に一緒に格納されている。


なので,下記のように情報をたどってゆくことができる。

  • ProgID → CLSID → DLLファイルパス


プログラム中で「ProgID」をまず指定してやれば,

それを手がかりにしてレジストリの情報を辿ってゆき,

呼び出すべきDLLのファイルパス(COMの実体のありか)を知ることができる。

というわけだ。

レジストリへの登録
http://eternalwindows.jp/com/comserve...

  • CoCreateInstanceが内部で呼び出すCoGetClassObjectは、 指定されたCLSIDからオブジェクトを実装するDLLを特定するわけですが、 この際にはレジストリのHKEY_CLASSES_ROOT\CLSID以下が参照される。
    • キーの下にはInprocServer32というサブキーが作成されていますが、 このサブキーにサーバーのDLLのパスが格納される
    • 他にProgIDというサブキーも作成していますが、これは必須ではありません。
  • ProgIDはいわばオブジェクトの名前であり、一見してそれがどのようなオブジェクトを識別しているのかを見分けることができます。
    • オブジェクトがProgIDを持つ場合は、ProgIDからCLSIDへの変換もサポートしておくべきです。
    • このためには、HKEY_CLASSES_ROOT以下にProgIDの名前をしたキーを作成します。


What is a ProgID and How Do I Change It?
http://www.vbaccelerator.com/progid.htm

  • To allow access to a COM object regardless of where it is located, COM implements a mechanism to identify where the executable implementing a given COM object is.
  • This mechanism means COM is not restricted to any given path for storing an object, and with the DCOM extensions the COM object can actually be held on another computer on the network.


WSHや他の言語では,ProgIDを経由してCOMオブジェクトを作るのが普通。

しかし,ProgIDではなくCLSIDからCOMオブジェクトを生成することも,やればできる。


どうして可能かというと,人間がProgIDを指定しても,

結局はOSの内部ではCLSIDに変換されて処理されているので,

つまるところ同じ物を指しているからだ。

C#でCLSIDからオブジェクトを作る方法 - イグトランスの頭の中
http://dev.activebasic.com/egtra/2013...

  • .NET言語でクラスID (CLSID) からオブジェクトを作成する方法として、Marshal.BindToMonikerを使うこともできる