2017/11/27
修改Assembly类加载不必要类型的Bug
using System;
using System.Collections.Generic;
using System.IO;
using ComTypes = System.Runtime.InteropServices.ComTypes;
namespace NFox.Runtime.Com.Reflection
{
///
/// Com程序集,只有类型集合,类型别名、枚举等未处理
///
public class Assembly
{
///
/// 程序集字典
///
private static Dictionary _openedAssemblies
= new Dictionary();
public static DirectoryInfo Root
{
get
{
var assem = System.Reflection.Assembly.GetExecutingAssembly();
var fi = new FileInfo(assem.Location);
return fi.Directory.CreateSubdirectory("ComAssemblies");
}
}
///
/// 获取IDispatch接口对象的类型信息
///
/// IDispatch接口对象
/// 对象的类型信息
public static Type GetType(IDispatch obj)
{
AssemblyKey key;
ComTypes.ITypeInfo info;
obj.GetTypeInfo(0, 0, out info);
ComTypes.ITypeLib lib;
int id;
info.GetContainingTypeLib(out lib, out id);
IntPtr ip;
lib.GetLibAttr(out ip);
var la = Utils.GetObject(ip);
key = new AssemblyKey(la.guid, la.wMajorVerNum, la.wMinorVerNum);
lib.ReleaseTLibAttr(ip);
if (!_openedAssemblies.ContainsKey(key))
{
string name, doc, helpfile;
int hc;
lib.GetDocumentation(-1, out name, out doc, out hc, out helpfile);
var dir = Root.CreateSubdirectory(name);
var clsdir = dir.CreateSubdirectory(key.ClsId.ToString());
var verdir = clsdir.CreateSubdirectory(key.Version);
_openedAssemblies.Add(key, new Assembly(key, name, verdir));
}
return _openedAssemblies[key].GetType(id, info);
}
private Assembly(AssemblyKey key, string name, DirectoryInfo path)
{
Key = key;
Name = name;
_root = path;
}
public string Name { get; }
public AssemblyKey Key { get; }
private DirectoryInfo _root;
///
/// 类型字典
///
public Dictionary[i] Types { get; }
= new Dictionary[i]();
///
/// 按索引获取Com程序集中的类型信息
///
/// 索引
/// ITypeInfo接口
/// 对应索引的类型信息
public Type GetType(int id, ComTypes.ITypeInfo info)
{
if (!Types.ContainsKey(id))
{
var name = $"{_root.FullName}/{id}.typ";
if (File.Exists(name))
{
Types.Add(id, new Type(this, name));
}
else
{
Type type = new Type(this, info);
type.Save(name);
Types.Add(id, type);
}
}
return Types[id];
}
public override string ToString()
{
return Name;
}
}
}