2007年3月24日星期六

修正 CopySourceAsHTML 插件无法用于中文 VS2005 的Bug

为了写Blog,我下载了一个叫 CopySourceAsHTML 的 VS2005 插件,通过它为VS2005增加的“Copy As HTML...”命令复制出来的代码会被HTML标记包裹,可以直接粘贴到Blog的HTML标记中(本篇文章中的代码就是用它作成的^_^)。

令人遗憾的是,当我兴冲冲地下载了CopySourceAsHTML 的安装文件 “CopySourceAsHtml.msi” 并且完成安装后,启动 VS2005,看到了这样一个 Exception:




进入VS2005后,发现菜单上也没有“Copy As Html...”选项。好在CopySourceAsHtml是一个开源软件,通过分析其源代码,笔者找到了修正此Bug的方法。

分析源代码

可以看到 Exception 的信息是“值不在预期范围内”,位置是 Connect.AddControls() 中对 CommandBars.CommandBarControls.get_Item() 的调用。安装了CopySourceAsHtml软件后,在“C:\Program Files\J.T. Leigh & Associates Inc\CopySourceAsHtml\” 可以找到一个叫 “Source.zip” 的压缩包,即是源代码了。将其解压缩,双击“Source\CopySourceAsHtml.sln” 打开工程,再打开 “Connect.cs”,来到第195行,可以看到如下代码:

187 private void AddControls()

188 {

189

190 CommandBars commandBars;

191 CommandBarPopup editPopup;

192 int copyIndex;

193

194 commandBars = (CommandBars)this.application.CommandBars;

195 editPopup = (CommandBarPopup)commandBars["MenuBar"].Controls["Edit"];

196

197 copyIndex = FindCopyOnCommandBar("Edit") + 1;




猜测不是在commandBars中找不到"MenuBar"就是在commandBars["MenuBar"].Controls中找不到"Edit"。

在第194行后面插入如下代码:

194 commandBars = (CommandBars)this.application.CommandBars;

195 // test

196 System.IO.StringWriter msg = new StringWriter();

197 foreach (CommandBar eachCommandBar in commandBars)

198 {

199 msg.Write(eachCommandBar.Name + " ");

200 }

201 throw new Exception(msg.ToString());

202 editPopup = (CommandBarPopup)commandBars["MenuBar"].Controls["Edit"];




重新编译工程,然后将新生成的CopySourceAsHtml.dll(在C:\Program Files\J.T. Leigh & Associates Inc\CopySourceAsHtml\Source\Source\Bin\) 复制粘贴到“My Documents\Visual Studio 2005\Addins\”覆盖同名文件(如果提示文件正在使用中,则需要关闭VS2005。也可以将原来的CopySourceAsHtml.dll重命名为CopySourceAsHtml.dll.old再粘贴新的CopySourceAsHtml.dll),然后打开一个新的VS2005,就可以看到commandBars中的所有内容了,发现有“MenuBar”。将测试代码变为:

194 commandBars = (CommandBars)this.application.CommandBars;

195 // test

196 System.IO.StringWriter msg = new StringWriter();

197 foreach (CommandBarControl eachCommandBarControl in commandBars["MenuBar"].Controls)

198 {

199 msg.Write(eachCommandBarControl.Caption + " ");

200 }

201 throw new Exception(msg.ToString());

202 editPopup = (CommandBarPopup)commandBars["MenuBar"].Controls["Edit"];



再次替换“My Documents\Visual Studio 2005\Addins\CopySourceAsHtml.dll”,重启VS2005,可以看到commandBars["MenuBar"].Controls中每个CommandBarControl的Caption都是中文的,其中与Edit相对应的应该是“编辑”,将editPopup = (CommandBarPopup)commandBars["MenuBar"].Controls["Edit"]; 替换为editPopup = (CommandBarPopup)commandBars["MenuBar"].Controls["编辑"]; 再次替换CopySourceAsHtml.dll并重启VS2005,Exception不再显现了。 现在源代码变为:

187 private void AddControls()

188 {

189

190 CommandBars commandBars;

191 CommandBarPopup editPopup;

192 int copyIndex;

193

194 commandBars = (CommandBars)this.application.CommandBars;

195 //editPopup = (CommandBarPopup)commandBars["MenuBar"].Controls["Edit"];

196 editPopup = (CommandBarPopup)commandBars["MenuBar"].Controls["编辑"];

197

198 copyIndex = FindCopyOnCommandBar("Edit") + 1;



不过“Copy As HTML...”命令出现的位置似乎不对,而且我们记得在第一次看到的Exception中提示在Connect.cs的第63行也有错误。通过与上面相似的方法,可以发现菜单“编辑|复制”不是英文的“Copy”而是“复制(C)”。修正的方法是在VS2005中的解决方案资源管理器中右击CopySourceAsHTML项目,在上下文菜单中点击“属性”,点击“资源”选项卡,将名称为“CopyMenuItemText”的值由原来的“Copy”更改为“复制(C)”。再次替换“My Documents\Visual Studio 2005\Addins\CopySourceAsHtml.dll”,重启VS2005,CopySourceAsHTML已经可以正常工作了。

下载修正后的CopySourceAsHtml.dll

如果你觉得自己改代码太麻烦,可以直接下载我的修正过的CopySourceAsHtml.dll文件。请按如下步骤操作:
  1. 下载CopySourceAsHtml的安装文件CopySourceAsHtml.msi,并安装。
  2. 下载我修正过的CopySourceAsHtml.dll文件,地址为:http://download.csdn.net/source/162560
  3. 将第二步下载的CopySourceAsHtml.dll文件复制到“My Documents\Visual Studio 2005\Addins\”覆盖同名文件。
  4. 重新启动VS2005。

一些疑问

CopySourceAsHtml这个插件之所以会抛出异常,是因为application.CommandBars.Controls的ObjectIndex由英文版VS2005的“Edit”变成了中文版VS2005的“编辑”。我对插件编程一窍不通,不知到为什么会发生这种事情,但想来不外乎三种情况:
  • CopySourceAsHtml这个插件使用了错误的访问application.CommandBars.Controls的方法。例如,也许存在一种英文版VS2005和中文版VS2005通用的访问application.CommandBars.Controls的方法,使得不论是哪个语言版本的VS2005都能正常使用这个插件。或者:
  • 中文版VS2005使用了错误的汉化方法。例如不应该直接将“Edit”改为“编辑”,而应该在资源文件中进行更改。或者:
  • VS2005的application.CommandBars.Controls设计有缺陷,没有考虑国际化方面的问题。造成无法编写出适用于所有语言版本的VS2005的插件。

请网友高人不吝赐教。

2 条评论:

匿名 说...

aaa

匿名 说...

Hi Iam Prabhu from chennai,joined today in this forum... :)