やれること
インスタンス化したComObject(※)が特定のインタフェース(IDispatch)を実装している場合に
- インタフェース名 と そのGUID
- TypeLibrary名
を取得します。
※簡単な判別方法: .GetType().ToString()
が "System.__ComObject"
になるやつ
ソースコード
ソースコード
using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
// ↓これを消すと、System.Runtime.InteropServicesにある同名の古い定義をうっかり引き当ててしまうおそれがあるので残す
using System.Runtime.InteropServices.ComTypes;
using ComTypes = System.Runtime.InteropServices.ComTypes;
public static class ShowComInfo
{
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-c000-000000000046")]
private interface IDispatch
{
[PreserveSig]
int GetTypeInfoCount(out int count);
[PreserveSig]
int GetTypeInfo([In] int itinfo, [In] int lcid, out IntPtr typeinfo);
[PreserveSig]
int GetIDsOfNames();//dummy. don't call this method
[PreserveSig]
int Invoke();//dummy. don't call this method
}
static Guid? GetGuidFromIType(ITypeInfo typ)
{
Guid? guid = null;
IntPtr ptr;
try {
typ.GetTypeAttr(out ptr);
}
catch ( COMException ) { return null; }
try {
var attr = Marshal.PtrToStructure<ComTypes.TYPEATTR>(ptr);
guid = attr.guid;
}
finally {
typ.ReleaseTypeAttr(ptr);
}
return guid;
}
static void ShowNamesOfTypeInfo(ITypeInfo typ)
{
string strName;
string strDocString;
int dwHelpContext;
string strHelpFile;
typ.GetDocumentation(-1, out strName, out strDocString, out dwHelpContext, out strHelpFile);
Console.Write("InterfaceName: ");
Console.WriteLine(strName??"<<NULL>>");
Console.Write("InterfaceDocString: ");
Console.WriteLine(strDocString??"<<NULL>>");
Console.Write("InterfaceHelpFile: ");
Console.WriteLine(strHelpFile??"<<NULL>>");
}
static void ShowNamesOfTypeLib(ITypeLib typ)
{
string strName;
string strDocString;
int dwHelpContext;
string strHelpFile;
typ.GetDocumentation(-1, out strName, out strDocString, out dwHelpContext, out strHelpFile);
Console.Write("TypeLibName: ");
Console.WriteLine(strName??"<<NULL>>");
Console.Write("TypeLibDocString: ");
Console.WriteLine(strDocString??"<<NULL>>");
Console.Write("TypeLibHelpFile: ");
Console.WriteLine(strHelpFile??"<<NULL>>");
}
public static void ShowInterfaceIdFromComObject(object obj)
{
Guid? guid = null;
ComTypes.ITypeInfo typeInfo = null;
IntPtr ptr = IntPtr.Zero;
try {
if ( obj is IDispatch ) {
var idisp = (IDispatch)obj;
int count;
int hResult = idisp.GetTypeInfoCount(out count);
if ( hResult >= 0 ) { // Succeeded
if ( count < 1 ) { // no type info
return;
}
idisp.GetTypeInfo(0, 0, out ptr);
if ( ptr == IntPtr.Zero ) {
return;
}
typeInfo = (ComTypes.ITypeInfo)
(Marshal.GetTypedObjectForIUnknown(ptr, typeof(ComTypes.ITypeInfo)));
if ( typeInfo == null ) {
return;
}
ShowNamesOfTypeInfo(typeInfo);
guid = GetGuidFromIType(typeInfo);
Console.Write("InterfaceGUID: ");
Console.WriteLine(guid);
ITypeLib typLib;
int indexOfLib;
typeInfo.GetContainingTypeLib(out typLib, out indexOfLib);
ShowNamesOfTypeLib(typLib);
}
}
else { // unknown type
return;
}
}
finally {
if ( ptr != IntPtr.Zero ) {
Marshal.Release(ptr);
ptr = IntPtr.Zero;
}
}
}
}
class Test
{
[STAThread]
static void Main(string[] args)
{
Type comType = Type.GetTypeFromProgID("Shell.Application");
dynamic o = Activator.CreateInstance(comType);
try {
ShowComInfo.ShowInterfaceIdFromComObject(o);
}
finally {
Marshal.ReleaseComObject(o);
}
}
}
実行結果
InterfaceName: IShellDispatch6
InterfaceDocString: Updated IShellDispatch
InterfaceHelpFile: <<NULL>>
InterfaceGUID: 34936ba1-67ad-4c41-99b8-8c12dff1e974
TypeLibName: Shell32
TypeLibDocString: Microsoft Shell Controls And Automation
TypeLibHelpFile: <<NULL>>
ちなみにCOMオブジェクトのインタフェースは、レジストリの HKEY_CLASSES_ROOT\Interface
にいます。
OleView.exeでTypeLibraryを探すと情報がみれる。
参考サイト
- http://eternalwindows.jp/com/auto/auto02.html
- http://goungoun.dip.jp/app/fswiki/wiki.cgi/devnotebook?page=Visual+Studio+%2ENET+2003+C%23%A1%A2COM%A5%AA%A5%D6%A5%B8%A5%A7%A5%AF%A5%C8%A4%CE%BC%EF%CE%E0%A4%F2%C6%C0%A4%EB%A1%A3
- https://msdn.microsoft.com/ja-jp/magazine/dd347981.aspx
OleView.exeの使い方
OleView.exeでインタフェースのメソッド、プロパティを調べる方法。
※そのPCにインストールされているものしか出ません。例:ExcelがインストールされていないPCでExcelのCOM Objectは多分でてこない。
■Step0. 入手する ・・・ oleview.exe microsoft あたりのキーワードでググるべし。
■Step1. 起動する ・・・ C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin らへんにいるはず。。環境依存。
■Step2. タイプライブラリ名を探す
「Type Libraries」から、TypeLib名を探す(例:Microsoft Shell Controls And Automation)
■Step3. タイプライブラリ名をダブルクリックする
・・・別ウィンドウが立ち上がります。
■Step4. インタフェース名を探す。
・・・dispinterface インタフェース名