<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Nana的荔枝园</title><subtitle type="text">Clark Kent是个普通的外星人，我是个普通的编程爱好者。</subtitle><id>http://feed.cnblogs.com/blog/u/63191/rss</id><updated>2012-05-27T02:34:09Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/63191/rss"/><entry><id>http://www.cnblogs.com/NanaLich/archive/2012/05/26/a-scriptlet-for-app-path.html</id><title type="text">一个简单的WSH Scriptlet</title><summary type="text">先强调一下，我这里把它称为“Scriptlet”只是因为和其字面意义比较近似，并不是指 Microsoft Windows 中的那种“脚本组件”。起因有些时候我会弄到一些免安装的实用工具，比方说 Sysinternals 套件中的工具就都属于这一种。但是虽然工具是免安装的，可实际用起来的时候找到工具的所在位置也挺麻烦的，所以我尝试过几种办法，有创建快捷方式、创建文件夹、设置 Path 环境变量等等，总地来说当这类五花八门的免安装工具越来越多的时候，我是会犯懒的，于是我就开始想有什么办法可以一劳永逸地解决这个问题。解决方案经过短时间的尝试以后，我最终写出了一个能有点帮助的 Scriptlet，语</summary><published>2012-05-26T12:59:00Z</published><updated>2012-05-26T12:59:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2012/05/26/a-scriptlet-for-app-path.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2012/05/26/a-scriptlet-for-app-path.html"/><content type="html">&lt;p&gt;先强调一下，我这里把它称为&amp;ldquo;Scriptlet&amp;rdquo;只是因为和其字面意义比较近似，并不是指 Microsoft Windows 中的那种&amp;ldquo;脚本组件&amp;rdquo;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;起因&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有些时候我会弄到一些免安装的实用工具，比方说 Sysinternals 套件中的工具就都属于这一种。&lt;/p&gt;&lt;p&gt;但是虽然工具是免安装的，可实际用起来的时候找到工具的所在位置也挺麻烦的，所以我尝试过几种办法，有创建快捷方式、创建文件夹、设置 Path 环境变量等等，总地来说当这类五花八门的免安装工具越来越多的时候，我是会犯懒的，于是我就开始想有什么办法可以一劳永逸地解决这个问题。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决方案&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;经过短时间的尝试以后，我最终写出了一个能有点帮助的 Scriptlet，语言为 JScript，完整代码如下：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;function print(s){&lt;br/&gt;  WScript.Echo(s);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;function installScriptlet(){&lt;br/&gt;  var sh = new ActiveXObject("WScript.Shell");&lt;br/&gt;  var env = sh.Environment("Process");&lt;br/&gt;  var installPath = env("AppData");&lt;br/&gt;  if(!installPath)&lt;br/&gt;    installPath = sh.SpecialFolders("MyDocuments");&lt;br/&gt;&lt;br/&gt;  var fso = new ActiveXObject("Scripting.FileSystemObject");&lt;br/&gt;  installPath = fso.BuildPath(installPath, "Scriptlet");&lt;br/&gt;  if(!fso.FolderExists(installPath))&lt;br/&gt;    fso.CreateFolder(installPath);&lt;br/&gt;&lt;br/&gt;  installPath = fso.BuildPath(installPath, WScript.ScriptName);&lt;br/&gt;  fso.CopyFile(WScript.ScriptFullName, installPath);&lt;br/&gt;&lt;br/&gt;  var kucr = "HKCU" + "\\Software\\Classes\\";&lt;br/&gt;  var verbKey = kucr + sh.RegRead("HKCR\\.exe\\") + "\\shell\\RegAppPath\\";&lt;br/&gt;  sh.RegWrite(verbKey, "Register Application Path");&lt;br/&gt;  sh.RegWrite(verbKey + "command\\", '"' + WScript.FullName + '" "' + installPath + '" "%1"');&lt;br/&gt;&lt;br/&gt;  print(WScript.ScriptName + " installation successful!");&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;function registerAppPath(appPath){&lt;br/&gt;  var fso = new ActiveXObject("Scripting.FileSystemObject");&lt;br/&gt;  var fn = fso.GetFileName(appPath);&lt;br/&gt;&lt;br/&gt;  var kuap = "HKCU" + "\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";&lt;br/&gt;  var sh = new ActiveXObject("WScript.Shell");&lt;br/&gt;  sh.RegWrite(kuap + fn + "\\", appPath);&lt;br/&gt;  sh.RegWrite(kuap + fn + "\\Path", fso.GetParentFolderName(appPath));&lt;br/&gt;&lt;br/&gt;  print("Path set for " + fn + " !");&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;var args = WScript.Arguments;&lt;br/&gt;&lt;br/&gt;if(args.Length &amp;lt; 1)&lt;br/&gt;  installScriptlet();&lt;br/&gt;else&lt;br/&gt;  registerAppPath(args(0));&lt;br/&gt;&lt;/div&gt;&lt;p&gt;使用方法很简单，首先得把这些代码保存在一个纯文本文件中，扩展名应为&amp;ldquo;.js&amp;rdquo;：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/NanaLich/201205/201205262059171194.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;然后双击刚刚保存的这个文件，就会出现这样的提示：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/NanaLich/201205/201205262059185272.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;现在 .exe 可执行文件的快捷菜单中就会多出来一个菜单项：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/NanaLich/201205/201205262059188587.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;当点击这个菜单项以后，会出现这样的提示：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/NanaLich/201205/201205262059199077.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;从此以后只要在"运行"对话框（快捷键为Win+R）中输入"Your Application"就可以直接运行 Your Application.exe 了：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/NanaLich/201205/201205262131493160.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;而不用特别指定路径，或是自己用资源管理器去把可执行文件找出来。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;答疑&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;可能我在开头说的"一劳永逸"会让一些人感到困惑：&lt;/p&gt;&lt;p&gt;这好像也没方便到哪去啊，而且每个可执行文件都要这么搞一次，也不比直接改Path好嘛。&lt;/p&gt;&lt;p&gt;实际上它是这么回事：&lt;/p&gt;&lt;p&gt;只有像 Sysinternals 这样的实用工具套件才比较适合用改 Path 的办法，而大部分的免安装工具都是一个两个可执行文件就作为一个产品发布出来了，很多时候不同的产品可能还会有些名字相同的文件，这样你就不能把它们都放在同一个目录中，如果设置 Path 的话得对每一个这样的产品都这样做一次；而且有些比较特殊的情况，比方说当你的 Windows 中同时安装了多个版本的 .NET Framework 时，你肯定不会希望将其中的一个或者多个都设置到 Path 环境变量中，因为那可能会引发一些难以预料的事情。&lt;/p&gt;&lt;p&gt;最后，即使用修改 Path 的方式能把上述问题都解决掉，可是如果因为某种原因需要重装 Windows 呢？可能重装一次之后我们还能隐约想起以前是怎么设置的了，那么再一次重装之后呢？以后还会每次都这样设置吗？&lt;/p&gt;&lt;p&gt;从我拥有自己的电脑以来到现在已经有十多年了，而这十多年使用电脑的经历中，重装 Windows 之后"懒得去折腾"算得上是高概率事件了，所以我把这种操作放在一个脚本工具里，这样就算重装 Windows 之后没有马上去设置这些免安装工具，但当第一次因为要使用某个工具而用资源管理器打开相应的文件夹时，只要轻击鼠标右键，就可以很方便地为这个工具配置好路径了。&lt;/p&gt;&lt;p&gt;而这个脚本工具本身，只要放在一个容易找到的地方，就算我自己再懒，每次重装 Windows 以后运行一次也还是做得到的。&lt;/p&gt;&lt;p&gt;我所谓的&amp;ldquo;一劳永逸&amp;rdquo;就是这个意思。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;注：&lt;/p&gt;&lt;p&gt;这个脚本工具在编写的时候只在 Windows 7 上测试过，后来检查相关的技术资料发现可能在 Windows XP 和 Windows Vista 上不能正常工作，如果使用过程中发现了这样的问题，只需要把&amp;ldquo;HKCU&amp;rdquo;改成&amp;ldquo;HKLM&amp;rdquo;即可。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/2519526.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2012/05/26/a-scriptlet-for-app-path.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2012/05/24/2516860.html</id><title type="text">另一种在字节数组和十六进制字符串之间转换的手段</title><summary type="text">几年前我使用国外的一个流行的Blog服务来撰写博文，但是因为一些众所周知的原因我打不开自己的博客了，于是才刚刚开始写博的我就不得不中断这种行为了，直到后来在园子重新开博。前几天我弄到了条VPN，一时兴起就翻出原来的博客来看，结果在上面找到了以前的一些小研究，其中之一便是标题所指的东西。用途什么的就不再废话了，总之在.NET编程中通常来说从字节数组到十六进制的转换是要用BitConverter.ToString，返回的字符串会包含减号/横线作为每个字节所对应的十六进制数之间的分隔符，不想看到的话就只能再Replace掉，而且BitConverter类名不能省略，用起来不怎么方便；从十六进制到字节</summary><published>2012-05-24T09:42:00Z</published><updated>2012-05-24T09:42:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2012/05/24/2516860.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2012/05/24/2516860.html"/><content type="html">&lt;p&gt;几年前我使用国外的一个流行的Blog服务来撰写博文，但是因为一些众所周知的原因我打不开自己的博客了，于是才刚刚开始写博的我就不得不中断这种行为了，直到后来在园子重新开博。&lt;/p&gt;&lt;p&gt;前几天我弄到了条VPN，一时兴起就翻出原来的博客来看，结果在上面找到了以前的一些小研究，其中之一便是标题所指的东西。&lt;/p&gt;&lt;p&gt;用途什么的就不再废话了，总之在.NET编程中通常来说从字节数组到十六进制的转换是要用BitConverter.ToString，返回的字符串会包含减号/横线作为每个字节所对应的十六进制数之间的分隔符，不想看到的话就只能再Replace掉，而且BitConverter类名不能省略，用起来不怎么方便；从十六进制到字节数组的转换就麻烦了，普遍只能手工编写对应的代码并封装。&lt;/p&gt;&lt;p&gt;在经过一些探索之后，我最后发现了一个捷径：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;using XS = System.Xml.Serialization;&lt;br/&gt;&lt;br/&gt;namespace Nana&lt;br/&gt;{&lt;br/&gt;  public static class BinaryExtensions&lt;br/&gt;  {&lt;br/&gt;    #region Dummy Utils&lt;br/&gt;&lt;br/&gt;    private class dummyReader : XS.XmlSerializationReader&lt;br/&gt;    {&lt;br/&gt;      protected override void InitCallbacks() { }&lt;br/&gt;      protected override void InitIDs() { }&lt;br/&gt;&lt;br/&gt;      public static byte[] HexToBytes(string hex)&lt;br/&gt;      {&lt;br/&gt;        return ToByteArrayHex(hex);&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    private class dummyWriter : XS.XmlSerializationWriter&lt;br/&gt;    {&lt;br/&gt;      protected override void InitCallbacks() { }&lt;br/&gt;&lt;br/&gt;      public static string BytesToHex(byte[] bin)&lt;br/&gt;      {&lt;br/&gt;        return FromByteArrayHex(bin);&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #endregion&lt;br/&gt;&lt;br/&gt;    public static string BytesToHex(this byte[] bin)&lt;br/&gt;    {&lt;br/&gt;      return dummyWriter.BytesToHex(bin);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    public static byte[] HexToBytes(this string hex)&lt;br/&gt;    {&lt;br/&gt;      return dummyReader.HexToBytes(hex);&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;}&lt;/div&gt;&lt;p&gt;虽然这里用了两个Dummy类型，但相比于其它流行的办法，我觉得这样更清晰一些。&lt;/p&gt;&lt;p&gt;而且如果你之前一直都在用BitConverter.ToString的话，现在封装了扩展方法用起来也更方便&amp;mdash;&amp;mdash;实际上它也比BitConverter.ToString略快。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/2516860.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2012/05/24/2516860.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/06/21/cnblogs-css-glitch.html</id><title type="text">园子的模板 CSS 有点小毛病</title><summary type="text">#green_channel a{/* ... 省略 ... */-moz-border-radius: 5px;-webkit-border-radius: 10px;-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5);-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5);/* ... 省略 ... */}这段 CSS 是针对 Mozilla 和 WebKit 引擎的，所以其它浏览器认不出来。实际上 Opera 和 IE9 早就可以正确呈现这样的效果了，只要换成这样就可以了：#green_channel a{/* ...</summary><published>2011-06-21T07:49:00Z</published><updated>2011-06-21T07:49:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/06/21/cnblogs-css-glitch.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/06/21/cnblogs-css-glitch.html"/><content type="html">#green_channel a{&lt;br/&gt;/* ... 省略 ... */&lt;br/&gt;-moz-border-radius: 5px;-webkit-border-radius: 10px;-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5);-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5);&lt;br/&gt;/* ... 省略 ... */&lt;br/&gt;}&lt;div&gt;这段 CSS 是针对 Mozilla 和 WebKit 引擎的，所以其它浏览器认不出来。&lt;/div&gt;&lt;div&gt;实际上 Opera 和 IE9 早就可以正确呈现这样的效果了，只要换成这样就可以了：&lt;/div&gt;#green_channel a{&lt;br/&gt;/* ... 省略 ... */&lt;br/&gt;border-radius: 5px; box-shadow: 0 1px 3px rgba(0,0,0,0.5);&lt;br/&gt;/* ... 省略 ... */&lt;br/&gt;}&lt;div&gt;当然了，我看的是我正在用的这个模板，不知道其它模板细节是如何。&lt;/div&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/2086099.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/06/21/cnblogs-css-glitch.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/06/16/regular-expression-that-validate-email-address-format.html</id><title type="text">两则用于验证 Email 地址的正则表达式</title><summary type="text">网络上所流传的大部分验证信箱格式的正则表达式往往会对一些实际上有效的信箱地址作出错误地判断，所以我参考 RFC 写了个比较完善的，可以用来对付几乎所有可能的信箱地址格式。</summary><published>2011-06-16T06:35:00Z</published><updated>2011-06-16T06:35:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/06/16/regular-expression-that-validate-email-address-format.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/06/16/regular-expression-that-validate-email-address-format.html"/><content type="html">&lt;p&gt;完全版（接受所有有效形式，除了域名部分为纯 IP 地址的情况）：&lt;/p&gt;/^("(?:\\[ -~]|[ !#-\[\]-~])+"|[!#-'*+\-\/\d=?A-Z^_`a-z{|}~]+(?:\.[!#-'*+\-\/\d=?A-Z^_`a-z{|}~]+)*)@((?:[\dA-Za-z](?:[-\dA-Za-z]*[\dA-Za-z])?\.)+[A-Za-z][-A-Za-z]*[A-Za-z])$/&lt;p&gt;简化版（只接受常见的 Email 地址形式，行为近似于 Hotmail）：&lt;/p&gt;/^([&amp;amp;'+\-\d=A-Z_a-z]+(?:\.[&amp;amp;'+\-\d=A-Z_a-z]+)*)@((?:[\dA-Za-z](?:[-\dA-Za-z]*[\dA-Za-z])?\.)+[A-Za-z][-A-Za-z]*[A-Za-z])$/&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/2082645.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/06/16/regular-expression-that-validate-email-address-format.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/01/22/1941947.html</id><title type="text">【备忘】在类库项目中使用 Razor 智能感知</title><summary type="text">http://blogs.msdn.com/b/webdevtools/archive/2011/01/20/how-to-get-razor-intellisense-for-model-in-a-class-library-project.aspx</summary><published>2011-01-22T07:15:00Z</published><updated>2011-01-22T07:15:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/01/22/1941947.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/01/22/1941947.html"/><content type="html">&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/webdevtools/archive/2011/01/20/how-to-get-razor-intellisense-for-model-in-a-class-library-project.aspx"&gt;http://blogs.msdn.com/b/webdevtools/archive/2011/01/20/how-to-get-razor-intellisense-for-model-in-a-class-library-project.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/1941947.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/01/22/1941947.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/01/21/KyuuBackground-implementing-basic-functions.html</id><title type="text">分享 Visual Studio 2010 扩展制作的心得：基本功能篇</title><summary type="text">在制作为 Visual Studio 2010 添加背景的扩展时遭遇了很多问题，现在我把这些问题以及解决的办法分享出来，希望能帮到同样对 Visual Studio 扩展感兴趣的同学。这一篇先说说“添加背景”这一基本功能的实现。</summary><published>2011-01-21T03:09:00Z</published><updated>2011-01-21T03:09:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/01/21/KyuuBackground-implementing-basic-functions.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/01/21/KyuuBackground-implementing-basic-functions.html"/><content type="html">&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;几个月前我做了一个&lt;a href="http://www.cnblogs.com/NanaLich/archive/2010/10/12/an-ita-background-extension-for-visual-studio-2010-code-editor.html"&gt;给 Visual Studio 2010 增加背景图片的扩展&lt;/a&gt;，不过说实在的这个东西也是借鉴了&lt;a href="http://visualstudiogallery.msdn.microsoft.com/zh-cn/0e6f9037-b753-469e-86d4-bfba78c74cf6"&gt;日本人做的同类扩展&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;没想到放出来之后有很多人对此感兴趣，我也因此决定增加配置对话框功能，免去手工编辑配置文件的麻烦。&lt;/p&gt;&lt;p&gt;但是因为一些奇怪的原因，说好的功能一直没有去做，在这期间也有别人在此基础上进行改造（虽然有点无伤大雅的小小误会），受这件事情的刺激我决定完善这个扩展，让它成为一个说得过去的产品。&lt;/p&gt;&lt;p&gt;而在完善这个扩展的过程中也遭遇了种种的困难，为了让对这方面感兴趣的同学们以后少走弯路，我决定以博文为载体将解决这些问题的经验分享出来。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;基本功能的实现&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;我这个扩展到基本功能么，就是给 Visual Studio 2010 里面的文本编辑器增加背景图案，然后还要使用一个 XML 文件来保存这些配置。&lt;/p&gt;&lt;p&gt;原理呢，就是通过编辑器修饰物扩展的实现，来在编辑器中插入 Canvas 控件和 Image 控件（WPF），来绘制背景，效果呢大概就是这样：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/99527/2010101222591991.jpg" width="438" height="318" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;通过 Visual Studio SDK 所提供的项目模板可以创建简单的编辑器修饰项目，模板中实现的是一个紫色的方块，我们需要把它改造成我们需要的东西。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;背景图片&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;单纯的背景图片实现其实是很容易的事情，因为通过模板创建的项目就是使用 Image 控件来显示紫色方块的，只要设置好其 Source 属性，再设定其位置和一些其它的杂项属性就成了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;设置 Source 属性&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为目标是图片文件，所以设置 Source 属性时的首选类型是 BitmapImage。&lt;/p&gt;&lt;p&gt;不过 BitmapImage 的默认构造器会独占目标图片文件，因而导致程序运行过程中无法修改或移动目标图片文件。&lt;/p&gt;&lt;p&gt;解决这个问题的办法则是使用无参数的构造器，并且手工编写初始化步骤：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;var bmp = new BitmapImage();&lt;br/&gt;bmp.BeginInit();&lt;br/&gt;bmp.CreateOptions = BitmapCreateOptions.IgnoreImageCache;&lt;br/&gt;bmp.CacheOption = BitmapCacheOption.OnLoad;&lt;br/&gt;bmp.UriSource = new Uri(value);&lt;br/&gt;bmp.EndInit();&lt;br/&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;设定位置和大小&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;项目的默认实现采用的是固定大小的 Image 控件，并将之放在右上角。&lt;/p&gt;&lt;p&gt;而对于我们采用的背景图片来说，可能放在其它位置更好，比方说我最喜欢的一张比较适合放在右下角。&lt;/p&gt;&lt;p&gt;要改变其位置也并不复杂，只要让 Image 控件填满整个空间，然后设置它的&amp;nbsp;HorizontalAlignment 和&amp;nbsp;VerticalAlignment 属性就可以了。&lt;/p&gt;&lt;p&gt;这里需要注意的是，ItaBackgroundImage 把 Image 控件的位置坐标设置成了『0, 0』，而当编辑器大小改变（比方说缩放了 Visual Studio 的窗口）时这种设计会导致背景图片错位。&lt;/p&gt;&lt;p&gt;正确的方法应该是这样做：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;Canvas.SetLeft(element, textView.ViewportLeft);&lt;br/&gt;Canvas.SetTop(element, textView.ViewportTop);&lt;br/&gt;&lt;br/&gt;element.Width = textView.ViewportWidth;&lt;br/&gt;element.Height = textView.ViewportHeight;&lt;br/&gt;&lt;br/&gt;adornmentLayer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative,&lt;br/&gt;  null, null, element, null);&lt;/div&gt;&lt;p&gt;&lt;strong&gt;墙纸图案&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;和背景图片不同，墙纸图案通常是重复绘制来填充整个背景空间的，所以使用 Canvas 和 ImageBrush 来配合的效果比较好，ImageBrush 的 TileMode 属性应该设置成 None 以外的项目。&lt;/p&gt;&lt;p&gt;不过使用过我之前发布的 ItaBackgroundKyuu 的同学可能会注意到，ItaBackgroundKyuu 的墙纸图案是&amp;ldquo;固定位置&amp;rdquo;的，当文本进行滚动的时候墙纸并不会跟随着一起滚动，这样用起来会感觉很奇怪，因此我又花了些时间来研究让墙纸跟随文本一起滚动的办法。&lt;/p&gt;&lt;p&gt;通过调用 AddAdornment 时指定 AdornmentPositioningBehavior.OwnerControlled 可以初步达到这个目的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;纵向坐标偏移的问题&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果改变了编辑器的显示比例（Zoom），或者从非正常关闭中恢复 Visual Studio 时，编辑器视图的坐标系可能会发生改变；如果这个时候向上滚动编辑器，就会发现前面的部分并没有绘制墙纸图案，甚至还有可能会引发异常。&lt;/p&gt;&lt;p&gt;借助 Reflector 等手段研究了一番之后，并没有发现什么可以确定文本中第一行的纵向坐标的简单办法，不知道是不是搞错了探索的方向。&lt;/p&gt;&lt;p&gt;不过在这个过程中却发现编辑器内部似乎是从某一行开始一行一行地累加行高，所以经过若干小时的尝试之后，最终我也采用了累加行高的办法，这部分是这样实现的：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;private double GetFirstLineTop(IWpfTextView view)&lt;br/&gt;{&lt;br/&gt;  var fvLine = view.TextViewLines.FirstVisibleLine;&lt;br/&gt;  double top = fvLine.Top;&lt;br/&gt;&lt;br/&gt;  var ss = fvLine.Snapshot;&lt;br/&gt;  int lastIndex = fvLine.Start;&lt;br/&gt;&lt;br/&gt;  IWpfTextViewLine line;&lt;br/&gt;  while (lastIndex &amp;gt; 0)&lt;br/&gt;  {&lt;br/&gt;    line = view.GetTextViewLineContainingBufferPosition(new SnapshotPoint(ss, lastIndex - 1));&lt;br/&gt;    top -= line.Height;&lt;br/&gt;&lt;br/&gt;    lastIndex = line.Start;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  return top;&lt;br/&gt;}&lt;/div&gt;&lt;p&gt;在 ITextView 的 LayoutChanged 事件中写入下面这样的代码，就可以让墙纸图案随着文本一并滚动了，而且改变显示比例也不会导致错位问题：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;var tileTop = GetFirstLineTop(textView);&lt;br/&gt;Canvas.SetTop(tile, tileTop); // tile 是用于呈现墙纸图案的 Canvas 控件&lt;br/&gt;&lt;br/&gt;var state = e.NewViewState;&lt;br/&gt;tile.Width = state.ViewportRight;&lt;br/&gt;tile.Height = state.ViewportBottom - tileTop;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;修饰层的呈现优先顺序&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;修饰层以哪种优先级呈现会影响到修饰层中的修饰物件会遮挡住什么、可以被什么遮挡住。&lt;/p&gt;&lt;p&gt;修饰项目默认采用的修饰层是这样设定的：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;[Export(typeof(AdornmentLayerDefinition))]&lt;br/&gt;[Name("ViewportAdornment1")]&lt;br/&gt;[Order(After = PredefinedAdornmentLayers.Caret)]&lt;br/&gt;[TextViewRole(PredefinedTextViewRoles.Document)]&lt;br/&gt;public AdornmentLayerDefinition editorAdornmentLayer = null;&lt;/div&gt;&lt;p&gt;然而在实际使用中会发现我们的修饰层可能会意外地显示不正确，调试过程中可以发现在能满足&amp;nbsp;[Order(After = PredefinedAdornmentLayers.Caret)] 的前提下，我们的修饰层的呈现顺序并不确定，而是随机插入在其它修饰层之间的。&lt;/p&gt;&lt;p&gt;为了让它正确呈现，我们需要指定一个较为严格的顺序，比方说：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;[Order(Before = PredefinedAdornmentLayers.Outlining)]&lt;/div&gt;&lt;p&gt;这样我们的修饰物就总会出现在编辑器的最底层了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;设置的存储&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;为了省却一部分人在重装系统之后可能需要重新设置的麻烦，我把设置以 XML 文件的形式保存在了『我的文档』之中。&lt;/p&gt;&lt;p&gt;由于采用的是独立的 XML 文件，因此直接使用了 XML 序列化功能，而没有去使用 .NET 框架所推荐的&amp;nbsp;ConfigurationSection 设计。&lt;/p&gt;&lt;p&gt;这部分没有什么需要特别注意的技术细节，也不作过多的说明了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;后记&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这一次主要说的是实现基本功能时需要注意的技术细节，然而在完善它使其成为一款真正的『产品』的过程中还有很多其它方面的问题，这些问题以及解决的办法我也会在以后的博文中一一列举出来。&lt;/p&gt;&lt;p&gt;博文大致会写成这样的几篇：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;设置对话框的实现；&lt;/li&gt;&lt;li&gt;打包 VSIX 的心得；&lt;/li&gt;&lt;li&gt;编程过程中遭遇的陷阱。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;最后，附上我的扩展在『Visual Studio 扩展库』上的下载页面链接：&lt;/p&gt;&lt;p&gt;&lt;a href="http://visualstudiogallery.msdn.microsoft.com/zh-cn/2d4f653f-262a-4d3a-b42c-c6f8e35e777e"&gt;http://visualstudiogallery.msdn.microsoft.com/zh-cn/2d4f653f-262a-4d3a-b42c-c6f8e35e777e&lt;/a&gt;&lt;/p&gt;&lt;p&gt;发布在扩展库上就意味着安装扩展的用户以后都能及时收到更新。&lt;/p&gt;&lt;p&gt;需要注意的是，扩展名称已经从『ItaBackgroundKyuu』改成了『KyuuBackground』，名称上的改变导致之前版本的配置文件也不再起作用了，需要通过选项对话框重新设置。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/1940816.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/01/21/KyuuBackground-implementing-basic-functions.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/01/21/asp-net-mvc-3-chs-released.html</id><title type="text">ASP.NET MVC 3 中文版正式释出上线</title><summary type="text">微软下载中心已经提供了中文版的 ASP.NET MVC 3 下载，之前公布的免费 Web 平台产品已经有六款放出了中文版本。而 Visual Studio Service Pack 1 还要等上一段时间才会发布。</summary><published>2011-01-21T00:57:00Z</published><updated>2011-01-21T00:57:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/01/21/asp-net-mvc-3-chs-released.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/01/21/asp-net-mvc-3-chs-released.html"/><content type="html">&lt;p&gt;今天在&lt;a href="http://www.microsoft.com/downloads/zh-cn/default.aspx"&gt;微软（中国）下载中心首页&lt;/a&gt;的&lt;a href="http://www.microsoft.com/downloads/zh-cn/resultsForCategory.aspx?nr=50&amp;amp;sortOrder=Descending&amp;amp;sortCriteria=Date&amp;amp;period=30&amp;amp;stype=ss_nd&amp;amp;sterm=%e6%89%80%e6%9c%89%e7%b1%bb%e5%88%ab"&gt;最新下载&lt;/a&gt;栏目中已经提供了 &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=d2928bc1-f48c-4e95-a064-2a455a22c8f6&amp;amp;displayLang=zh-cn"&gt;ASP.NET MVC 3 中文语言包&lt;/a&gt;&amp;nbsp;的下载链接。&lt;/p&gt;&lt;p&gt;请大家注意，下载页面上并没有写清楚，但是提供的并不是完整的 ASP.NET MVC 3，仅仅是中文语言包，需要先安装 &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&amp;amp;FamilyID=d2928bc1-f48c-4e95-a064-2a455a22c8f6"&gt;&amp;ldquo;非本地化版的&amp;rdquo; ASP.NET MVC 3&lt;/a&gt; 才能使用。&lt;/p&gt;&lt;p&gt;除了 ASP.NET MVC 3 以外，从前几天开始微软就提供了另外几款免费 Web 平台产品的中文版下载，它们分别是：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=300314da-dedd-4540-a236-a0de0a5a534d&amp;amp;displayLang=zh-cn"&gt;Razor 页面/视图引擎 (ASP.NET Web Pages with Razor Syntax)&lt;/a&gt;；&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=5b9510a1-bc42-4323-90ab-adf4daaaa2f0&amp;amp;displayLang=zh-cn"&gt;WebMatrix&lt;/a&gt;；&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=32b0dfe5-f139-4e1c-b412-3da39f50bbf9&amp;amp;displayLang=zh-cn"&gt;Web 平台安装程序 (WebPI) 3.0&lt;/a&gt;；&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=abc59783-89de-4adc-b770-0a720bb21deb&amp;amp;displayLang=zh-cn"&gt;IIS 7.5 Express&lt;/a&gt;；&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=cfa66d50-90ce-49cb-b021-fefbd7a302ab&amp;amp;displayLang=zh-cn"&gt;Web 部署工具 (Web Deploy) 2.0&lt;/a&gt;。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;注：&lt;/p&gt;&lt;p&gt;安装 WebMatrix 以前请确保已经安装了 &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=32b0dfe5-f139-4e1c-b412-3da39f50bbf9&amp;amp;displayLang=zh-cn"&gt;WebPI&lt;/a&gt;、&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=abc59783-89de-4adc-b770-0a720bb21deb&amp;amp;displayLang=zh-cn"&gt;IIS 7.5 Express&lt;/a&gt; 和 &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=cfa66d50-90ce-49cb-b021-fefbd7a302ab&amp;amp;displayLang=zh-cn"&gt;Web Deploy&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;Razor 引擎的 Visual Studio 支持是包含在 ASP.NET MVC 3 中的，如果希望在编辑 Razor 模板时利用到 Visual Studio 的便利功能，就需要安装 &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=d2928bc1-f48c-4e95-a064-2a455a22c8f6&amp;amp;displayLang=zh-cn"&gt;ASP.NET MVC 3&lt;/a&gt;；但是 Razor 文档本身可以用任何文本编辑器进行编辑，只要安装了 &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=300314da-dedd-4540-a236-a0de0a5a534d&amp;amp;displayLang=zh-cn"&gt;Razor 引擎的独立安装版本&lt;/a&gt;，任何现有的 ASP.NET 网站都可以使用 Razor 文档（不包括使用 CodeBehind 模式的『ASP.NET 应用程序』项目&amp;mdash;&amp;mdash;这类的项目应该使用 ASPX 文档）。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;另外，&lt;a href="http://weblogs.asp.net/scottgu/archive/2011/01/13/announcing-release-of-asp-net-mvc-3-iis-express-sql-ce-4-web-farm-framework-orchard-webmatrix.aspx#7685211"&gt;Visual Studio 2010 Service Pack 1 应该会在几个星期以后推出&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; And can you tell when we will get Visual Studio 2010 Service Pack 1?&lt;/p&gt;&lt;p&gt;This will ship in a few more weeks.&lt;/p&gt;&lt;p&gt;Hope this helps,&lt;/p&gt;&lt;p&gt;Scott&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/1940784.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/01/21/asp-net-mvc-3-chs-released.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/01/19/KyuuBackground-rc-1.html</id><title type="text">悄悄地进村，打枪的不要——KyuuBackground(原 ItaBackgroundKyuu)改造完成</title><summary type="text">增加 OptionPage 支持花了不少时间，只有 OptionPage 是不行的，还得改变装饰物的实现好随时响应设置的变化。改造的过程中又发现一个之前没注意到的问题，改变缩放比例会导致背景图案错位……为了修正这个问题也花了好几个小时去研究，最后用了一些算不上太漂亮的办法让它勉勉强强看不出来。我把它扔到了 Visual Studio 资源库上，下载页面的链接是http://visualstudiogallery.msdn.microsoft.com/zh-cn/2d4f653f-262a-4d3a-b42c-c6f8e35e777e。技术细节什么的等精神好的时候再补吧。</summary><published>2011-01-18T18:24:00Z</published><updated>2011-01-18T18:24:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/01/19/KyuuBackground-rc-1.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/01/19/KyuuBackground-rc-1.html"/><content type="html">&lt;p&gt;增加 OptionPage 支持花了不少时间，只有 OptionPage 是不行的，还得改变装饰物的实现好随时响应设置的变化。&lt;/p&gt;&lt;p&gt;改造的过程中又发现一个之前没注意到的问题，改变缩放比例会导致背景图案错位&amp;hellip;&amp;hellip;为了修正这个问题也花了好几个小时去研究，最后用了一些算不上太漂亮的办法让它勉勉强强看不出来。&lt;/p&gt;&lt;p&gt;我把它扔到了 Visual Studio 资源库上，下载页面的链接是&amp;nbsp;&lt;a href="http://visualstudiogallery.msdn.microsoft.com/zh-cn/2d4f653f-262a-4d3a-b42c-c6f8e35e777e"&gt;http://visualstudiogallery.msdn.microsoft.com/zh-cn/2d4f653f-262a-4d3a-b42c-c6f8e35e777e&lt;/a&gt;&amp;nbsp;。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;技术细节什么的等精神好的时候再补吧。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/1938790.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/01/19/KyuuBackground-rc-1.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/01/17/lightyear-the-distance-light-travels-in-one-year.html</id><title type="text">光年：光走一年的距离</title><summary type="text">光年是距离单位，而非时间单位。但是“5000 万光年”的距离，光要走多久呢？</summary><published>2011-01-17T08:37:00Z</published><updated>2011-01-17T08:37:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/01/17/lightyear-the-distance-light-travels-in-one-year.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/01/17/lightyear-the-distance-light-travels-in-one-year.html"/><content type="html">&lt;p&gt;去年11约的时候 NASA 发布了个消息，说是发现了距离地球约 5000 万光年的黑洞，一个年仅 30 岁的黑洞。&lt;/p&gt;&lt;p&gt;然后这里面产生了一些有趣的问题&amp;mdash;&amp;mdash;有些人可能对这个笑话比较有印象：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一位游客游览史前古遗址时，发现一些恐龙化石，便问导游：&amp;ldquo;这些恐龙化石有多久的历史了？&amp;rdquo;&lt;/p&gt;&lt;p&gt;&amp;ldquo;一万万年零两天。&amp;rdquo;导游回答。&lt;/p&gt;&lt;p&gt;&amp;ldquo;你怎么这样肯定？&amp;rdquo;游客惊讶地问。&lt;/p&gt;&lt;p&gt;&amp;ldquo;因为前天，一位著名的考古学家认定它们已有一万万年的历史。&amp;rdquo;导游狡黠地答道。&lt;/p&gt;&lt;p&gt;这个笑话你可能听过其它的版本，不过别管它说的是几亿年还是几万年，笑话的笑点基本上是一样的：专家只能根据化石的特征来估计出一个大体的&amp;ldquo;年龄&amp;rdquo;，这个几万年也好几亿年也好只是个误差可能有千千万万年的近似值，在误差这么大的近似值上自作聪明地加上了精确的&amp;ldquo;两天&amp;rdquo;（别的版本也许是十个月）就显得太好笑了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;那么同样的，对于距离地球约 5000 万光年的黑洞来说，&amp;ldquo;年仅 30 岁&amp;rdquo;这样一个比较精确的数值也显得很可笑了。&lt;/p&gt;&lt;p&gt;&amp;ldquo;等一下！&amp;rdquo;有人看到这里人可能忍不住要有意见了：&amp;ldquo;&amp;lsquo;光年&amp;rsquo;是距离单位，不是时间单位！&amp;rdquo;&lt;/p&gt;&lt;p&gt;我知道有很多人看别人拿&amp;ldquo;5000 万光年&amp;rdquo;和&amp;ldquo;30 岁&amp;rdquo;什么的放在一起说的时候会有这种想法&amp;mdash;&amp;mdash;光年可是距离单位，你怎么能把它和时间相比较呢？&lt;/p&gt;&lt;p&gt;其实这么说的时候，忽略了一个很明显的问题：&amp;ldquo;光年&amp;rdquo;为什么叫做&amp;ldquo;光年&amp;rdquo;。&lt;/p&gt;&lt;p&gt;这个问题的答案也很简单，很浅显的道理：&amp;ldquo;光年&amp;rdquo;在字面上表示&amp;ldquo;以光速&amp;lsquo;行走&amp;rsquo;一年的距离&amp;rdquo;，那么实际上对于以光或者电磁波（光其实就是一种电磁波，你知道吗？）作为主要的天文观测手段的我们来说，&amp;ldquo;5000 万光年&amp;rdquo;也就意味着我们观察到的是&amp;ldquo;光从遥远的地方&amp;lsquo;行走&amp;rsquo;了 5000 万年之后给我们带来的景象&amp;rdquo;，简单点说，也就是&amp;ldquo;5000 万年以前的景象&amp;rdquo;。&lt;/p&gt;&lt;p&gt;当然了，实际上光年这个距离单位的定义和&amp;ldquo;光行走一年&amp;rdquo;是有点细微差别的，不过通常我们还是可以粗略地认为它们相同。&lt;/p&gt;&lt;p&gt;所以你看，&amp;ldquo;光年&amp;rdquo;的确是距离单位，但是从&amp;ldquo;5000 万光年&amp;rdquo;我们却可以知道我们所看到的是 5000 万年前的景象，这里并没有谁把&amp;ldquo;光年&amp;rdquo;当成了时间单位，只不过它隐含了距离和时间之间的关系，只要我们还依赖光作为观测手段，它就一直成立。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;而我在这里谈到&amp;ldquo;光年&amp;rdquo;和&amp;ldquo;光&amp;rdquo;和&amp;ldquo;年&amp;rdquo;的关系的问题，其实也想提醒同学们注意：&lt;/p&gt;&lt;p&gt;我们的身边是不是有这样的人？或者我们自己是不是也犯这样的错误？&lt;/p&gt;&lt;p&gt;过分地纠缠在一些细枝末节的表面问题上，却忽略掉了事物自身的内在联系？&lt;/p&gt;&lt;p&gt;我们有没有被微小的现象迷惑而没有看到问题的全貌，并因此作出错误的判断、错误的决定？&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;以前有过也好，以前没有过也好，希望大家都不要犯这样令人哭笑不得的错误。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;哦，关于&amp;ldquo;5000 万光年以外的 30 岁黑洞&amp;rdquo;的问题，其实这个&amp;ldquo;30 岁&amp;rdquo;作为比较精确的数值，是没有任何问题的&amp;mdash;&amp;mdash;科学家通过&amp;ldquo;5000 万光年以外的光&amp;rdquo;（具体来说是 X 射线之类的辐射现象）观察到的的确是年龄只有 30 岁的黑洞，尽管&amp;ldquo;5000 万光年&amp;rdquo;这个距离数值可能存在巨大的偏差，但射线跨越 5000 万光年为我们带来的关于黑洞的信息却是足够精确的。&lt;/p&gt;&lt;p&gt;问题只是在于，现有的语言里实在没有一个特别合适的描述这种情况的办法&amp;mdash;&amp;mdash;根本上的原因，还是我们的日常生活并不会经常跟 5000 万光年的距离之外的东西打交道，以至于有些像我这样的人从直觉上不能区分&amp;ldquo;5000 万年以前的景象&amp;rdquo;和&amp;ldquo;30 岁的黑洞&amp;rdquo;里时间精度所具备的不同含义，语言中缺乏描述方法也是因为这个原因。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;所以其实说到头来，像我这样因为&amp;ldquo;5000 万光年&amp;rdquo;而怀疑&amp;ldquo;30 岁&amp;rdquo;的精确性，也是有点让人哭笑不得的。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/1937544.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/01/17/lightyear-the-distance-light-travels-in-one-year.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/NanaLich/archive/2011/01/17/microsoft-web-platform-products-chs-released.html</id><title type="text">微软免费 Web 平台产品线中文版已部分上线</title><summary type="text">虽然 ASP.NET MVC 3 的中文版还没有发布，但是上次公布的 Web 平台产品中已经有五款发布了中文版本，现在大家就可以使用它们了！</summary><published>2011-01-17T03:39:00Z</published><updated>2011-01-17T03:39:00Z</updated><author><name>Nana's Lich</name><uri>http://www.cnblogs.com/NanaLich/</uri></author><link rel="alternate" href="http://www.cnblogs.com/NanaLich/archive/2011/01/17/microsoft-web-platform-products-chs-released.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/NanaLich/archive/2011/01/17/microsoft-web-platform-products-chs-released.html"/><content type="html">&lt;p&gt;几天之前 &lt;a href="http://weblogs.asp.net/scottgu/archive/2011/01/13/announcing-release-of-asp-net-mvc-3-iis-express-sql-ce-4-web-farm-framework-orchard-webmatrix.aspx"&gt;ScottGu 通过博文公布了包括 ASP.NET MVC 3、IIS Express、WebMatrix 在内的数种免费 Web 平台产品正式释出上线&lt;/a&gt;，不过比较可惜的是只发布了 ASP.NET MVC 3 的英文版，一时间大家还用不上中文版的 ASP.NET MVC 3。&lt;/p&gt;&lt;p&gt;不过在等待 ASP.NET MVC 3 中文版的过程中，意外地发现在微软（中国）下载中心的首页看到了一些 Web 平台产品的链接，调查之后发现前面提到的 Web 平台产品中已经有五款完成了中文化并提供下载，他们分别是：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=300314da-dedd-4540-a236-a0de0a5a534d&amp;amp;displayLang=zh-cn"&gt;Razor 页面/视图引擎 (ASP.NET Web Pages with Razor Syntax)&lt;/a&gt;；&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=5b9510a1-bc42-4323-90ab-adf4daaaa2f0&amp;amp;displayLang=zh-cn"&gt;WebMatrix&lt;/a&gt;；&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=32b0dfe5-f139-4e1c-b412-3da39f50bbf9&amp;amp;displayLang=zh-cn"&gt;Web 平台安装程序 (WebPI) 3.0&lt;/a&gt;；&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=abc59783-89de-4adc-b770-0a720bb21deb&amp;amp;displayLang=zh-cn"&gt;IIS 7.5 Express&lt;/a&gt;；&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=cfa66d50-90ce-49cb-b021-fefbd7a302ab&amp;amp;displayLang=zh-cn"&gt;Web 部署工具 (Web Deploy) 2.0&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;点击链接进入页面就可以下载到上述产品的中文版。&lt;/p&gt;&lt;p&gt;注：文件名中含有&amp;ldquo;amd64&amp;rdquo;的文件表示是面向 64 位 Windows 的版本，&amp;ldquo;amd64&amp;rdquo;含义同&amp;ldquo;x86-64&amp;rdquo;。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;另外在一般的&amp;ldquo;ASP.NET Web 应用程序&amp;rdquo;中使用 Razor 引擎的办法，好像也有人研究出来了，有兴趣的同学可以参考文章试试：&lt;a href="http://blog.joycode.com/saucer/archives/2011/01/15/116131.joy"&gt;http://blog.joycode.com/saucer/archives/2011/01/15/116131.joy&lt;/a&gt;&lt;/p&gt;&lt;p&gt;不过现在仍然不知道 ASP.NET MVC 3 的中文版要到什么时候才会释出，也许要等到 Visual Studio 2010 Service Pack 1 发布了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/NanaLich/aggbug/1937223.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/NanaLich/archive/2011/01/17/microsoft-web-platform-products-chs-released.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
