银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
  268 随笔 :: 2 文章 :: 2606 评论 :: 48 引用

以前在 Windows Live Writer 中一直使用 Paste from Visual Studio 插件来在博文中粘贴代码。这个插件对 Visual Studio 2008 很好用,但是从 Visual Stduio 2010 中粘贴代码的话,每个中文字符后面,会跟着一个乱码,如下 ClipboardTester.cs 所示:

01:  using System;
02:  using System.Windows;
03:  
04:  namespace Skyiv.Tester
05:  {
06:    static class ClipboardTester
07:    {
08:      [STAThread]
09:      static void Main()
10:      {
11:        var obj = Clipboard.GetDataObject();
12:        foreach (var v in obj.GetFormats())
13:        {
14:          Console.WriteLine("[{0}]", v);
15:          Console.WriteLine("-------- 开a始? --------");
16:          try { Console.WriteLine("{0}", obj.GetData(v)); }
17:          catch (Exception ex) { Console.WriteLine(ex); }
18:          Console.WriteLine("-------- 结á束? --------");
19:          Console.WriteLine();
20:        }
21:      }
22:    }
23:  }

 

我以前是手工一个个删除这些乱码。

查找根源

现在让我们来查找为什么会有乱码的原因吧。首先用以下命令编译上面给出的 ClipboardTester.cs 程序:

E:\CS\VSPaste> csc ClipboardTester.cs -r:C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationCore.dll
Microsoft(R) Visual C# 2010 编译器 4.0.30319.1 版
版权所有(C) Microsoft Corporation。保留所有权利。

 

然后在 Visual Studio 2010 中使用“Ctrl-A”、“Ctrl-C”将这段源程序代码送到系统剪贴板,再运行 ClipboardTester.exe 从系统剪贴板中取出数据:

E:\CS\VSPaste> ClipboardTester
[Text]
-------- 开始 --------
using System;
using System.Windows;

namespace Skyiv.Tester
{
  static class ClipboardTester
  {
    [STAThread]
    static void Main()
    {
      var obj = Clipboard.GetDataObject();
      foreach (var v in obj.GetFormats())
      {
        Console.WriteLine("[{0}]", v);
        Console.WriteLine("-------- 开始 --------");
        try { Console.WriteLine("{0}", obj.GetData(v)); }
        catch (Exception ex) { Console.WriteLine(ex); }
        Console.WriteLine("-------- 结束 --------");
        Console.WriteLine();
      }
    }
  }
}
-------- 结束 --------

[UnicodeText]
-------- 开始 --------
using System;
using System.Windows;

namespace Skyiv.Tester
{
  static class ClipboardTester
  {
    [STAThread]
    static void Main()
    {
      var obj = Clipboard.GetDataObject();
      foreach (var v in obj.GetFormats())
      {
        Console.WriteLine("[{0}]", v);
        Console.WriteLine("-------- 开始 --------");
        try { Console.WriteLine("{0}", obj.GetData(v)); }
        catch (Exception ex) { Console.WriteLine(ex); }
        Console.WriteLine("-------- 结束 --------");
        Console.WriteLine();
      }
    }
  }
}
-------- 结束 --------

[System.String]
-------- 开始 --------
using System;
using System.Windows;

namespace Skyiv.Tester
{
  static class ClipboardTester
  {
    [STAThread]
    static void Main()
    {
      var obj = Clipboard.GetDataObject();
      foreach (var v in obj.GetFormats())
      {
        Console.WriteLine("[{0}]", v);
        Console.WriteLine("-------- 开始 --------");
        try { Console.WriteLine("{0}", obj.GetData(v)); }
        catch (Exception ex) { Console.WriteLine(ex); }
        Console.WriteLine("-------- 结束 --------");
        Console.WriteLine();
      }
    }
  }
}
-------- 结束 --------

[Rich Text Format]
-------- 开始 --------
{\rtf\ansi{\fonttbl{\f0 NSimSun;}}{\colortbl;\red0\green0\blue255;\red43\green14
5\blue175;\red163\green21\blue21;}\f0 \fs19 \cf1 using\cf0  System;\par \cf1 usi
ng\cf0  System.Windows;\par \par \cf1 namespace\cf0  Skyiv.Tester\par \{\par   \
cf1 static\cf0  \cf1 class\cf0  \cf2 ClipboardTester\cf0 \par   \{\par     [\cf2
 STAThread\cf0 ]\par     \cf1 static\cf0  \cf1 void\cf0  Main()\par     \{\par
     \cf1 var\cf0  obj = \cf2 Clipboard\cf0 .GetDataObject();\par       \cf1 for
each\cf0  (\cf1 var\cf0  v \cf1 in\cf0  obj.GetFormats())\par       \{\par
   \cf2 Console\cf0 .WriteLine(\cf3 "[\{0\}]"\cf0 , v);\par         \cf2 Console
\cf0 .WriteLine(\cf3 "-------- \uinput2\u24320 ?a\uinput2\u22987 ê? --------"\cf
0 );\par         \cf1 try\cf0  \{ \cf2 Console\cf0 .WriteLine(\cf3 "\{0\}"\cf0 ,
 obj.GetData(v)); \}\par         \cf1 catch\cf0  (\cf2 Exception\cf0  ex) \{ \cf
2 Console\cf0 .WriteLine(ex); \}\par         \cf2 Console\cf0 .WriteLine(\cf3 "-
------- \uinput2\u32467 \uinput2\u26463 ê? --------"\cf0 );\par         \cf2 C
onsole\cf0 .WriteLine();\par       \}\par     \}\par   \}\par \}\par }
-------- 结束 --------

E:\CS\VSPaste>

 

从上面可以看出,出现乱码的根源在于 Visual Studio 2010 往系统剪贴板送 RTF 格式的内容时出错了。

修改 Paste from Visual Studio 插件

我们无法改变 Visual Studio 2010 的做法,只好修改 Paste from Visual Studio 插件了。以下步骤参照老赵的“定制 Paste from Visual Studio 插件”一文。

首先,使用 Reflector 查看 VSPaste.dll:

 

参照上图中的代码,编写一个 VSPaste2.cs:

01:  using System;
02:  using System.Windows.Forms;
03:  using System.Text.RegularExpressions;
04:  
05:  public class HTMLRootProcessor
06:  {
07:    public static string FromRTF(string s) { return null; }
08:  }
09:  
10:  namespace VSPaste
11:  {
12:    public class ContentSource
13:    {
14:      public virtual DialogResult CreateContent(IWin32Window dialogOwner, ref string newContent)
15:      {
16:        return DialogResult.Cancel;
17:      }
18:    }
19:  
20:    public class VSPaste : ContentSource
21:    {
22:      public static string Undent(string s) { return null; }
23:  
24:      public static string AddLines(string html)
25:      {
26:        string[] lines = html.Trim().Split('\n');
27:        string pattern = "<span style=\"color:black; font-weight:bold;\">{0:" +
28:          new String('0', lines.Length.ToString().Length) + "}:  </span>";
29:        for (int i = 0; i < lines.Length; i++)
30:          lines[i] = String.Format(pattern, i + 1) + lines[i];
31:        return String.Join("\n", lines);
32:      }
33:  
34:      public static string DeleteChineseGarbage(string str)
35:      {
36:        return Regex.Replace(str, @"(?<ch>\\u-?\d+ )..", "${ch}?");
37:      }
38:  
39:      public override DialogResult CreateContent(IWin32Window dialogOwner, ref string newContent)
40:      {
41:        try
42:        {
43:          if (Clipboard.ContainsData(DataFormats.Rtf))
44:          {
45:            string data = DeleteChineseGarbage((string)Clipboard.GetData(DataFormats.Rtf));
46:            string str3 = AddLines(Undent(HTMLRootProcessor.FromRTF(data)));
47:            newContent = "<pre class=\"code\">" + str3 + "</pre>";
48:            return DialogResult.OK;
49:          }
50:        }
51:        catch
52:        {
53:          MessageBox.Show("VS Paste could not convert that content.", "VS Paste Problem", MessageBoxButtons.OK, MessageBoxIcon.Hand);
54:        }
55:        return DialogResult.Cancel;
56:      }
57:    }
58:  }

 

上述程序中,第 34 行到第 37 行的 DeleteChineseGarbage 方法用于删除中文乱码。第 45 行调用这个方法。用以下命令编译和反汇编:

E:\CS\VSPaste> csc /t:library VSPaste2.cs
Microsoft(R) Visual C# 2010 编译器 4.0.30319.1 版
版权所有(C) Microsoft Corporation。保留所有权利。

E:\CS\VSPaste> ildasm VSPaste2.dll /output:VSPaste2.il

得到的 VSPaste2.il 文件如下所示:

001:  //  Microsoft (R) .NET Framework IL Disassembler.  Version 4.0.30319.1
002:  
003:  
004:  
005:  
006:  // Metadata version: v2.0.50727
007:  .assembly extern mscorlib
008:  {
009:    .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
010:    .ver 2:0:0:0
011:  }
012:  .assembly extern System.Windows.Forms
013:  {
014:    .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
015:    .ver 2:0:0:0
016:  }
017:  .assembly extern System
018:  {
019:    .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
020:    .ver 2:0:0:0
021:  }
022:  .assembly VSPaste2
023:  {
024:    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
025:    .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
026:                                                                                                               63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
027:    .hash algorithm 0x00008004
028:    .ver 0:0:0:0
029:  }
030:  .module VSPaste2.dll
031:  // MVID: {A944F44D-8C74-42FF-956B-B14EADD37E70}
032:  .imagebase 0x00400000
033:  .file alignment 0x00000200
034:  .stackreserve 0x00100000
035:  .subsystem 0x0003       // WINDOWS_CUI
036:  .corflags 0x00000001    //  ILONLY
037:  // Image base: 0x00280000
038:  
039:  
040:  // =============== CLASS MEMBERS DECLARATION ===================
041:  
042:  .class public auto ansi beforefieldinit HTMLRootProcessor
043:         extends [mscorlib]System.Object
044:  {
045:    .method public hidebysig static string 
046:            FromRTF(string s) cil managed
047:    {
048:      // 代码大小       7 (0x7)
049:      .maxstack  1
050:      .locals init (string V_0)
051:      IL_0000:  nop
052:      IL_0001:  ldnull
053:      IL_0002:  stloc.0
054:      IL_0003:  br.s       IL_0005
055:  
056:      IL_0005:  ldloc.0
057:      IL_0006:  ret
058:    } // end of method HTMLRootProcessor::FromRTF
059:  
060:    .method public hidebysig specialname rtspecialname 
061:            instance void  .ctor() cil managed
062:    {
063:      // 代码大小       7 (0x7)
064:      .maxstack  8
065:      IL_0000:  ldarg.0
066:      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
067:      IL_0006:  ret
068:    } // end of method HTMLRootProcessor::.ctor
069:  
070:  } // end of class HTMLRootProcessor
071:  
072:  .class public auto ansi beforefieldinit VSPaste.ContentSource
073:         extends [mscorlib]System.Object
074:  {
075:    .method public hidebysig newslot virtual 
076:            instance valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult 
077:            CreateContent(class [System.Windows.Forms]System.Windows.Forms.IWin32Window dialogOwner,
078:                          string& newContent) cil managed
079:    {
080:      // 代码大小       7 (0x7)
081:      .maxstack  1
082:      .locals init (valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult V_0)
083:      IL_0000:  nop
084:      IL_0001:  ldc.i4.2
085:      IL_0002:  stloc.0
086:      IL_0003:  br.s       IL_0005
087:  
088:      IL_0005:  ldloc.0
089:      IL_0006:  ret
090:    } // end of method ContentSource::CreateContent
091:  
092:    .method public hidebysig specialname rtspecialname 
093:            instance void  .ctor() cil managed
094:    {
095:      // 代码大小       7 (0x7)
096:      .maxstack  8
097:      IL_0000:  ldarg.0
098:      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
099:      IL_0006:  ret
100:    } // end of method ContentSource::.ctor
101:  
102:  } // end of class VSPaste.ContentSource
103:  
104:  .class public auto ansi beforefieldinit VSPaste.VSPaste
105:         extends VSPaste.ContentSource
106:  {
107:    .method public hidebysig static string 
108:            Undent(string s) cil managed
109:    {
110:      // 代码大小       7 (0x7)
111:      .maxstack  1
112:      .locals init (string V_0)
113:      IL_0000:  nop
114:      IL_0001:  ldnull
115:      IL_0002:  stloc.0
116:      IL_0003:  br.s       IL_0005
117:  
118:      IL_0005:  ldloc.0
119:      IL_0006:  ret
120:    } // end of method VSPaste::Undent
121:  
122:    .method public hidebysig static string 
123:            AddLines(string html) cil managed
124:    {
125:      // 代码大小       130 (0x82)
126:      .maxstack  5
127:      .locals init (string[] V_0,
128:               string V_1,
129:               int32 V_2,
130:               string V_3,
131:               char[] V_4,
132:               int32 V_5,
133:               bool V_6)
134:      IL_0000:  nop
135:      IL_0001:  ldarg.0
136:      IL_0002:  callvirt   instance string [mscorlib]System.String::Trim()
137:      IL_0007:  ldc.i4.1
138:      IL_0008:  newarr     [mscorlib]System.Char
139:      IL_000d:  stloc.s    V_4
140:      IL_000f:  ldloc.s    V_4
141:      IL_0011:  ldc.i4.0
142:      IL_0012:  ldc.i4.s   10
143:      IL_0014:  stelem.i2
144:      IL_0015:  ldloc.s    V_4
145:      IL_0017:  callvirt   instance string[] [mscorlib]System.String::Split(char[])
146:      IL_001c:  stloc.0
147:      IL_001d:  ldstr      "<span style=\"color:black; font-weight:bold;\">{0:"
148:      IL_0022:  ldc.i4.s   48
149:      IL_0024:  ldloc.0
150:      IL_0025:  ldlen
151:      IL_0026:  conv.i4
152:      IL_0027:  stloc.s    V_5
153:      IL_0029:  ldloca.s   V_5
154:      IL_002b:  call       instance string [mscorlib]System.Int32::ToString()
155:      IL_0030:  callvirt   instance int32 [mscorlib]System.String::get_Length()
156:      IL_0035:  newobj     instance void [mscorlib]System.String::.ctor(char,
157:                                                                        int32)
158:      IL_003a:  ldstr      "}:  </span>"
159:      IL_003f:  call       string [mscorlib]System.String::Concat(string,
160:                                                                  string,
161:                                                                  string)
162:      IL_0044:  stloc.1
163:      IL_0045:  ldc.i4.0
164:      IL_0046:  stloc.2
165:      IL_0047:  br.s       IL_0066
166:  
167:      IL_0049:  ldloc.0
168:      IL_004a:  ldloc.2
169:      IL_004b:  ldloc.1
170:      IL_004c:  ldloc.2
171:      IL_004d:  ldc.i4.1
172:      IL_004e:  add
173:      IL_004f:  box        [mscorlib]System.Int32
174:      IL_0054:  call       string [mscorlib]System.String::Format(string,
175:                                                                  object)
176:      IL_0059:  ldloc.0
177:      IL_005a:  ldloc.2
178:      IL_005b:  ldelem.ref
179:      IL_005c:  call       string [mscorlib]System.String::Concat(string,
180:                                                                  string)
181:      IL_0061:  stelem.ref
182:      IL_0062:  ldloc.2
183:      IL_0063:  ldc.i4.1
184:      IL_0064:  add
185:      IL_0065:  stloc.2
186:      IL_0066:  ldloc.2
187:      IL_0067:  ldloc.0
188:      IL_0068:  ldlen
189:      IL_0069:  conv.i4
190:      IL_006a:  clt
191:      IL_006c:  stloc.s    V_6
192:      IL_006e:  ldloc.s    V_6
193:      IL_0070:  brtrue.s   IL_0049
194:  
195:      IL_0072:  ldstr      "\n"
196:      IL_0077:  ldloc.0
197:      IL_0078:  call       string [mscorlib]System.String::Join(string,
198:                                                                string[])
199:      IL_007d:  stloc.3
200:      IL_007e:  br.s       IL_0080
201:  
202:      IL_0080:  ldloc.3
203:      IL_0081:  ret
204:    } // end of method VSPaste::AddLines
205:  
206:    .method public hidebysig static string 
207:            DeleteChineseGarbage(string str) cil managed
208:    {
209:      // 代码大小       22 (0x16)
210:      .maxstack  3
211:      .locals init (string V_0)
212:      IL_0000:  nop
213:      IL_0001:  ldarg.0
214:      IL_0002:  ldstr      "(\?<ch>\\\\u-\?\\d+ ).."
215:      IL_0007:  ldstr      "${ch}\?"
216:      IL_000c:  call       string [System]System.Text.RegularExpressions.Regex::Replace(string,
217:                                                                                        string,
218:                                                                                        string)
219:      IL_0011:  stloc.0
220:      IL_0012:  br.s       IL_0014
221:  
222:      IL_0014:  ldloc.0
223:      IL_0015:  ret
224:    } // end of method VSPaste::DeleteChineseGarbage
225:  
226:    .method public hidebysig virtual instance valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult 
227:            CreateContent(class [System.Windows.Forms]System.Windows.Forms.IWin32Window dialogOwner,
228:                          string& newContent) cil managed
229:    {
230:      // 代码大小       115 (0x73)
231:      .maxstack  4
232:      .locals init (string V_0,
233:               string V_1,
234:               valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult V_2,
235:               bool V_3)
236:      IL_0000:  nop
237:      .try
238:      {
239:        IL_0001:  nop
240:        IL_0002:  ldsfld     string [System.Windows.Forms]System.Windows.Forms.DataFormats::Rtf
241:        IL_0007:  call       bool [System.Windows.Forms]System.Windows.Forms.Clipboard::ContainsData(string)
242:        IL_000c:  ldc.i4.0
243:        IL_000d:  ceq
244:        IL_000f:  stloc.3
245:        IL_0010:  ldloc.3
246:        IL_0011:  brtrue.s   IL_0050
247:  
248:        IL_0013:  nop
249:        IL_0014:  ldsfld     string [System.Windows.Forms]System.Windows.Forms.DataFormats::Rtf
250:        IL_0019:  call       object [System.Windows.Forms]System.Windows.Forms.Clipboard::GetData(string)
251:        IL_001e:  castclass  [mscorlib]System.String
252:        IL_0023:  call       string VSPaste.VSPaste::DeleteChineseGarbage(string)
253:        IL_0028:  stloc.0
254:        IL_0029:  ldloc.0
255:        IL_002a:  call       string HTMLRootProcessor::FromRTF(string)
256:        IL_002f:  call       string VSPaste.VSPaste::Undent(string)
257:        IL_0034:  call       string VSPaste.VSPaste::AddLines(string)
258:        IL_0039:  stloc.1
259:        IL_003a:  ldarg.2
260:        IL_003b:  ldstr      "<pre class=\"code\">"
261:        IL_0040:  ldloc.1
262:        IL_0041:  ldstr      "</pre>"
263:        IL_0046:  call       string [mscorlib]System.String::Concat(string,
264:                                                                    string,
265:                                                                    string)
266:        IL_004b:  stind.ref
267:        IL_004c:  ldc.i4.1
268:        IL_004d:  stloc.2
269:        IL_004e:  leave.s    IL_0070
270:  
271:        IL_0050:  nop
272:        IL_0051:  leave.s    IL_006b
273:  
274:      }  // end .try
275:      catch [mscorlib]System.Object 
276:      {
277:        IL_0053:  pop
278:        IL_0054:  nop
279:        IL_0055:  ldstr      "VS Paste could not convert that content."
280:        IL_005a:  ldstr      "VS Paste Problem"
281:        IL_005f:  ldc.i4.0
282:        IL_0060:  ldc.i4.s   16
283:        IL_0062:  call       valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string,
284:                                                                                                                                                           string,
285:                                                                                                                                                           valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxButtons,
286:                                                                                                                                                           valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxIcon)
287:        IL_0067:  pop
288:        IL_0068:  nop
289:        IL_0069:  leave.s    IL_006b
290:  
291:      }  // end handler
292:      IL_006b:  nop
293:      IL_006c:  ldc.i4.2
294:      IL_006d:  stloc.2
295:      IL_006e:  br.s       IL_0070
296:  
297:      IL_0070:  nop
298:      IL_0071:  ldloc.2
299:      IL_0072:  ret
300:    } // end of method VSPaste::CreateContent
301:  
302:    .method public hidebysig specialname rtspecialname 
303:            instance void  .ctor() cil managed
304:    {
305:      // 代码大小       7 (0x7)
306:      .maxstack  8
307:      IL_0000:  ldarg.0
308:      IL_0001:  call       instance void VSPaste.ContentSource::.ctor()
309:      IL_0006:  ret
310:    } // end of method VSPaste::.ctor
311:  
312:  } // end of class VSPaste.VSPaste
313:  
314:  
315:  // =============================================================
316:  
317:  // *********** 反汇编完成 ***********************
318:  // 警ˉ告: 创建了 Win32 资ê源文件 VSPaste2.res

 

现在,使用以下命令反汇编 VSPaste.dll:

E:\CS\VSPaste> ildasm VSPaste.dll /output:VSPaste.il

 

把 VSPaste2.il 文件中第 226 行到第 300 行的 VSPaste::CreateContent 方法替代 VSPaste.il 中的同名方法。并且把 VSPaste2.il 文件中第 206 行到第 224 行的 VSPate::DeleteChineseGarbage 方法加入到 VSPaste.il 文件中去。最后,使用以下命令重新进行汇编:

E:\CS\VSPaste> ilasm /dll /quiet VSPaste.il

将得到的 VSPaste.dll 拷贝到 Windows Live Writer 安装目录的 Plugins 目录,在我的机器上是 C:\Program Files\Windows Live\Writer\Plugins\,就行了。现在,让我们运行 Windows Live Writer,咦,VSPaste 插件不见了。怎么回事?

想了半天,最后使用 .NET Framework 2.0 中的 csc.exe 和 ilasm.exe 代替 .NET Framework 4 的,重做以上步骤。

在我的机器上,这两个 exe 文件位于 C:\Windows\Microsoft.NET\Framework\v2.0.50727\ 目录。因为没有找到 .NET Framework 2.0 的 ildasm.exe,就使用 .NET Framework 3.5 的,它位于 C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\ 目录。

这下果然行了。  微笑

测试一下效果:

01:  using System;
02:  using System.Windows;
03:  
04:  namespace Skyiv.Tester
05:  {
06:    static class ClipboardTester
07:    {
08:      [STAThread]
09:      static void Main()
10:      {
11:        var obj = Clipboard.GetDataObject();
12:        foreach (var v in obj.GetFormats())
13:        {
14:          Console.WriteLine("[{0}]", v);
15:          Console.WriteLine("-------- 开始 --------");
16:          try { Console.WriteLine("{0}", VSPaste.VSPaste.DeleteChineseGarbage(obj.GetData(v).ToString())); }
17:          catch (Exception ex) { Console.WriteLine(ex); }
18:          Console.WriteLine("-------- 结束 --------");
19:          Console.WriteLine();
20:        }
21:      }
22:    }
23:  }

 

果然没有乱码了。

另外一个 Paste from Visual Studio 插件

后来,又找到另外一个 Paste from Visual Studio 插件,效果如下:

ClipboardTester.cs
  1. using System;
  2. using System.Windows;
  3.  
  4. namespace Skyiv.Tester
  5. {
  6.   static class ClipboardTester
  7.   {
  8.     [STAThread]
  9.     static void Main()
  10.     {
  11.       var obj = Clipboard.GetDataObject();
  12.       foreach (var v in obj.GetFormats())
  13.       {
  14.         Console.WriteLine("[{0}]", v);
  15.         Console.WriteLine("-------- 开始 --------");
  16.         try { Console.WriteLine("{0}", VSPaste.VSPaste.DeleteChineseGarbage(obj.GetData(v).ToString())); }
  17.         catch (Exception ex) { Console.WriteLine(ex); }
  18.         Console.WriteLine("-------- 结束 --------");
  19.         Console.WriteLine();
  20.       }
  21.     }
  22.   }
  23. }

 

该插件使用另外一套方法来把 RTF 格式转换为 Html 格式。我是直接从“让Paste as Visual Studio Code支持Visual Studio 2010粘贴的中文--自己动手丰衣足食”下载现成的 LavernockEnterprises.PasteAsVSCode.dll 文件来使用。

参考资料

  1. 定制 Paste from Visual Studio 插件 (上)
  2. 定制 Paste from Visual Studio 插件 (下)
  3. 让Paste as Visual Studio Code支持Visual Studio 2010粘贴的中文--自己动手丰衣足食
  4. 维基百科: RTF
posted on 2011-01-15 16:23 银河 阅读(...) 评论(...) 编辑 收藏