最近用Windows Live Writer 写学习笔记,在用代码插件时,用SyntaxHighlight代码插件,在代码前面总是多一些空格出来,今天搜了一下觉得VSPaste这个插件不错。复制了VS里的代码,点一下这个插件就能够把VS里复制的类容直接以VS里的格式复制过来,效果不错。但是复制其他地方的文本却不能贴过来。就在想它能不能复制其他地方的东西呢。于是用ildasm来看了一下。
Writer插件是调用了一个叫CreateContent的函数来实现的。打开后找到这个函数。
打开这个函数的IL代码
.try { IL_0001: nop IL_0002: ldsfld string [System.Windows.Forms]System.Windows.Forms.DataFormats::Rtf IL_0007: call bool [System.Windows.Forms]System.Windows.Forms.Clipboard::ContainsData(string) IL_000c: ldc.i4.0 IL_000d: ceq IL_000f: stloc.1 IL_0010: ldloc.1 IL_0011: brtrue.s IL_0042 IL_0013: nop IL_0014: ldarg.2 IL_0015: ldstr "<pre class=\"code\">" IL_001a: ldsfld string [System.Windows.Forms]System.Windows.Forms.DataFormats::Rtf IL_001f: call object [System.Windows.Forms]System.Windows.Forms.Clipboard::GetData(string) IL_0024: castclass [mscorlib]System.String IL_0029: call string HTMLRootProcessor::FromRTF(string) IL_002e: call string VSPaste.VSPaste::Undent(string) IL_0033: ldstr "</pre><a href=\"http://11011.net/software/vspaste\">" + "</a>" IL_0038: call string [mscorlib]System.String::Concat(string, string, string) IL_003d: stind.ref IL_003e: ldc.i4.1 IL_003f: stloc.0 IL_0040: leave.s IL_0062 IL_0042: nop IL_0043: leave.s IL_005d } // end .try
很容易就发现这里的代码是很熟悉的。
IL_0011: brtrue.s IL_0042 IL_0013: nop IL_0014: ldarg.2 IL_0015: ldstr "<pre class=\"code\">"
看到IL_0015 然后往上找到IL_0011 是直接判断跳转到了IL_0042刚好跳过了文本转换的代码。于是把IL_0011: brtrue.s IL_0042 修改成IL_0011: brtrue.s IL_0013保证只要是剪贴板里的文本都做文本转换为HTML。测试了一下,弹出了VS Paste could not convert that content.的错误提示。于是继续看看代码到底做了些什么。
这个生成的字符串代码。大概意思如下:
try { string str = System.Windows.Forms.DataFormats.Rtf;//vs 是以rtf为格式 IL_0002: ldsfld if (System.Windows.Forms.Clipboard.ContainsData(str))//判断剪贴板格式能否转化为Rtf IL_0007: call { string code = "<pre class=\"code\">"; object obj = System.Windows.Forms.Clipboard.GetData(str);//得到格式数据 code += VSPaste.Undent(HTMLRootProcessor.FromRTF(obj.ToString()));//这里调用函数把RTF格式转换为HTML IL_001a: ldsfld IL_001f: call code += "</pre><a href=\"http://11011.net/software/vspaste\">" + "</a>"; } } catch { MessageBox.Show("VS Paste could not convert that content."); }
说了上面一大堆,最后就是把剪贴板里如果是Rtf格式的数据就按格式转换成HTML代码然后返回来。只有微软用RTF,也就打消了这个想法。
我在博客里配置的代码部分的class=‘xcode’ ,而这里的是code,想改成xcode。下面那句<a href=\"http://11011.net/software/vspaste\></a>每段代码下面都生车这句,看着不是很舒服。
于是把IL代码改成了
IL_0015: ldstr "<pre class=\"xcode\">" IL_001a: ldsfld string [System.Windows.Forms]System.Windows.Forms.DataFormats::Rtf IL_001f: call object [System.Windows.Forms]System.Windows.Forms.Clipboard::GetData(string) IL_0024: castclass [mscorlib]System.String IL_0029: call string HTMLRootProcessor::FromRTF(string) IL_002e: call string VSPaste.VSPaste::Undent(string) IL_0033: ldstr "</pre>"
然后 ilasm VSPaste /dll 编译然后替换旧的文件。这下就比较舒服了。
最后的话
最近看框架设计,上面提到的工具ILDasm和ILasm也一直没有试过什么回事。看到IL代码有点头晕,毕竟还是读书的时候写过几段汇编,也没有深入,于是开着MSDN弄了两小时才把这个意思大概弄明白。被堆栈弄晕了。回头还得仔细看框架设计。本文是闲的无聊蛋疼贴。欢迎拍砖。