📄 typelib.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR;
using TYPEKIND = System.Runtime.InteropServices.ComTypes.TYPEKIND;
using System.Windows.Forms;
using System.IO;
namespace IDLTest
{
/// <summary>
/// 类型库
/// </summary>
class TypeLib
{
#region 属性
/// <summary>
/// 对应的类型信息
/// </summary>
public List<TypeInfo> TypeInfos = new List<TypeInfo>();
public Int32 LCID
{
get { return Marshal.GetTypeLibLcid(Lib); }
}
public String Name
{
get { return Marshal.GetTypeLibName(Lib); }
}
public Guid Guid
{
get { return Marshal.GetTypeLibGuid(Lib); }
}
public String UUID
{
get { return Guid.ToString(); }
}
//private String _HelpString = "";
//public String HelpString
//{
// get
// {
// if (!String.IsNullOrEmpty(_HelpString)) return _HelpString;
// String dll = "";
// int context = 0;
// Lib.GetDocumentation2(-1, out _HelpString, out context, out dll);
// return null;
// }
//}
#endregion
#region 原有属性
private ITypeLib2 Lib;
private TYPELIBATTR Attr;
#endregion
#region 构造函数
public TypeLib(String filename)
{
try
{
Lib = LoadTypeLib(filename);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
if (Lib == null) return;
IntPtr ip;
Lib.GetLibAttr(out ip);
Attr = (TYPELIBATTR)Marshal.PtrToStructure(ip, typeof(TYPELIBATTR));
int c = Lib.GetTypeInfoCount();
for (int i = 0; i < c; i++)
{
ITypeInfo ppTI;
Lib.GetTypeInfo(i, out ppTI);
TypeInfo pi = new TypeInfo(ppTI);
pi.Lib = this;
TypeInfos.Add(pi);
//如果上一个是这个类的接口,那么设置它的类GUID
//if (i > 0 && pi.TypeKind == TYPEKIND.TKIND_COCLASS
// && TypeInfos[i - 1].TypeKind == TYPEKIND.TKIND_DISPATCH
// && (TypeInfos[i - 1].Name == "_" + pi.Name
// || TypeInfos[i - 1].Name == "I" + pi.Name))
//{
// TypeInfos[i - 1].ClassGuid = pi.Attr.guid;
//}
}
foreach (TypeInfo ti in TypeInfos)
{
if (ti.TypeKind == TYPEKIND.TKIND_DISPATCH)
{
foreach (TypeInfo t in TypeInfos)
{
if (!ti.Equals(t) && t.TypeKind == TYPEKIND.TKIND_COCLASS && (ti.Name == "_" + t.Name || ti.Name == "I" + t.Name))
{
ti.ClassGuid = t.Attr.guid;
break;
}
}
}
}
}
public void SearchVirturlAddress()
{
//if (!IsVB && VirturlAddress.ToInt32() == DefaultAddress.ToInt32())
{
IntPtr ip = TypeInfos[0].BaseAddress;
foreach (TypeInfo ti in TypeInfos)
{
IntPtr p = ti.BaseAddress;
if (p != IntPtr.Zero)
{
if ((p.ToInt32() < ip.ToInt32() || ip == IntPtr.Zero))
ip = p;
p = Marshal.ReadIntPtr(p);
if ((p.ToInt32() < ip.ToInt32() || ip == IntPtr.Zero))
ip = p;
}
}
String s = ip.ToString("X");
s = s.Substring(0, s.Length - 4);
s += "0000";
ip = (IntPtr)Convert.ToInt32(s, 16);
VirturlAddress = ip;
}
}
//~TypeLib()
//{
// IntPtr ip;// = IntPtr.Zero;
// Marshal.StructureToPtr(Attr, ip, true);
// Lib.ReleaseTLibAttr(ip);
//}
#endregion
[DllImport("oleaut32.dll", PreserveSig = false, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
private static extern ITypeLib2 LoadTypeLib(string szFile);
#region 生成
private static IntPtr DefaultAddress = new IntPtr(Convert.ToInt32("0x00400000", 16));
/// <summary>
/// 是否VB程序
/// </summary>
public Boolean IsVB = true;
/// <summary>
/// 映像基址
/// </summary>
public IntPtr ImageBase = DefaultAddress;
/// <summary>
/// 基址
/// </summary>
public IntPtr VirturlAddress = DefaultAddress;
/// <summary>
/// 是否生成结构体
/// </summary>
public Boolean IsStruct = false;
public String RendIDCs()
{
StringBuilder sb = new StringBuilder();
sb.Append(Begin);
foreach (TypeInfo ti in TypeInfos)
{
if (ti.TypeKind != TYPEKIND.TKIND_COCLASS)
{
//if (IsStruct)
// sb.Append(MakeStruct(ti));
//else
// sb.Append(MakeName(ti));
sb.Append(RendIDC(ti, false));
}
}
sb.Append(End);
return sb.ToString();
}
public String RendIDC(TypeInfo ti, Boolean includehead)
{
if (ti.TypeKind != TYPEKIND.TKIND_DISPATCH) return null;
StringBuilder sb = new StringBuilder();
if (includehead) sb.AppendLine(Begin);
if (!IsVB && !IsStruct && ti.StaticAddress != IntPtr.Zero)
{
sb.AppendFormat("\tMakeDword(\"0x{0}\");", ti.StaticAddress.ToString("X"));
sb.AppendLine();
sb.AppendFormat("\tMakeNameEx(\"0x{0}\", \"vft{1}\", SN_NON_PUBLIC | SN_NOWARN);", ti.StaticAddress.ToString("X"), ti.Name);
sb.AppendLine();
}
if (IsStruct)
sb.Append(MakeStruct(ti));
else
sb.Append(MakeName(ti));
if (includehead) sb.AppendLine(End);
return sb.ToString();
}
private String Begin
{
get
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("// {0} 类型库命名脚本", Name);
sb.AppendLine();
sb.AppendFormat("// Design By 大石头 {0}", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
sb.AppendLine();
sb.AppendLine("#include <idc.idc>");
sb.AppendLine();
//String dir = Application.ExecutablePath;
//dir = dir.Substring(0, dir.LastIndexOf(@"\") + 1);
//if (File.Exists(dir + "header.idc"))
//{
// using (StreamReader sr = new StreamReader(dir + "header.idc", Encoding.UTF8, true))
// {
// sb.AppendLine(sr.ReadToEnd());
// sr.Close();
// }
//}
sb.AppendLine("#include \"header.c\"");
sb.AppendLine();
sb.AppendLine("static main()");
sb.AppendLine("{");
sb.AppendLine("\tauto sHandle;");
return sb.ToString();
}
}
private String End
{
get
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("\tMessage(\"{0} 类型库命名完成!\\n\");", Name);
sb.AppendLine();
sb.AppendLine("}");
return sb.ToString();
}
}
private String MakeName(TypeInfo ti)
{
StringBuilder sb = new StringBuilder();
foreach (Func f in ti.Funcs)
{
IntPtr ip = f.FuncAddress;
if (!IsVB && ti.StaticAddress != IntPtr.Zero)
ip = (IntPtr)(ti.StaticAddress.ToInt32() + f.OffVft);
//ip = Marshal.ReadIntPtr((IntPtr)(ti.StaticAddress.ToInt32() + ti.OffVft));
if ((!IsVB || f.OffVft >= 7 * 4) && ip != IntPtr.Zero)
{
sb.AppendFormat("\tMakeAddrName(0x{0}, \"{1}\", \"{2}\", {3});", ip.ToString("X"), ti.ClassName, f.FuncName, IsVB ? 1 : 0);
sb.AppendLine();
}
}
return sb.ToString();
}
private String MakeStruct(TypeInfo ti)
{
if (ti.Funcs.Count <= 7 || ti.BaseAddress == IntPtr.Zero) return null;
StringBuilder sb = new StringBuilder();
sb.AppendFormat("\tsHandle = GetStrucIdByName(\"I{0}\");", ti.ClassName);
sb.AppendLine();
sb.AppendLine("\tif(sHandle==-1)");
sb.AppendLine("\t{");
sb.AppendFormat("\t\tMake_stuctures(\"I{0}\");", ti.ClassName);
sb.AppendLine();
sb.AppendFormat("\t\tsHandle = GetStrucIdByName(\"I{0}\");", ti.ClassName);
sb.AppendLine();
foreach (Func f in ti.Funcs)
{
if ((!IsVB || f.OffVft >= 7 * 4) && f.FuncAddress != IntPtr.Zero)
{
sb.AppendFormat("\t\tAddStrucMember(sHandle, \"{0}\", 0x{1}, FF_DWRD, 0, 4);", f.FuncName, f.OffVft.ToString("X"));
sb.AppendLine();
}
}
sb.AppendLine("\t}");
return sb.ToString();
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -