惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
G
Google Developers Blog
B
Blog
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
The Cloudflare Blog
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
雷峰网
雷峰网
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
A
About on SuperTechFans
量子位
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
H
Help Net Security
Help Net Security
Help Net Security
P
Palo Alto Networks Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
W
WeLiveSecurity
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
Know Your Adversary
Know Your Adversary
Apple Machine Learning Research
Apple Machine Learning Research
Scott Helme
Scott Helme
N
News | PayPal Newsroom
AWS News Blog
AWS News Blog
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
腾讯CDC
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
TaoSecurity Blog
TaoSecurity Blog
GbyAI
GbyAI
Y
Y Combinator Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Docker

博客园 - 寒星

2010年度总结 Win7、Windows Server 2008下无法在Windows Service中打开一个已经存在的Excel 2007文件问题的解决方案 企业IT部门的职责和定位(转摘) 09年度总结 重读《软件架构师职业导读》有感 向给我留言的朋友道歉 B/S应用中的ActiveX数字签名相关问题杂谈 兑现承诺,给出我出的面试题。 年后第一天上班 提前给大家拜个早年。 闻听家乡出现流脑病例,祝福ing... 年终了,准备换换环境。 开心ing,终于买到回家的车票了。 老婆的第一次产前检查 Small Tip One: 根据指定的IIS虚拟路径获取相应的物理路径 《十种不宜追随的老板》一文读后感 十种不宜追随的老板[转] 回顾 2004 凑热闹,Share自己写的另一个小工具--代码统计器。
走近COM Interop--编程以实现COM-->Assembly
寒星 · 2005-01-28 · via 博客园 - 寒星

  这篇文章是《走近COM Interop》系列的最后一篇,也是涉及技术点最多的一篇。希望我的描述大家能看到懂,难免有错,请各位不吝赐教。
  书归正传,我开始介绍如果通过编程的方式导入一个COM组件,并生成相应的.Net Assembly。其实,过程非常简单,个人认为只是自己实现了TLBIMP.EXE做的事情而已。(当然,也可以实现TLBEXP.EXE的功能,只是它属于CCW的范畴,这儿就不多说了。)

一、准备工作
  具体说来,编程实现COM-->Assembly的功能,需要使用的以前几个类:
  System.Runtime.InteropServices
   -TypeLibConverter      
提供一组服务,将托管程序集转换为 COM 类型库或进行反向转换。
   -ITypeLibImporterNotifySink  提供回调机制,以供类型库转换器向调用方通知转换的状态,并在转换过程本身之中涉及调用方。
  System.Reflection
   -StrongNameKeyPair(可选)  
封装对公钥或私钥对的访问,该公钥或私钥对用于为强名称程序集创建签名。
  System.Reflection.Emit
   -AssemblyBuilder                           
定义并表示动态程序集。   此外,还需要使用一个WinAPI,LoadTypeLibEx,具体定义如下:
    [DllImport( "oleaut32.dll", CharSet = CharSet.Unicode, PreserveSig = false )]
          private static extern void LoadTypeLibEx(String strTypeLibName, RegKind regKind, [MarshalAs(UnmanagedType.Interface)] out     Object typeLib );
  
为了让这个WinAPI function可以正常使用,我们还需要定义一个枚举,

  注:上述类的说明来自MSDN。   大家都看到了,上述几个类中,仅有StrongNameKeyPair是可选的,这是因为如果我们不需要生成PIA,那么是不需要使用这个类的。同时,如果需要生成PIA,那么需要提供相应的密钥文件。在后面的描述中,我们将使用《走近COM Interop--浅谈PIA》中的例子做进一步的演示。

二、实战

演练
  在此,我们仍就由VB生成的PIADemo.dll展开演示。
1. 载入一个COM组件

2. 定义一个实现ITypeLibImporterNotifySink接口的类,基于提供回调机制,以供类型库转换器向调用方通知转换的状态,并在转换过程本身之中涉及调用方。

3. 将COM类型库生成程序集
 A. 生成PIA Assembly

FileStream stream = new FileStream("common.snk", FileMode.Open);
try
{
    StrongNameKeyPair pair 
= new StrongNameKeyPair(stream);
    TypeLibConverter converter 
= new TypeLibConverter();
    ConversionEventHandler eventHandler 
= new ConversionEventHandler();
    AssemblyBuilder ab 
= converter.ConvertTypeLibToAssembly(typeLib, "interop.PIADemo.dll", TypeLibImporterFlags.PrimaryInteropAssembly, eventHandler, null, pair, nullnull);    
    ab.Save(
"interop.PIADemo.dll");

    MessageBox.Show(
"Importing is ok.");

    Assembly asm 
= Assembly.LoadFile(Application.StartupPath + @"\interop.PIADemo.dll");
    Type t 
= asm.GetType("interop.PIADemo.TestClass");
    
object obj = t.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, nullnullnull);
    
string ret = (string)t.InvokeMember("Format", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | 
BindingFlags.Instance 
| BindingFlags.InvokeMethod, null, obj, new object[]{"Go!"});
    MessageBox.Show(ret);
}

catch(Exception ep)
{
    
if(stream != null)
    
{
        stream.Close();
    }


    MessageBox.Show(ep.Message);
}


 B. 生成一般的Assembly

TypeLibConverter converter = new TypeLibConverter();
ConversionEventHandler eventHandler 
= new ConversionEventHandler();
AssemblyBuilder ab 
= converter.ConvertTypeLibToAssembly(typeLib, "interop.PIADemo.dll"0
eventHandler, 
nullnullnullnull);    
ab.Save(
"interop.PIADemo.dll");

MessageBox.Show(
"Importing is ok.");

Assembly asm 
= Assembly.LoadFile(Application.StartupPath + @"\interop.PIADemo.dll");
Type t 
= asm.GetType("interop.PIADemo.TestClass");
object obj = t.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, nullnullnull);
string ret = (string)t.InvokeMember("Format", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | 
   BindingFlags.Instance 
| BindingFlags.InvokeMethod, null, obj, new object[]{"Go!"});
MessageBox.Show(ret);


 需要说明几点:
 1. 上述示例中使用的PIADemo.dll和Common.snk都需要被copy至测试程序的bin目录中,否则,就需要指定可达到的文件路径。
 2. Assembly.LoadFile的参数是要加载的文件的绝对路径,相对路径将会引发异常。

  至此,本系列文章全部完成。因本人水平有限,有不对的地方,欢迎指正。