<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nocoo.Weblog &#187; 微软技术</title>
	<atom:link href="http://www.nocoo.us/category/microsoft-technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nocoo.us</link>
	<description>Professional, Passion and Patient</description>
	<lastBuildDate>Sun, 27 Jun 2010 09:55:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>如何关联Silverlight和ASP.NET项目</title>
		<link>http://www.nocoo.us/2009/11/silverlight-asp-net-build-link/</link>
		<comments>http://www.nocoo.us/2009/11/silverlight-asp-net-build-link/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 03:29:37 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=4097</guid>
		<description><![CDATA[用过Silverlight的兄弟都清楚，当在Visual Studio 2008中建立一个Silverlight Application Project时，首先会弹出一个提示框如上图，询问是否自动生成一个ASP.NET网站来托管这个Silverlight应用。默认会建立。一般情况下我们都会选择不建立，这样会在解决方案里少生成一个项目。 自动生成一个ASP.NET网站来托管这个Silverlight应用的好处是，在每次Debug整个解决方案的时候，Visual Studio 2008会自动首先编译Silverlight项目，然后把编译结果，一个xap文件，自动拷贝到ASP.NET网站项目的ClientBin下，然后启动ASP.NET网站项目的默认页面，显示了最新版本的Silverlight应用。如下图所示。 问题是，如果你一开始没有让Visual Studio 2008建立那个网站项目，如果哪天你需要一个网站了，可能是各种原因，比如需要一个本地的Web Service等等，自己新建一个ASP.NET网站，就不能实现上面的自动拷贝xap文件了。 解决方法比较绕。这是一个MSBuild问题，你需要Unload各个项目，然后用写字板打开ASP.NET的项目文件（csproj文件），然后在PropertyGroup中加一个SilverlightApplicationList项，如图： 注意相对路径，项目名称以及项目的GUID。这些东西都可以在解决方案文件（sln文件）里找到。就不详细解释了。 Reload项目之后Build，就会发现你的项目可以自动把xap文件拷贝到ClientBin下了。 后记：作为一个使用Silverlight开发了无数年的工程师，这似乎是我第一次写关于Silverlight的博文。现在想想，大概是公司政策使然？我应该是个很守规矩的人。]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.nocoo.us/wp-content/uploads/2009/11/silverlight-host.png" alt="silverlight-host" title="silverlight-host" width="447" height="265" class="alignnone size-full wp-image-4098" /></p>
<p>用过Silverlight的兄弟都清楚，当在Visual Studio 2008中建立一个Silverlight Application Project时，首先会弹出一个提示框如上图，询问是否自动生成一个ASP.NET网站来托管这个Silverlight应用。默认会建立。一般情况下我们都会选择不建立，这样会在解决方案里少生成一个项目。<br />
自动生成一个ASP.NET网站来托管这个Silverlight应用的好处是，在每次Debug整个解决方案的时候，Visual Studio 2008会自动首先编译Silverlight项目，然后把编译结果，一个xap文件，自动拷贝到ASP.NET网站项目的ClientBin下，然后启动ASP.NET网站项目的默认页面，显示了最新版本的Silverlight应用。如下图所示。</p>
<p><img src="http://www.nocoo.us/wp-content/uploads/2009/11/silverlight-host2.png" alt="silverlight-host2" title="silverlight-host2" width="293" height="372" class="alignnone size-full wp-image-4099" /></p>
<p>问题是，如果你一开始没有让Visual Studio 2008建立那个网站项目，如果哪天你需要一个网站了，可能是各种原因，比如需要一个本地的Web Service等等，自己新建一个ASP.NET网站，就不能实现上面的自动拷贝xap文件了。</p>
<p>解决方法比较绕。这是一个MSBuild问题，你需要Unload各个项目，然后用写字板打开ASP.NET的项目文件（csproj文件），然后在PropertyGroup中加一个SilverlightApplicationList项，如图：</p>
<p><a href="http://www.nocoo.us/wp-content/uploads/2009/11/silverlight-host3.png"><img src="http://www.nocoo.us/wp-content/uploads/2009/11/silverlight-host3-610x282.png" alt="silverlight-host3" title="silverlight-host3" width="610" height="282" class="alignnone size-large wp-image-4100" /></a></p>
<p>注意相对路径，项目名称以及项目的GUID。这些东西都可以在解决方案文件（sln文件）里找到。就不详细解释了。</p>
<p><img src="http://www.nocoo.us/wp-content/uploads/2009/11/silverlight-host4.png" alt="silverlight-host4" title="silverlight-host4" width="288" height="335" class="alignnone size-full wp-image-4101" /></p>
<p>Reload项目之后Build，就会发现你的项目可以自动把xap文件拷贝到ClientBin下了。</p>
<p><strong>后记：</strong>作为一个使用Silverlight开发了无数年的工程师，这似乎是我第一次写关于Silverlight的博文。现在想想，大概是公司政策使然？我应该是个很守规矩的人。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/11/silverlight-asp-net-build-link/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>好吧，我承认只有我才会发现这样的小问题</title>
		<link>http://www.nocoo.us/2009/09/silverlight-comment-error/</link>
		<comments>http://www.nocoo.us/2009/09/silverlight-comment-error/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 13:47:27 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=4028</guid>
		<description><![CDATA[public sealed class ScrollViewer : ContentControl // // Summary: // Gets a value that represents the horizontal size of the area that can be // scrolled; the difference between the width of the extent and the width of // the viewport.. // // Returns: // The horizontal size of the area that can be scrolled. [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.nocoo.us/wp-content/uploads/2009/09/c-sharp-comment.png" alt="c-sharp-comment" title="c-sharp-comment" width="600" height="242" class="alignnone size-full wp-image-4030" /></p>
<p><strong>public sealed class ScrollViewer : ContentControl</strong></p>
<pre class="brush: csharp">
//
// Summary:
//     Gets a value that represents the horizontal size of the area that can be
//     scrolled; the difference between the width of the extent and the width of
//     the viewport..
//
// Returns:
//     The horizontal size of the area that can be scrolled. This property has no
//     default value.
public double ScrollableWidth { get; internal set; }
</pre>
<p>Silverlight Control里面的小细节，小小小细节&#8230;<br />
好几篇这样的文章了，以后学着粗枝大叶一点，产品中的这些小细节太让我恼火了。</p>
<p>补充几句，觉得C#里面的注释写得太像八股文了。最近写了好多好多，现在随便开个东西开始无意识输出的是“Gets or sets a value indicating whether&#8230;”。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/09/silverlight-comment-error/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>安装SP1导致的Microsoft Office Setup Assistant死循环问题</title>
		<link>http://www.nocoo.us/2009/04/mac-os-x-microsoft-office-setup-assistant-loop/</link>
		<comments>http://www.nocoo.us/2009/04/mac-os-x-microsoft-office-setup-assistant-loop/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 16:00:11 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[Mac OS]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3796</guid>
		<description><![CDATA[问题 在我的Mac OS X 10.5.6中,通过自动升级安装Microsoft Office 2008 for Mac的SP1后,再次打开任意Office程序时,都会出现一个Microsoft Office Setup Assistant: 问题是下一步通过这个窗口后,都会弹出Mirosoft Autoupdate升级窗口: 在这里,任何选择最终都会关闭这个窗口.然后再次点击Office的任意程序,循环重新开始上面的过程. 解决 删除这两个文件: /Users/username/Library/Preferences/Microsoft/Office 2008/Microsoft Office 2008 settings.plist /Applications/Microsoft Office 2008/Office/OfficePID.plist 删除这两个文件后,再次打开Office程序时会要求重新输入用户名,单位名和序列号,但是通过后就可以正常使用了.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.nocoo.us/wp-content/uploads/2009/04/picture-6.png" alt="picture-6" title="picture-6" width="530" height="340" class="alignnone size-full wp-image-3799" /></p>
<h3>问题</h3>
<p>在我的Mac OS X 10.5.6中,通过自动升级安装Microsoft Office 2008 for Mac的SP1后,再次打开任意Office程序时,都会出现一个Microsoft Office Setup Assistant:</p>
<p><img src="http://www.nocoo.us/wp-content/uploads/2009/04/picture-1-600x445.png" alt="picture-1" title="picture-1" width="600" height="445" class="alignnone size-large wp-image-3797" /></p>
<p>问题是下一步通过这个窗口后,都会弹出Mirosoft Autoupdate升级窗口:</p>
<p><img src="http://www.nocoo.us/wp-content/uploads/2009/04/picture-2-600x379.png" alt="picture-2" title="picture-2" width="600" height="379" class="alignnone size-large wp-image-3798" /></p>
<p>在这里,任何选择最终都会关闭这个窗口.然后再次点击Office的任意程序,循环重新开始上面的过程.</p>
<h3>解决</h3>
<p>删除这两个文件:<br />
<strong>/Users/username/Library/Preferences/Microsoft/Office 2008/Microsoft Office 2008 settings.plist</strong><br />
<img src="http://www.nocoo.us/wp-content/uploads/2009/04/picture-4.png" alt="picture-4" title="picture-4" width="474" height="456" class="alignnone size-full wp-image-3802" /></p>
<p><strong>/Applications/Microsoft Office 2008/Office/OfficePID.plist</strong></p>
<p><img src="http://www.nocoo.us/wp-content/uploads/2009/04/picture-3.png" alt="picture-3" title="picture-3" width="345" height="469" class="alignnone size-full wp-image-3800" /></p>
<p>删除这两个文件后,再次打开Office程序时会要求重新输入用户名,单位名和序列号,但是通过后就可以正常使用了.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/04/mac-os-x-microsoft-office-setup-assistant-loop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>6个常见的IE渲染Bug及其修复方法</title>
		<link>http://www.nocoo.us/2009/04/ie-bugs/</link>
		<comments>http://www.nocoo.us/2009/04/ie-bugs/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 16:01:55 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[Web标准化研究]]></category>
		<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[Microsoft]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3721</guid>
		<description><![CDATA[1. size,padding和margin距离异常 在IE6中,各种size,padding和margin总是感觉怪怪的,有时候死活差那么几个像素.这时候可以使用单独为IE准备的CSS文件来纠正.只需要在页面头部加类似这样的CSS文件即可: &#60;!--[if IE 6]&#62; &#60;link rel=&#34;stylesheet&#34; href=&#34;css/ie6.css&#34; type=&#34;text/css&#34; media=&#34;screen&#34; /&#62; &#60;![EndIf]--&#62; 其中的ie.css是对主CSS文件中,那些在IE6下显示异常的元素,重新定义的CSS. 2. 块元素居中问题 在现代浏览器中,一个块元素,假设是一个p,设置了宽度,设置左右margin都是auto之后,渲染效果应该是居中.但是在IE中,必须对其父元素,假设是body,加text-align:center;才能看到居中效果: body { text-align: center; } 并且,你还要在子元素p里把继承的居中纠正回来: p { text-align: left; } 3. div最小高度不能低于12px的bug 如果你需要一个高度很小的div,假设说做一个分隔线之类,你会发现div最小高度不会低于12px.这时候要设置div的line-height: 0;才行. &#60;div style=&#34;line-height: 0px; height: 2px;&#34;&#62;&#60;/div&#62; 如果还是不行,你要在div里套一个p,并且指定这个p的line-height: 0;. &#60;div style=&#34;height: 2px;&#34;&#62;&#60;p style=&#34;line-height: 0px;&#34;&#62;&#60;/p&#62;&#60;/div&#62; 4. 浮动元素的双倍margin距离bug 这是一个非常严重的bug.你会发现你的侧边栏总会跑到第二行去显示,或者明明你计算好宽度,平分两半,还预留了些空隙,在Firefox显示正常,在屏幕左右分布的两个块元素,在IE下非换行不可.说起来应当是IE的float块元素,margin加倍渲染的bug. 这样的代码: .floatbox { float: left; width: 150px; height: [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.nocoo.us/wp-content/uploads/2009/04/ie-bug.jpg" alt="ie-bug" title="ie-bug" width="550" height="143" class="alignnone size-full wp-image-3722" /></p>
<h3>1. size,padding和margin距离异常</h3>
<p>在IE6中,各种size,padding和margin总是感觉怪怪的,有时候死活差那么几个像素.这时候可以使用单独为IE准备的CSS文件来纠正.只需要在页面头部加类似这样的CSS文件即可:</p>
<pre class="brush: html">
&lt;!--[if IE 6]&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;css/ie6.css&quot; type=&quot;text/css&quot; media=&quot;screen&quot; /&gt;
&lt;![EndIf]--&gt;
</pre>
<p>其中的ie.css是对主CSS文件中,那些在IE6下显示异常的元素,重新定义的CSS.</p>
<h3>2. 块元素居中问题</h3>
<p>在现代浏览器中,一个块元素,假设是一个p,设置了宽度,设置左右margin都是auto之后,渲染效果应该是居中.但是在IE中,必须对其父元素,假设是body,加text-align:center;才能看到居中效果:</p>
<pre class="brush: css">body { text-align: center; }</pre>
<p>并且,你还要在子元素p里把继承的居中纠正回来:</p>
<pre class="brush: css">p { text-align: left; }</pre>
<h3>3. div最小高度不能低于12px的bug</h3>
<p>如果你需要一个高度很小的div,假设说做一个分隔线之类,你会发现div最小高度不会低于12px.这时候要设置div的line-height: 0;才行.</p>
<pre class="brush: html">&lt;div style=&quot;line-height: 0px; height: 2px;&quot;&gt;&lt;/div&gt;</pre>
<p>如果还是不行,你要在div里套一个p,并且指定这个p的line-height: 0;.</p>
<pre class="brush: html">&lt;div style=&quot;height: 2px;&quot;&gt;&lt;p style=&quot;line-height: 0px;&quot;&gt;&lt;/p&gt;&lt;/div&gt;</pre>
<h3>4. 浮动元素的双倍margin距离bug</h3>
<p>这是一个非常严重的bug.你会发现你的侧边栏总会跑到第二行去显示,或者明明你计算好宽度,平分两半,还预留了些空隙,在Firefox显示正常,在屏幕左右分布的两个块元素,在IE下非换行不可.说起来应当是IE的float块元素,margin加倍渲染的bug.<br />
这样的代码:</p>
<pre class="brush: css">
.floatbox {
   float: left;
   width: 150px;
   height: 150px;
   margin: 5px 0 5px 100px;
   /*This last value applies the 100px left margin */
}
</pre>
<p>正确的渲染应该是这样:</p>
<p><img src="http://www.nocoo.us/wp-content/uploads/2009/04/marg-norm.gif" alt="marg-norm" title="marg-norm" width="504" height="166" class="alignnone size-full wp-image-3724" /></p>
<p>但是在IE5和IE6里,margin的100px被加倍,渲染成这个样子:</p>
<p><img src="http://www.nocoo.us/wp-content/uploads/2009/04/marg-doubled.gif" alt="marg-doubled" title="marg-doubled" width="504" height="166" class="alignnone size-full wp-image-3725" /></p>
<p>margin被加倍成了200px.<br />
浮动元素的双倍margin距离bug的出现条件和特点是:</p>
<ol>
<li>float块元素</li>
<li>margin方向与float方向相同,即float: left;的块只会加倍margin-left的值.</li>
<li>这个float块与其父容器的内边之间夹着这个margin的情况下,才会加倍.当前行的第二个float块,因为其左边不是父容器的内边,就不会出现这个bug.</li>
<li>浮动元素的双倍margin距离bug具备左右对称性.</li>
</ol>
<p>修复很简单,在所有float的元素的CSS中加入<strong>display: inline;</strong>即可.其实根据W3C对float的定义,当float具备left或者right时,display效果应当是<strong>不起作用的</strong>,除非是display: none;,但是指定了display: inline;确实让IE6正确显示了margin.</p>
<h3>5. 盒模型的bug</h3>
<p>看这样一段代码:</p>
<pre class="brush: css">
div#box {
   width: 100px;
   border: 2px solid black;
   padding: 10px;
}
</pre>
<p>根据盒模型定义,这个div的宽度应该是2+10+100+10+2=124px.大部分浏览器也是这样解析的,唯独IE6认为它是100px宽.<br />
这个bug会对布局带来严重影响.消除这个bug只需要在页首制定DTD即可.</p>
<pre class="brush: html">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</pre>
<p>此前的一篇文章这样解释:在页首制定了DTD,浏览器就认定Web开发者知道并理解DTD,于是就会使用兼容标准的方式来解析和渲染页面.</p>
<h3>6. PNG图片不能透明bug</h3>
<p>在IE6中,PNG图片原本透明的部分被渲染成不透明的颜色.可以使用<a href="http://css-tricks.com/the-different-techniques-for-applying-the-png-hack/">这篇文章</a>提到的办法修复之.<br />
其实这个bug只会出现在设置为alpha透明方式的png图片上,导引色透明方式在IE6中则不会出现不能透明的bug.</p>
<p>参考资料</p>
<ul>
<li><a href="http://www.positioniseverything.net/explorer/doubled-margin.html">The IE5/6 Doubled Float-Margin Bug</a></li>
<li><a href="http://www.wipeout44.com/brain_food/css_ie_bug_fixes.asp">Internet Explorer CSS bug fixes</a></li>
<li><a href="http://css-tricks.com/ie-css-bugs-thatll-get-you-every-time/">IE CSS Bugs That’ll Get You Every Time</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/04/ie-bugs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft STBC HPC面试</title>
		<link>http://www.nocoo.us/2009/03/microsoft-stbc-hpc-interview/</link>
		<comments>http://www.nocoo.us/2009/03/microsoft-stbc-hpc-interview/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 07:38:11 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[微软技术]]></category>
		<category><![CDATA[心情日记]]></category>
		<category><![CDATA[Microsoft]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3625</guid>
		<description><![CDATA[寒假的时候让杨光帮我投了下简历，然后过了一阵子就组织面试了。说起来比较神奇，之前我在joinms里自己投过简历，没多久就收到STBC的HR写来的written test通知，我延了一次，第二次约好的时间因为和杨光介绍过去的STBC HPC的电话面试时间冲突，被我拒掉了&#8230;神奇的是，当STBC HPC电话面试结束后，收到的却是之前写来written test通知的同一个HR发来的on site面试通知&#8230;岂不是给人一种错觉：Microsoft的written test通知直接无视即可获得面试机会，呵呵。 Anyway，STBC是一个很远的地方，我九点半出门，约好下午一点面试，我觉得肯定够用了，说不定还能找个KFC吃顿像样的饭，没想到当我最终赶到，是12点50分&#8230; 饿着肚子面试一下午，三个FTE（最后一个是STBC HPC组的一个PM），每人一小时，当我回到学校的时候已经是晚上7点，一天被占用掉了～ 面试过程&#8230;没什么好说的，实验室这边不见得会放我走，所以我去的时候是抱着面着玩的心态去的，无欲无求我就很放松，所以一点也不紧张。第二个小伙是个复旦的帅哥，被他一阵鄙视算法，无奈了，还是继续加油吧&#8230; 不过收获总是有的，至少我知道了别人是怎么看待我的简历的，他们注意些什么，不注意些什么，看来简历要大改了～]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.nocoo.us/wp-content/uploads/2009/03/hpc_headers_04_sl.jpg" alt="hpc_headers_04_sl" title="hpc_headers_04_sl" width="610" height="127" class="alignnone size-full wp-image-3626" /></p>
<p>寒假的时候让杨光帮我投了下简历，然后过了一阵子就组织面试了。说起来比较神奇，之前我在joinms里自己投过简历，没多久就收到STBC的HR写来的written test通知，我延了一次，第二次约好的时间因为和杨光介绍过去的STBC HPC的电话面试时间冲突，被我拒掉了&#8230;神奇的是，当STBC HPC电话面试结束后，收到的却是之前写来written test通知的同一个HR发来的on site面试通知&#8230;岂不是给人一种错觉：Microsoft的written test通知直接无视即可获得面试机会，呵呵。<br />
Anyway，STBC是一个很远的地方，我九点半出门，约好下午一点面试，我觉得肯定够用了，说不定还能找个KFC吃顿像样的饭，没想到当我最终赶到，是12点50分&#8230;<br />
饿着肚子面试一下午，三个FTE（最后一个是STBC HPC组的一个PM），每人一小时，当我回到学校的时候已经是晚上7点，一天被占用掉了～<br />
面试过程&#8230;没什么好说的，实验室这边不见得会放我走，所以我去的时候是抱着面着玩的心态去的，无欲无求我就很放松，所以一点也不紧张。第二个小伙是个复旦的帅哥，被他一阵鄙视算法，无奈了，还是继续加油吧&#8230;<br />
不过收获总是有的，至少我知道了别人是怎么看待我的简历的，他们注意些什么，不注意些什么，看来简历要大改了～</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/03/microsoft-stbc-hpc-interview/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[译作]新白宫网站代码分析</title>
		<link>http://www.nocoo.us/2009/01/whitehousegov-website-code/</link>
		<comments>http://www.nocoo.us/2009/01/whitehousegov-website-code/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 08:01:55 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[Web标准化研究]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[开发心得]]></category>
		<category><![CDATA[影音娱乐]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[微软]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3499</guid>
		<description><![CDATA[概述. 在美国第44任总统就职日这个历史性的日子，让我们来分析一下新的白宫网站（whitehouse.gov）代码结构吧。网站基于ASP.NET构建。 [singlepic=18466] whitehouse.gov网站使用IIS 6.0. 网站的HTTP头信息中包含键值对&#8221;Server: Microsoft-IIS/6.0&#8243;。网站并没有使用微软公司最新版本服务器软件，IIS/7。 whitehouse.gov网站使用ASP.NET 2.0. HTTP头中标识自己的程序版本为&#8221;X-Aspnet-Version: 2.0.50727&#8243;。这个信息可以去掉，这样可以为每次服务器响应节省30字节带宽。 whitehouse.gov网站使用JQuery 1.2.6. JQuery JavaScript库，使用了其最小集版本，位于/includes/文件夹下。很多开发者使用Google服务器托管的JQuery以便提升性能和减小下载脚本的延迟时间。这样做可以提升站点性能。 &#60;script type="text/javascript" src="/includes/eop/jquery-1.2.6.min.js"&#62;&#60;/script&#62; whitehouse.gov网站使用GZIP压缩. 所有网站文本都采用了GZIP压缩，显著地提升了性能。 未压缩大小: 48218 bytes 压缩后大小: 8370 bytes 节省带宽: ~80% whitehouse.gov网站使用Vary: Accept-Encoding. 在HTTP头中添加Vary: Accept-Encoding是一种强制代理不向不能解码GZIP的客户端发送GZIP内容的手段。 whitehouse.gov网站使用Cache-Control: private和max-age. 它使用了&#8221;max-age=85895&#8220;，大约1 天。这样，html页面应该只会在你的计算机中缓存1天。 whitehouse.gov网站使用Web Trends Live追踪技术. WebTrends声称是“领先的网页分析和客户为中心智能市场营销解决方案（leading provider of web analytics and consumer-centric marketing intelligence solutions）。” whitehouse.gov网站使用meta keywords标记. 这样做很奇怪，因为Internet上的访问者很少有不知道这里是干什么的。meta标记如下： &#60;meta name="keywords" content="President, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>概述.</strong> 在美国第44任总统就职日这个历史性的日子，让我们来分析一下新的白宫网站（<strong>whitehouse.gov</strong>）代码结构吧。网站基于ASP.NET构建。</p>
<p>[singlepic=18466]</p>
<p><strong>whitehouse.gov网站使用IIS 6.0.</strong> 网站的HTTP头信息中包含键值对&#8221;Server: Microsoft-IIS/6.0&#8243;。网站并没有使用微软公司最新版本服务器软件，IIS/7。</p>
<p><strong>whitehouse.gov网站使用ASP.NET 2.0.</strong> HTTP头中标识自己的程序版本为&#8221;X-Aspnet-Version: 2.0.50727&#8243;。这个信息可以去掉，这样可以为每次服务器响应节省30字节带宽。</p>
<p><strong>whitehouse.gov网站使用JQuery 1.2.6.</strong> JQuery JavaScript库，使用了其最小集版本，位于<em>/includes/</em>文件夹下。很多开发者使用Google服务器托管的JQuery以便提升性能和减小下载脚本的延迟时间。这样做可以提升站点性能。</p>
<pre>&lt;script type="text/javascript" src="/includes/eop/jquery-1.2.6.min.js"&gt;&lt;/script&gt;</pre>
<p><strong>whitehouse.gov网站使用GZIP压缩.</strong> 所有网站文本都采用了GZIP压缩，显著地提升了性能。</p>
<pre>未压缩大小:  48218 bytes
压缩后大小:   8370 bytes
节省带宽:           ~80%</pre>
<p><strong>whitehouse.gov</strong><strong>网站</strong><strong>使用<em>Vary: Accept-Encoding</em>.</strong> 在HTTP头中添加Vary: Accept-Encoding是一种强制代理不向不能解码GZIP的客户端发送GZIP内容的手段。</p>
<p><strong>whitehouse.gov</strong><strong>网站使用</strong><strong><em>Cache-Control: private</em>和<em>max-age</em>.</strong> 它使用了&#8221;<em>max-age=85895</em>&#8220;，大约<em>1</em> 天。这样，html页面应该只会在你的计算机中缓存1天。</p>
<p><strong>whitehouse.gov网站使用Web Trends Live追踪技术.</strong> WebTrends声称是“领先的网页分析和客户为中心智能市场营销解决方案（leading provider of web analytics and consumer-centric marketing intelligence solutions）。”</p>
<p><strong>whitehouse.gov网站使用<em>meta</em> keywords标记.</strong> 这样做很奇怪，因为Internet上的访问者很少有不知道这里是干什么的。meta标记如下：</p>
<pre>&lt;meta name="keywords" content="President, Barack Obama, White House,
United States of America, 44th President, White House history, President Obama,
Barck, Barek, Barak, Barrack, Barrak, Obma, Barack" /&gt;</pre>
<p><strong>这样并不会对提升</strong><strong>whitehouse.gov</strong><strong>网站的Google PageRank有多少贡献。</strong>我认为搜索Barack Obama的用户无论如何都会被导引到这个网站的。</p>
<p><strong>whitehouse.gov网站使用<em>ViewState</em>.</strong> 这是一个隐藏表单，允许网站在浏览器中存储服务器端数据。ASP.NET自动解析发送到浏览器的<em>ViewState</em>信息。浏览器不应该解析这个信息。</p>
<p><strong>whitehouse.gov网站使用<em>WebResource.axd</em>.</strong> 这是ASP.NET生成的一个脚本文件。通常它们不能被有效地缓存，并且我发现它们的确降低了性能。</p>
<p><strong>whitehouse.gov网站包含了很多空白字符.</strong> 如果你的浏览器启用了GZIP，这并不会带来性能影响，但是如果去掉这些空白字符，网站代码可以减小20%以上。</p>
<p><strong>whitehouse.gov网站包含注释标签.</strong> 网站使用了很多HTML注释分割页面代码区域。如果能将这些注释写在服务器端代码中，可以在编译页面时不将注释编译在最终页面代码中，从而提升效率。</p>
<pre><em>&lt;!-- Start --&gt;
&lt;!-- End --&gt;</em></pre>
<p><strong>whitehouse.gov网站包含很长很长的ASP.NET <em>ID</em>.</strong> 页面中的很多元素包含非常长的ID，是浪费带宽的主要因素之一。这些长ID可以很容易地在服务器端替换成短ID。</p>
<pre>&lt;a id="ctl09_rptNavigation_ctl00_rptNavigationItems_ctl01_hlSubNav"...</pre>
<p><strong>whitehouse.gov网站使用的GIF多于PNG.</strong> 网站使用的GIF图片多于PNG图片。PNG格式的图片可以更加优化，从而节省带宽和消耗。网站中使用了两个GIF动画。</p>
<p><strong>whitehouse.gov网站使用了<em>5</em>个层叠式样式表（stylesheets）文件和<em>12</em>个JavaScripts脚本文件.</strong> 如果能把这两类文件合并成两个文件，网站可以更快而且更轻量级。当然这是针对访问首页的访客而言。奇怪的是，用于修饰管理页面的层叠式样式表也被加载进了普通用户的访问中：</p>
<pre><em>/* admin styles */
/* cms */</em>
.adminNavigation {width:996px; position:relative; z-index:100;}</pre>
<p><strong>whitehouse.gov网站使用了高度压缩的JPG.</strong> 如果你距离屏幕较远，或者视力不是那么好，这些图片看起来还行。开发者对JPG图片采用了高度压缩。这里显示的图片被放大并且轻微地二次压缩过。</p>
<p>[singlepic=18465]</p>
<p><strong>whitehouse.gov网站使用了image sprites技术.</strong> 这项技术可以大幅提升站点性能，因为它将若干个小图片合并成了一张图片。这是一项先进的技术。采用了image sprites技术的图片是&#8221;<em>nav-sprite.png</em>&#8220;.</p>
<p><strong>whitehouse.gov网站使用了Packer.</strong> Dean Edward的Packer是一个用于压缩JavaScript文件的工具。JavaScript脚本将在被下载时自动解压缩，这是一项很差的优化手段， 因为往往JavaScript经过GZIP压缩之后，比经过YUI压缩器（YUI Compressor）压缩之后更小。<small>[参见 jquery-plugins.js]</small></p>
<pre>eval(function(p,a,c,k,e,d)...</pre>
<p><strong>使用Packer的决定</strong>不像是一个深入了解GZIP或者文本压缩技术的人做出的。压缩之前的文件确实变小了，然而这导致了最终需要被下载的文件变大了。<small>[http://dean.edwards.name/packer/]</small></p>
<p><strong>whitehouse.gov大小</strong><em>821 KB</em>， 在我的线路上（cable modem）使用了<em>1.58</em>秒完成加载。这个数字大约是新的、基于图片的网站的平均值。</p>
<pre>加载时间:  1.58 seconds
总计大小:  821 KB</pre>
<p><strong>whitehouse.gov网站包含了几个隐藏链接.</strong> 在源文件里，大部分是在JavaScript中，大约嵌入了<em>6</em>个链接。这样，这些幸运的人就得到了来自白宫网站的外链（译者注：PageRank 9啊！9！）。</p>
<pre>www.youngpup.net

http://sorgalla.com/jcarousel/

http://billwscott.com/carousel/

http://www.codylindley.com</pre>
<p><strong>whitehouse.gov网站使用了一个不透明的favicon.ico.</strong> 为了站点在加入书签后具有更好的视觉效果（译者注：对很多非IE浏览器而言，无论是否加入书签，favicon文件都会显示在标签栏），一个具有透明背景的favicon是更好的选择。这项改变对于一个知道怎么修改的人来说可以在10分钟内完成。</p>
<p><strong>结论是，</strong>whitehouse.gov网站还是很吸引人的。虽然它并不算是一个非常有效率的站点，并且过多地注意了视觉效果。一个网站优化专家可以在几天之内将它的加载速度提升到现在的两倍。<small></small></p>
<p><strong>最后，记住本届政府和奥巴马总统并不是写这些代码的人。</strong></p>
<p><strong>翻译自：</strong><a href="http://dotnetperls.com/Content/whitehouse-gov-Site.aspx">http://dotnetperls.com/Content/whitehouse-gov-Site.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/whitehousegov-website-code/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Let&#8217;s Start From Here</title>
		<link>http://www.nocoo.us/2009/01/lets-start-from-here/</link>
		<comments>http://www.nocoo.us/2009/01/lets-start-from-here/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 07:50:53 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[影音娱乐]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[行摄]]></category>
		<category><![CDATA[资料文献]]></category>
		<category><![CDATA[歌曲]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3490</guid>
		<description><![CDATA[A little jazz, help you to move on. Let&#8217;s Start From Here 王若琳 giving up, why should i we&#8217;ve come to far to forget we&#8217;re beautiful, we just got lost somewhere along the way so much was missing when you went away let&#8217;s start from here, lose the past change our minds, we don&#8217;t need [...]]]></description>
			<content:encoded><![CDATA[<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="624" height="520"><param name="movie" value="http://player.youku.com/player.php/sid/XMTg2OTg5OTY=/v.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#FFFFFF" /><object data="http://player.youku.com/player.php/sid/XMTg2OTg5OTY=/v.swf" width="624" height="520" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="bgcolor" value="#FFFFFF" /><param name="pluginurl" value="http://www.macromedia.com/go/getflashplayer" /></object></object></p>
<blockquote><p>A little jazz, help you to move on.</p></blockquote>
<blockquote><p><strong>Let&#8217;s Start From Here</strong><br />
<em>王若琳</em><br />
giving up, why should i<br />
we&#8217;ve come to far to forget<br />
we&#8217;re beautiful, we just got lost<br />
somewhere along the way<br />
so much was missing when you went away<br />
let&#8217;s start from here, lose the past<br />
change our minds, we don&#8217;t need a finish line<br />
let&#8217;s take this chance don&#8217;t think too deep<br />
and all those promises we couldn&#8217;t seem to keep<br />
i don&#8217;t care where we go<br />
let&#8217;s start from here<br />
standing here face to face<br />
a finger on your lips<br />
don&#8217;t say a word don&#8217;t make a sound<br />
silence surrounds us now<br />
even when you were gone i felt you everywhere<br />
let&#8217;s start from here, lose the past<br />
change our minds, we don&#8217;t need a finish line<br />
let&#8217;s take this chance don&#8217;t think too deep<br />
and all those promises we couldn&#8217;t seem to keep<br />
i don&#8217;t care where we go<br />
let&#8217;s start from here<br />
let&#8217;s start from here<br />
i&#8217;ve never been the one to open up<br />
but you&#8217;ve always been the voive within<br />
the only warmth from my cold heart<br />
let&#8217;s start from here, lose the past<br />
change our minds, we don&#8217;t need a finish line<br />
let&#8217;s take this chance don&#8217;t think too deep<br />
and all those promises<br />
let&#8217;s start from here, lose the past<br />
change our minds<br />
we don&#8217;t need a finish line<br />
let&#8217;s take this chance don&#8217;t think too deep<br />
and all those promises we couldn&#8217;t seem to keep<br />
i don&#8217;t care where we go<br />
let&#8217;s start from here<br />
let&#8217;s start from here<br />
let&#8217;s start from here<br />
let&#8217;s start from here</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/lets-start-from-here/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>验证视图状态MAC失败的原因</title>
		<link>http://www.nocoo.us/2009/01/viewstateexception/</link>
		<comments>http://www.nocoo.us/2009/01/viewstateexception/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 03:01:44 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3433</guid>
		<description><![CDATA[“/”应用程序中的服务器错误。 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载，请确保&#60;machineKey&#62;配置指定了相同的validationKey和验证算法。不能在群集中使用AutoGenerate。 概括地说，就是POST执行时引起的“验证视图状态MAC失败”错误。 原因很简单：当你想使用传统POST提交信息到另一个aspx页面时出现这个错误。如果提交的action是本页面则不会出错。 解决方案：也很简单，去掉form中的runat=&#8221;server&#8221;即可。]]></description>
			<content:encoded><![CDATA[<blockquote><p>
<strong>“/”应用程序中的服务器错误。</strong><br />
验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载，请确保&lt;machineKey&gt;配置指定了相同的validationKey和验证算法。不能在群集中使用AutoGenerate。
</p></blockquote>
<p>概括地说，就是POST执行时引起的“验证视图状态MAC失败”错误。<br />
<strong>原因很简单：</strong>当你想使用传统POST提交信息到另一个aspx页面时出现这个错误。如果提交的action是本页面则不会出错。<br />
<strong>解决方案：</strong>也很简单，去掉form中的runat=&#8221;server&#8221;即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/viewstateexception/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>符合标准的TreeView实现(Div+CSS+JS+ASP.NET)</title>
		<link>http://www.nocoo.us/2009/01/standard-treeview/</link>
		<comments>http://www.nocoo.us/2009/01/standard-treeview/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 01:02:46 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[Web标准化研究]]></category>
		<category><![CDATA[作品发布]]></category>
		<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3428</guid>
		<description><![CDATA[这几天有点小活，要求是ASP.NET的，虽然我不怎么看好ASP.NET，但是人家要求了我也就照做吧。 最复杂的部分是一个TreeView。出于兼容性和简单性考虑没有用ASP.NET的TreeView控件，而是参考一篇文章自行写了一个出来。 [singlepic=18460] 技术指标如下： 实现：Div+CSS+JavaScript+ASP.NET(C#) 功能：可以实现无限级的TreeNode 标准：在IE 7和Firefox 3.1下显示效果相同，兼容XHTML 1.0 Strict最严格的网页标准 效果如左图所示。最后一个函数可能会因为超宽看不到全部，具体请参照文章附件中的源代码。 附件下载：http://download.nocoo.us/Download/Archive/TreeViewCode.rar TreeNode.cs /// &#60;summary&#62; /// TreeView结点类 /// &#60;/summary&#62; public class TreeNode { private string name; private string href; private List&#60;TreeNode&#62; subNodes = new List&#60;TreeNode&#62;(); /// &#60;summary&#62; /// 结点名 /// &#60;/summary&#62; public string Name { get { return name; } } /// &#60;summary&#62; /// [...]]]></description>
			<content:encoded><![CDATA[<p>这几天有点小活，要求是ASP.NET的，虽然我不怎么看好ASP.NET，但是人家要求了我也就照做吧。<br />
最复杂的部分是一个TreeView。出于兼容性和简单性考虑没有用ASP.NET的TreeView控件，而是参考<a href="http://www.cnblogs.com/FrankChen/archive/2008/03/26/1122936.html">一篇文章</a>自行写了一个出来。</p>
<p>[singlepic=18460]</p>
<p>技术指标如下：</p>
<ul>
<li><strong>实现：</strong>Div+CSS+JavaScript+ASP.NET(C#)</li>
<li><strong>功能：</strong>可以实现无限级的TreeNode</li>
<li><strong>标准：</strong>在IE 7和Firefox 3.1下显示效果相同，兼容XHTML 1.0 Strict最严格的网页标准</li>
</ul>
<p>效果如左图所示。<strong>最后一个函数可能会因为超宽看不到全部，具体请参照文章附件中的源代码。</strong><br />
<strong>附件下载：</strong><a href="http://download.nocoo.us/Download/Archive/TreeViewCode.rar">http://download.nocoo.us/Download/Archive/TreeViewCode.rar</a></p>
<h3>TreeNode.cs</h3>
<pre class="brush: c#">
/// &lt;summary&gt;
/// TreeView结点类
/// &lt;/summary&gt;
public class TreeNode
{
    private string name;
    private string href;
    private List&lt;TreeNode&gt; subNodes = new List&lt;TreeNode&gt;();

    /// &lt;summary&gt;
    /// 结点名
    /// &lt;/summary&gt;
    public string Name { get { return name; } }
    /// &lt;summary&gt;
    /// 结点链接
    /// &lt;/summary&gt;
    public string Href { get { return href; } }
    /// &lt;summary&gt;
    /// 下级结点个数
    /// &lt;/summary&gt;
    public int Count { get { return this.subNodes.Count; } }
    /// &lt;summary&gt;
    /// 获取或者设置下级结点
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;index&quot;&gt;序号&lt;/param&gt;
    /// &lt;returns&gt;下级结点&lt;/returns&gt;
    public TreeNode this[int index]
    {
        get { return subNodes[index]; }
        set { subNodes[index] = value; }
    }

    /// &lt;summary&gt;
    /// 构造函数
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;name&quot;&gt;结点名&lt;/param&gt;
    public TreeNode(string name)
    {
        this.name = name;
        this.href = null;
    }

    /// &lt;summary&gt;
    /// 构造函数
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;name&quot;&gt;结点名&lt;/param&gt;
    /// /// &lt;param name=&quot;href&quot;&gt;结点链接&lt;/param&gt;
    public TreeNode(string name, string href)
    {
        this.name = name;
        this.href = href;
    }

    /// &lt;summary&gt;
    /// 添加下级结点
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;node&quot;&gt;新结点&lt;/param&gt;
    public void Add(TreeNode node)
    {
        subNodes.Add(node);
    }
}
</pre>
<h3>TreeView.cs</h3>
<pre class="brush: c#">
/// &lt;summary&gt;
/// TreeView
/// &lt;/summary&gt;
public class TreeView
{
    private List&lt;TreeNode&gt; nodes = new List&lt;TreeNode&gt;();

    /// &lt;summary&gt;
    /// 填充测试用数据
    /// &lt;/summary&gt;
    public void FillTestData()
    {
        TreeNode node1 = new TreeNode(&quot;中国&quot;, &quot;#&quot;);
        TreeNode node11 = new TreeNode(&quot;华北地区&quot;, &quot;#&quot;);
        TreeNode node111 = new TreeNode(&quot;河南省&quot;, &quot;#&quot;);
        TreeNode node112 = new TreeNode(&quot;河北省&quot;, &quot;#&quot;);
        TreeNode node113 = new TreeNode(&quot;山东省&quot;, &quot;#&quot;);
        TreeNode node1131 = new TreeNode(&quot;青岛市&quot;, &quot;#&quot;);
        TreeNode node1132 = new TreeNode(&quot;济南市&quot;, &quot;#&quot;);
        TreeNode node11321 = new TreeNode(&quot;市中区&quot;, &quot;#&quot;);
        TreeNode node11322 = new TreeNode(&quot;历下区&quot;, &quot;#&quot;);
        TreeNode node11323 = new TreeNode(&quot;槐荫区&quot;, &quot;#&quot;);
        TreeNode node11324 = new TreeNode(&quot;天桥区&quot;, &quot;#&quot;);
        TreeNode node11325 = new TreeNode(&quot;长清区&quot;, &quot;#&quot;);
        TreeNode node1133 = new TreeNode(&quot;菏泽市&quot;, &quot;#&quot;);
        TreeNode node1134 = new TreeNode(&quot;济宁市&quot;, &quot;#&quot;);
        TreeNode node1135 = new TreeNode(&quot;德州市&quot;, &quot;#&quot;);
        TreeNode node12 = new TreeNode(&quot;东北地区&quot;, &quot;#&quot;);
        TreeNode node13 = new TreeNode(&quot;西北地区&quot;, &quot;#&quot;);
        TreeNode node14 = new TreeNode(&quot;华东地区&quot;, &quot;#&quot;);
        TreeNode node15 = new TreeNode(&quot;西南地区&quot;, &quot;#&quot;);
        TreeNode node16 = new TreeNode(&quot;华南地区&quot;, &quot;#&quot;);
        TreeNode node17 = new TreeNode(&quot;华中地区&quot;, &quot;#&quot;);
        TreeNode node18 = new TreeNode(&quot;港澳台地区&quot;, &quot;#&quot;);

        node1132.Add(node11321);
        node1132.Add(node11322);
        node1132.Add(node11323);
        node1132.Add(node11324);
        node1132.Add(node11325);

        node113.Add(node1131);
        node113.Add(node1132);
        node113.Add(node1133);
        node113.Add(node1134);
        node113.Add(node1135);

        node11.Add(node111);
        node11.Add(node112);
        node11.Add(node113);

        node1.Add(node11);
        node1.Add(node12);
        node1.Add(node13);
        node1.Add(node14);
        node1.Add(node15);
        node1.Add(node16);
        node1.Add(node17);
        node1.Add(node18);

        nodes.Add(node1);
        nodes.Add(new TreeNode(&quot;俄罗斯&quot;, &quot;&quot;));
        nodes.Add(new TreeNode(&quot;美国&quot;));
        nodes.Add(new TreeNode(&quot;韩国&quot;));
        nodes.Add(new TreeNode(&quot;澳大利亚&quot;));
        nodes.Add(new TreeNode(&quot;印度&quot;, &quot;&quot;));
        nodes.Add(new TreeNode(&quot;加拿大&quot;, &quot;&quot;));
    }

    /// &lt;summary&gt;
    /// 获取TreeView的html代码
    /// &lt;/summary&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public string GetHtmlString()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(&quot;&lt;ul&gt;&quot;);
        for (int i = 0; i &lt; nodes.Count; i++)
        {
            sb.AppendLine(GetNodeHtml(nodes[i], 1, (i + 1).ToString()));
        }
        sb.AppendLine(&quot;&lt;/ul&gt;&quot;);
        return sb.ToString();
    }

    private string GetNodeHtml(TreeNode thisNode, int depth, string id)
    {
        StringBuilder sb = new StringBuilder();
        bool hasSub = (thisNode.Count &gt; 0) ? true : false;
        sb.AppendLine(string.Format(&quot;&lt;li id=\&quot;depth_{0}_item_{1}\&quot;&gt;&quot;, depth, id));
        sb.AppendLine(string.Format(
            &quot;&lt;div class=\&quot;{0}\&quot; id=\&quot;depth_{1}_item_{2}_ico\&quot; onclick=\&quot;controlNode(this,&#039;depth_{1}_item_{2}&#039;)\&quot;&gt;&lt;/div&gt;&lt;h1&gt;{3}&lt;/h1&gt;&quot;,
            hasSub ? &quot;closedir&quot; : &quot;nodir&quot;,
            depth,
            id,
            (thisNode.Href == null || thisNode.Href.Equals(&quot;&quot;)) ? thisNode.Name : string.Format(&quot;&lt;a href=\&quot;{0}\&quot;&gt;{1}&lt;/a&gt;&quot;, thisNode.Href, thisNode.Name)
            ));
        if (hasSub)
        {
            sb.AppendLine(string.Format(&quot;&lt;div id=\&quot;depth_{0}_item_{1}_layer\&quot; style=\&quot;display:block;\&quot;&gt;&quot;, depth, id));
            sb.AppendLine(&quot;&lt;ul&gt;&quot;);
            for (int i = 0; i &lt; thisNode.Count; i++)
            {
                sb.AppendLine(GetNodeHtml(thisNode[i], depth + 1, string.Format(&quot;{0}_{1}&quot;, id, i + 1)));
            }
            sb.AppendLine(&quot;&lt;/ul&gt;&quot;);
            sb.AppendLine(&quot;&lt;/div&gt;&quot;);
        }
        sb.AppendLine(&quot;&lt;/li&gt;&quot;);
        return sb.ToString();
    }
}
</pre>
<h3>ASP.NET页面调用：</h3>
<pre class="brush: c#">
&lt;%
    CMC.TreeView list = new CMC.TreeView();
    list.FillTestData();
    Response.Write(list.GetHtmlString());
%&gt;
</pre>
<h3>ASP.NET页面JavaScript：</h3>
<pre class="brush: js">
defaultNodeState();

function defaultNodeState()
{
	var nodeState = getCookie(&quot;nodeState&quot;);
	if(nodeState == null)
	{
	    nodeState = &quot;,|,|,&quot;;
		setCookie(&quot;nodeState&quot;,nodeState);
	}
	var layer = nodeState.split(&#039;|&#039;);
	for(var i=0;i&lt;layer.length;i++)
	{
		if(layer[i] != &quot;,&quot;)
		{
			var lItem = layer[i].split(&#039;,&#039;);
			var nodeIco = document.getElementById(lItem[0]+&quot;_ico&quot;);
			var nodeLayer = document.getElementById(lItem[0]+&quot;_layer&quot;);
			OpenNode(nodeIco);
			ShowDiv(nodeLayer);
		}
	}
}
function controlNode(obj,layerId)
{
	var className = obj.className.toLowerCase();
	var layer = document.getElementById(layerId + &quot;_layer&quot;);

	cookiesNode(layerId, className);
	if(className == &quot;opendir&quot;)
	{
		HideDiv(layer);
		obj.className = &quot;closedir&quot;;
	}
	else if (className == &quot;closedir&quot;)
	{
		ShowDiv(layer);
		obj.className = &quot;opendir&quot;;
	}
}

function cookiesNode(layerId,className)
{
    var nodeState = getCookie(&quot;nodeState&quot;);
	if(nodeState == null)
	{
	    nodeState = &quot;,|,|,&quot;;
		setCookie(&quot;nodeState&quot;,nodeState);
	}
	var layer = nodeState.split(&#039;|&#039;);
	var lDepth = getDepth(layerId);
	if(className == &quot;opendir&quot;)
	{

		layer[lDepth-1] = &quot;,&quot;
	}
	else
	{
		if(layer[lDepth-1] &amp;amp;&amp;amp;amp layer[lDepth-1] != &quot;,&quot;) {
                        var lItem = layer[lDepth - 1].split(&#039;,&#039;);
			var lIco = document.getElementById(lItem[0]+&quot;_ico&quot;);
			var lLayer = document.getElementById(lItem[0] + &quot;_layer&quot;);
			HideDiv(lLayer);
			CloseNode(lIco);
			    }
			    layer[lDepth - 1] = layerId + &quot;,&quot; + lDepth;
		    }
	var cValue = layer[0];
	for(var i=1;i&lt;layer.length;i++)
	{
		cValue += &quot;|&quot; + layer[i];
	}
	setCookie(&quot;nodeState&quot;,cValue);
}

function getDepth(layerId)
{
	var lItem = layerId.split(&#039;_&#039;);
	return lItem[1];
}

function OpenNode(obj)
{
	obj.className = &quot;opendir&quot;;
}
function CloseNode(obj)
{
	obj.className = &quot;closedir&quot;;
}
function HideDiv(obj)
{
    obj.style.display=&#039;none&#039;;

}
function ShowDiv(obj)
{
    obj.style.display=&#039;block&#039;;
}

//设置cookies
function setCookie(name,value)
{
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days*24*60*60*1000);
    document.cookie = name + &quot;=&quot; + escape(value) +
      &quot;;expires=&quot; + exp.toGMTString();
}
//读取cookies
function getCookie(name)
{
    var arr,reg = new RegExp(&quot;(^| )&quot; + name + &quot;=([^;]*)(;|$)&quot;);
    if(arr = document.cookie.match(reg)) return unescape(arr[2]);
    else return null;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/standard-treeview/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++中的Hello World</title>
		<link>http://www.nocoo.us/2009/01/cpp-hello-world/</link>
		<comments>http://www.nocoo.us/2009/01/cpp-hello-world/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 11:55:30 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3395</guid>
		<description><![CDATA[我一直觉得孔乙己会做一个很好的HR。 “读过书，……我便考你一考。茴香豆的茴字，怎样写的？” ——孔乙己 在初学一门编程语言的时候，写一个“Hello world!”程序是最常见的入门方法。通过写一个成功的“Hello world!”，可以实践这门语言最基本的语法特性，还可以带给自己成就感，真是一举两得。C/C++语言本身有很多特性，如果能够将这些技术分解出来变成一个个的“Hello world!”，并且将这些技术点到为止，貌似也算是一件善事。这里，列举了10个“Hello world!”程序，大家雅俗共赏一下。 1. 最经典的“Hello world!” “Hello world!”最经典的写法当然是直接用 printf 输出“Hello world!”这几个字符了。无论用C还是 C++，写起来都非常的简洁明了。这里把最常见的几个全部列在下面。 #include &#60;stdio.h&#62; #include &#60;iostream&#62; int main() { printf(&#34;Hello world!&#34;); // 教科书的写法 puts(&#34;Hello world!&#34;); // 我最喜欢的 puts(&#34;Hello&#34; &#34; &#34; &#34;world!&#34;); // 拼接字符串 std::cout &#60;&#60; &#34;Hello world!&#34; &#60;&#60; std::endl; // C++风格的教科书写法 return 0; } 特别需要注意的是，在C/C++里，如果两个字符串之间除空白符以外没有任何东西，编译器会自动认为这两个字符串是连在一起的字符串。这样，如果一个字符串过长，可以用这种方法换行来写，既不浪费性能，又美观。 2. 用宏写的“Hello world!” 在C/C++里，宏是一个神奇的东西。特别是在C语言中，宏可以帮我们做一些“又脏又累”的活，包括拼接代码片断、隐藏繁琐的实现细节等等。其中特别有趣的是“#”的用法，它可以“提取”参数的名字，把它变成字符串。 #include [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
我一直觉得孔乙己会做一个很好的HR。<br />
<strong>“读过书，……我便考你一考。茴香豆的茴字，怎样写的？” ——孔乙己</strong>
</p></blockquote>
<p>在初学一门编程语言的时候，写一个“Hello world!”程序是最常见的入门方法。通过写一个成功的“Hello world!”，可以实践这门语言最基本的语法特性，还可以带给自己成就感，真是一举两得。C/C++语言本身有很多特性，如果能够将这些技术分解出来变成一个个的“Hello world!”，并且将这些技术点到为止，貌似也算是一件善事。这里，列举了10个“Hello world!”程序，大家雅俗共赏一下。</p>
<h3>1. 最经典的“Hello world!”</h3>
<p>“Hello world!”最经典的写法当然是直接用 printf 输出“Hello world!”这几个字符了。无论用C还是 C++，写起来都非常的简洁明了。这里把最常见的几个全部列在下面。</p>
<pre class="brush: c++">
#include &lt;stdio.h&gt;
#include &lt;iostream&gt;

int main()
{
    printf(&quot;Hello world!&quot;);                   // 教科书的写法
    puts(&quot;Hello world!&quot;);                     // 我最喜欢的
    puts(&quot;Hello&quot; &quot; &quot; &quot;world!&quot;);               // 拼接字符串
    std::cout &lt;&lt; &quot;Hello world!&quot; &lt;&lt; std::endl; // C++风格的教科书写法

    return 0;
}
</pre>
<p>特别需要注意的是，在C/C++里，如果两个字符串之间除空白符以外没有任何东西，编译器会自动认为这两个字符串是连在一起的字符串。这样，如果一个字符串过长，可以用这种方法换行来写，既不浪费性能，又美观。</p>
<h3>2. 用宏写的“Hello world!”</h3>
<p>在C/C++里，宏是一个神奇的东西。特别是在C语言中，宏可以帮我们做一些“又脏又累”的活，包括拼接代码片断、隐藏繁琐的实现细节等等。其中特别有趣的是“#”的用法，它可以“提取”参数的名字，把它变成字符串。</p>
<pre class="brush: c++">
#include &lt;stdio.h&gt;

#define Say(sth) puts(#sth)

int main()
{
    return Say(Hello world!);
}
</pre>
<p>请注意，这个Hello world可是完全没有出现引号哦！</p>
<h3>3. 断章取义的“Hello world!”</h3>
<p>字符串是一种常量这当然毫无疑问，但是它的类型是什么，这就需要考虑一下了。使用C++的typeid就可以这个问题的答案，而且只要是符合C或C++标准的编译器就应该是一样的结果。比如字符串“Hello world!”，它的类型就是 char const [13]。<br />
知道了这个，就可以写出以下的“Hello world!”：</p>
<pre class="brush: c++">
#include &lt;stdio.h&gt;

int main()
{
    return puts(&amp;amp;&quot;Do not say: Hello world!&quot;[12]);
}
</pre>
<h3>4. 退出时运行的“Hello world!”</h3>
<p>大家都知道 main 函数退出意味着程序结束，可是这并不完全正确，我们完全可以在 main 函数退出以后做很多事呢——比如说，输出“Hello world!”。这个功能依赖于C标准库中提供的函数 atexit()，调用这个函数并注册自己的回调函数就行。需要注意，这个函数可以调用多次，最后注册的函数最先执行。</p>
<pre class="brush: c++">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

void say()
{
    printf(&quot;world!&quot;);
}

void sth()
{
    printf(&quot;Hello &quot;);
}

int main()
{
    return atexit(say), atexit(sth);
}
</pre>
<h3>5. 读取自己的“Hello world!”</h3>
<p>C/C++的编译器提供了一些有用的内置宏，最常用的就是 __FILE__ 和 __LINE__ 了。其中，__FILE__ 代表当前的源文件的文件名，嗯，对了，如果我们让这个程序读取自己的源文件，不就可以做一个很有意思的“Hello world!”了么？</p>
<pre class="brush: c++">
// Hello world!

#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;

int main()
{
    std::ifstream ifs(__FILE__);
    std::string say, some, word;

    ifs &gt;&gt; say &gt;&gt; some &gt;&gt; word;
    std::cout &lt;&lt; some &lt;&lt; &quot; &quot; &lt;&lt; word;

    return 0;
}
</pre>
<h3>6. 话分两头的“Hello world!”</h3>
<p>有了C++的类，我们就可以光明正大的在 main 函数执行之前和之后做感兴趣的事情了。我们可以声明一个全局的类的实例，这样，在 main 函数执行之前会调用这个类的构造函数，结束之后则会调用析构函数。</p>
<pre class="brush: c++">
#include &lt;iostream&gt;

class say
{
public:
    say()
    {
        std::cout &lt;&lt; &quot;Hell&quot;;
    }

    ~say()
    {
        std::cout &lt;&lt; &quot;world!&quot;;
    }
}hello;

int main()
{
    std::cout &lt;&lt; &quot;o &quot;;
    return 0;
}
</pre>
<h3>7. 传入模板的“Hello world!”</h3>
<p>C++的模板功能极为强大，可以说是C++里面最艰深、最经典、最时尚的部分。一个“Hello world!”当然无法使用很多很高级的模板技巧，我也不想只使用模板特化这样无阻挂齿的小技巧，嗯，那就来演示一个比较罕见的用法吧。</p>
<pre class="brush: c++">
#include &lt;iostream&gt;

template &lt;char * words&gt;
class say
{
public:
    void operator () ()
    {
        std::cout &lt;&lt; words;
    }
};

extern char hello[] = &quot;Hello world!&quot;;

int main()
{
    return say&lt;hello&gt;()(), 0;
}
</pre>
<p>请注意，这个 extern 是十分必要的，只有加上了 extern，这个指针才是一个编译器间可以确定的值，也才可以参与模板运算。还有，hello 必须为数组类型，而不能为 char*，这个道理和加 extern 是一样的。<br />
此外，这里还演示了 functor 的用法，嗯，关于它的优点就不在这里多说了，反正是与原生指针相比有很多好处就是了。</p>
<h3>8. 调用私有函数的“Hello world!”</h3>
<p>我们知道，C++类的私有函数是不能被外界访问的，比如说 main 函数里面，它绝对不能访问类的私有函数，除非把它设为类的友元函数。不过我们还是可以用一些比较奇怪的方法访问类的私有函数——当然，这个私有函数必须满足一个条件：它是虚函数。<br />
这里就涉及到一个问题，指向虚函数的虚表放在哪里？对于 VS.Net 2003 而言，虚表是类的第一个成员，虚函数指针按照函数声明的顺序放在虚表里面。当然，这个说法并不严谨，更细节的东西还是去看看那本“成人高钙奶粉”吧，它会给出最权威的解答。<br />
这里是一个很有意思的例子：</p>
<pre class="brush: c++">
#include &lt;iostream&gt;
#include &lt;cstddef&gt;

class secret
{
private:
    virtual void say()
    {
        std::cout &lt;&lt; &quot;Hello world!&quot;;
    }
};

int main()
{
    secret word;
    (reinterpret_cast&lt;void (*)()&gt;(**(intptr_t**)(&amp;amp;word)))();

    return 0;
}
</pre>
<h3>9. 最暴力的“Hello world!”</h3>
<p>最暴力的调用函数的方法是：直接修改函数的返回地址，让这个地址指向我们想要调用的函数。这也就是缓冲区溢出漏洞的应用方法了，不过里面还涉及到很多问题，在这里就不一一列举，想要了解的话，还是去 Google 吧。这里只演示一个可以在 VS.Net 2003 下可以用的“Hello world!”。</p>
<pre class="brush: c++">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stddef.h&gt;

void say()
{
    puts(&quot;Hello world!&quot;);
    exit(0);
}

int main()
{
    volatile intptr_t a = 0;
    volatile intptr_t * p = &amp;amp;a;

    *(p + 2) = (intptr_t)say;
    *(p + 3) = (intptr_t)say;

    return 0;
}
</pre>
<h3>10. 外星人说的“Hello world!”</h3>
<p>好了，这个“Hello world!”是最匪夷所思的一个了！不过它并没有涉及任何复杂的C/C++语言特性，只是看起来有点酷。你能看懂外星人在说什么不？</p>
<pre class="brush: c++">
#include &lt;stdio.h&gt;

void alien_say(char * p)
{
    while (putchar(*(p += *(p + 1) - *p)));
}

int main()
{
    return alien_say(&quot;BETHO! Altec oh liryom(a loadjudas!) dowd.&quot;), 0;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/cpp-hello-world/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#8220;C#中反射(Reflection)对const、readonly及static的影响</title>
		<link>http://www.nocoo.us/2009/01/reflection-const-readonly-static/</link>
		<comments>http://www.nocoo.us/2009/01/reflection-const-readonly-static/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 11:37:08 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3393</guid>
		<description><![CDATA[using System; using System.Collections.Generic; using System.Text; using System.Reflection; namespace ConsoleApplication1 { public class ReflectionTest { public const int test1 = 1; public readonly static int test2 = 1; public static int test3 = 1; public readonly int test4 = 1; } class Program { static void Main(string[] args) { ReflectionTest t = new ReflectionTest(); FieldInfo [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: c#">
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    public class ReflectionTest
    {
        public const int test1 = 1;
        public readonly static int test2 = 1;
        public static int test3 = 1;
        public readonly int test4 = 1;
    }

    class Program
    {
        static void Main(string[] args)
        {
            ReflectionTest t = new ReflectionTest();
            FieldInfo f;

            // const int test1
            // const不应该被更改，猜想应当抛出异常
            // 运行中SetValue(t, 2);确实抛出System.FieldAccessException异常
            Console.WriteLine(&quot;test1=&quot; + ReflectionTest.test1);
            f = typeof(ReflectionTest).GetField(&quot;test1&quot;);
            f.SetValue(t, 2);
            Console.WriteLine(&quot;test1=&quot; + ReflectionTest.test1);

            // readonly static int test2
            // 因为readonly不进行编译时检查，编译通过，但是执行时应当出错
            // 但是实际中没有任何提示，也并未更改，错误被吃掉了！
            Console.WriteLine(&quot;test2=&quot; + ReflectionTest.test2);
            f = typeof(ReflectionTest).GetField(&quot;test2&quot;);
            f.SetValue(t, 2);
            Console.WriteLine(&quot;test2=&quot; + ReflectionTest.test2);

            // static int test3
            // static变量当然可以通过反射更改
            Console.WriteLine(&quot;test3=&quot; + ReflectionTest.test3);
            f = typeof(ReflectionTest).GetField(&quot;test3&quot;);
            f.SetValue(t, 2);
            Console.WriteLine(&quot;test3=&quot; + ReflectionTest.test3);

            // readonly int test4
            // 实例中的readonly变量可以通过反射更改其值
            // 因此，readonly变量的赋值方法总共有三种：
            // 1. 在声明时对readonly变量赋值；
            // 2. 在构造函数中对readonly变量赋值；
            // 3. 使用反射在实例生命期中对readonly变量赋值。
            Console.WriteLine(&quot;test4=&quot; + t.test4);
            f = typeof(ReflectionTest).GetField(&quot;test4&quot;);
            f.SetValue(t, 2);
            Console.WriteLine(&quot;test4=&quot; + t.test4);
        }
    }
}
</pre>
<p>运行结果：</p>
<pre class="brush: sh">
test1=1
未处理的异常:  System.FieldAccessException: 无法设置常量字段。
   在 System.Reflection.MdFieldInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureIn
fo culture)
   在 System.Reflection.FieldInfo.SetValue(Object obj, Object value)
   在 ConsoleApplication1.Program.Main(String[] args) 位置 C:\Documents and Settings\Zheng Li\桌面\ConsoleApplication1\C
onsoleApplication1\Program.cs:行号 28
</pre>
<p>注释掉第28行的结果：</p>
<pre class="brush: sh">
test1=1
test1=1
test2=1
test2=1
test3=1
test3=2
test4=1
test4=2
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/reflection-const-readonly-static/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>标准C++中获取某种数据类型的最大值和最小值</title>
		<link>http://www.nocoo.us/2009/01/cpp-numeric-max-min-limits/</link>
		<comments>http://www.nocoo.us/2009/01/cpp-numeric-max-min-limits/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 07:49:32 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3381</guid>
		<description><![CDATA[用惯C#，比如我想让一个int数等于无穷大，只需要简单写： int a = int.MaxValue; 转到C++上，疑惑了&#8230; 首先C++不会有属性这种东西，而且不同平台上的某个类型的最大最小值是不一样的。 解决方案是使用limits头文件的方法。 #include &#60;limits&#62; #include &#60;iostream&#62; using namespace std; int _tmain(int argc, _TCHAR* argv[]) { cout&#60;&#60;&#34;short:&#34;&#60;&#60;endl; cout&#60;&#60;&#34;min=&#34;&#60;&#60;numeric_limits&#60;short&#62;::min()&#60;&#60;endl; cout&#60;&#60;&#34;max=&#34;&#60;&#60;numeric_limits&#60;short&#62;::max()&#60;&#60;endl; cout&#60;&#60;&#34;int:&#34;&#60;&#60;endl; cout&#60;&#60;&#34;min=&#34;&#60;&#60;numeric_limits&#60;int&#62;::min()&#60;&#60;endl; cout&#60;&#60;&#34;max=&#34;&#60;&#60;numeric_limits&#60;int&#62;::max()&#60;&#60;endl; cout&#60;&#60;&#34;double:&#34;&#60;&#60;endl; cout&#60;&#60;&#34;min=&#34;&#60;&#60;numeric_limits&#60;double&#62;::min()&#60;&#60;endl; cout&#60;&#60;&#34;max=&#34;&#60;&#60;numeric_limits&#60;double&#62;::max()&#60;&#60;endl; cout&#60;&#60;&#34;long:&#34;&#60;&#60;endl; cout&#60;&#60;&#34;min=&#34;&#60;&#60;numeric_limits&#60;long&#62;::min()&#60;&#60;endl; cout&#60;&#60;&#34;max=&#34;&#60;&#60;numeric_limits&#60;long&#62;::max()&#60;&#60;endl; return 0; } 在我的工作站平台(Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1)下输出： short: min=-32768 max=32767 int: min=-2147483648 max=2147483647 double: min=2.22507e-308 max=1.79769e+308 long: min=-2147483648 [...]]]></description>
			<content:encoded><![CDATA[<p>用惯C#，比如我想让一个int数等于无穷大，只需要简单写：</p>
<pre class="brush: c#">
int a = int.MaxValue;
</pre>
<p>转到C++上，疑惑了&#8230;<br />
首先C++不会有属性这种东西，而且不同平台上的某个类型的最大最小值是不一样的。<br />
解决方案是使用limits头文件的方法。</p>
<pre class="brush: cpp">
#include &lt;limits&gt;
#include &lt;iostream&gt;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    cout&lt;&lt;&quot;short:&quot;&lt;&lt;endl;
    cout&lt;&lt;&quot;min=&quot;&lt;&lt;numeric_limits&lt;short&gt;::min()&lt;&lt;endl;
    cout&lt;&lt;&quot;max=&quot;&lt;&lt;numeric_limits&lt;short&gt;::max()&lt;&lt;endl;

    cout&lt;&lt;&quot;int:&quot;&lt;&lt;endl;
    cout&lt;&lt;&quot;min=&quot;&lt;&lt;numeric_limits&lt;int&gt;::min()&lt;&lt;endl;
    cout&lt;&lt;&quot;max=&quot;&lt;&lt;numeric_limits&lt;int&gt;::max()&lt;&lt;endl;

    cout&lt;&lt;&quot;double:&quot;&lt;&lt;endl;
    cout&lt;&lt;&quot;min=&quot;&lt;&lt;numeric_limits&lt;double&gt;::min()&lt;&lt;endl;
    cout&lt;&lt;&quot;max=&quot;&lt;&lt;numeric_limits&lt;double&gt;::max()&lt;&lt;endl;

    cout&lt;&lt;&quot;long:&quot;&lt;&lt;endl;
    cout&lt;&lt;&quot;min=&quot;&lt;&lt;numeric_limits&lt;long&gt;::min()&lt;&lt;endl;
    cout&lt;&lt;&quot;max=&quot;&lt;&lt;numeric_limits&lt;long&gt;::max()&lt;&lt;endl;
    return 0;
}
</pre>
<p>在我的工作站平台(Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1)下输出：</p>
<pre class="brush: sh">
short:
min=-32768
max=32767
int:
min=-2147483648
max=2147483647
double:
min=2.22507e-308
max=1.79769e+308
long:
min=-2147483648
max=2147483647
</pre>
<p>在Ubuntu Server下用gcc version 4.2.4执行的结果如下</p>
<pre class="brush: sh">
short:
min=-32768
max=32767
int:
min=-2147483648
max=2147483647
double:
min=2.22507e-308
max=1.79769e+308
long:
min=-2147483648
max=2147483647
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/cpp-numeric-max-min-limits/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C#读取任意charset网页</title>
		<link>http://www.nocoo.us/2009/01/c-sharp-any-charset-web-page/</link>
		<comments>http://www.nocoo.us/2009/01/c-sharp-any-charset-web-page/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 02:01:07 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3356</guid>
		<description><![CDATA[private string GetPageContent(string address) { try { string result = null; HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address); req.Method = &#34;GET&#34;; using (WebResponse wr = req.GetResponse()) { // 请求网页内容 Stream stream = wr.GetResponseStream(); StreamReader sr = new StreamReader(stream, Encoding.Default); result = sr.ReadToEnd(); // 获取网页编码 int charsetIndex = result.IndexOf(&#34;charset&#34;); string charset = &#34;utf-8&#34;; if (charsetIndex != -1) { int [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: c#">
private string GetPageContent(string address)
{
    try
    {
        string result = null;
        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
        req.Method = &quot;GET&quot;;
        using (WebResponse wr = req.GetResponse())
        {
            // 请求网页内容
            Stream stream = wr.GetResponseStream();
            StreamReader sr = new StreamReader(stream, Encoding.Default);
            result = sr.ReadToEnd();

            // 获取网页编码
            int charsetIndex = result.IndexOf(&quot;charset&quot;);
            string charset = &quot;utf-8&quot;;
            if (charsetIndex != -1)
            {
                int right = result.IndexOf(&quot;&gt;&quot;, charsetIndex);
                charset = result.Substring(
                    charsetIndex + 7, right - charsetIndex - 7).Trim();
                charset = charset.Replace(&quot;=&quot;, &quot;&quot;);
                charset = charset.Replace(&quot;\r&quot;, &quot;&quot;);
                charset = charset.Replace(&quot;\n&quot;, &quot;&quot;);
                charset = charset.Replace(&quot;\&quot;&quot;, &quot;&quot;);
                charset = charset.Replace(&quot;&#039;&quot;, &quot;&quot;);
                charset = charset.Replace(&quot;/&quot;, &quot;&quot;);
                charset = charset.Replace(&quot; &quot;, &quot;&quot;).ToLower();
            }

            // 将字符串转换成网页中指定的编码类型
            result = Encoding.GetEncoding(charset).GetString(
                Encoding.Convert(Encoding.Default,
                Encoding.GetEncoding(charset),
                Encoding.Default.GetBytes(result)));

            sr.Close();
            stream.Close();
        }
        return result;
    }
    catch
    {
        return null;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2009/01/c-sharp-any-charset-web-page/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>对字符串数组生成一个随机序</title>
		<link>http://www.nocoo.us/2008/12/random-string-array/</link>
		<comments>http://www.nocoo.us/2008/12/random-string-array/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 12:17:30 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[作品发布]]></category>
		<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3323</guid>
		<description><![CDATA[这种情况： 一组照片，或者MP3歌曲，知道它们的路径，保存在一个数组中。现在想随机播放之。要求，每首歌出现的概率相等，且播放完全部之前不会重复，并且保证顺序可以前后无限快进或者快倒。 using System; using System.Collections.Generic; using System.Text; using System.IO; namespace RandomStringArray { class Program { private static int count = 50; static void Main(string[] args) { string[] originalArray = GetStringArray(); string[] randomArray = new string[originalArray.Length]; SortedList&#60;int, string&#62; list = new SortedList&#60;int, string&#62;(); for (int i = 0; i &#60; originalArray.Length; i++) { list.Add(originalArray[i].GetHashCode(), originalArray[i]); [...]]]></description>
			<content:encoded><![CDATA[<p>这种情况：<br />
一组照片，或者MP3歌曲，知道它们的路径，保存在一个数组中。现在想随机播放之。要求，每首歌出现的概率相等，且播放完全部之前不会重复，并且保证顺序可以前后无限快进或者快倒。</p>
<pre class="brush: c#">
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace RandomStringArray
{
    class Program
    {
        private static int count = 50;

        static void Main(string[] args)
        {
            string[] originalArray = GetStringArray();
            string[] randomArray = new string[originalArray.Length];

            SortedList&lt;int, string&gt; list = new SortedList&lt;int, string&gt;();
            for (int i = 0; i &lt; originalArray.Length; i++)
            {
                list.Add(originalArray[i].GetHashCode(), originalArray[i]);
            }

            int index = 0;
            foreach (KeyValuePair&lt;int, string&gt; item in list)
            {
                randomArray[index++] = item.Value;
            }

            // Print Result
            Console.WriteLine(&quot;Original:&quot;);
            for (int i = 0; i &lt; originalArray.Length; i++)
            {
                Console.WriteLine(string.Format(&quot;[{0}]{1}&quot;, i, originalArray[i]));
            }
            Console.WriteLine(&quot;Random:&quot;);
            for (int i = 0; i &lt; randomArray.Length; i++)
            {
                Console.WriteLine(string.Format(&quot;[{0}]{1}&quot;, i, randomArray[i]));
            }
        }

        /// &lt;summary&gt;
        /// Generate a directories list for test
        /// &lt;/summary&gt;
        /// &lt;returns&gt;Directories list&lt;/returns&gt;
        private static string[] GetStringArray()
        {
            if (!Directory.Exists(&quot;Temp&quot;))
            {
                Directory.CreateDirectory(&quot;Temp&quot;);

                for (int i = 0; i &lt; count; i++)
                {
                    Directory.CreateDirectory(&quot;Temp\\&quot; +
                                Guid.NewGuid().ToString());
                }
            }
            return Directory.GetDirectories(&quot;Temp&quot;);
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2008/12/random-string-array/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Preview!</title>
		<link>http://www.nocoo.us/2008/12/a-preview/</link>
		<comments>http://www.nocoo.us/2008/12/a-preview/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 07:29:17 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[作品发布]]></category>
		<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[心情日记]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[ARsync]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3172</guid>
		<description><![CDATA[[singlepic=18221] 用户登录 [singlepic=18222,610,422] 远程文件夹同步]]></description>
			<content:encoded><![CDATA[<p>[singlepic=18221]<br />
用户登录</p>
<p>[singlepic=18222,610,422]<br />
远程文件夹同步</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2008/12/a-preview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>为什么MemoryStream里读取的数组会全0</title>
		<link>http://www.nocoo.us/2008/12/why-memerystream-byte-array-0/</link>
		<comments>http://www.nocoo.us/2008/12/why-memerystream-byte-array-0/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 16:00:22 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3144</guid>
		<description><![CDATA[第一个版本： public static byte[] Serialize(object o) { MemoryStream ms = new MemoryStream(); GZipStream compressedStream = new GZipStream(ms, CompressionMode.Compress, true); BinaryFormatter b = new BinaryFormatter(); b.Serialize(compressedStream, o); byte[] buffer = new byte[ms.Length]; ms.Read(buffer, 0, (int)ms.Length); compressedStream.Close(); ms.Close(); return buffer; } 第一个版本的问题是，buffer的长度不正确，同样的对象如果序列化到文件再读文件出来，长度总是和MemoryStream差那么十几个byte。甚是郁闷。 第二个版本： public static byte[] Serialize(object o) { MemoryStream ms = new MemoryStream(); GZipStream compressedStream = [...]]]></description>
			<content:encoded><![CDATA[<h3>第一个版本：</h3>
<pre class="brush: c#">
public static byte[] Serialize(object o)
{
  MemoryStream ms = new MemoryStream();
  GZipStream compressedStream =
                        new GZipStream(ms, CompressionMode.Compress, true);
  BinaryFormatter b = new BinaryFormatter();
  b.Serialize(compressedStream, o);

  byte[] buffer = new byte[ms.Length];
  ms.Read(buffer, 0, (int)ms.Length);

  compressedStream.Close();
  ms.Close();
  return buffer;
}
</pre>
<p>第一个版本的问题是，buffer的长度不正确，同样的对象如果序列化到文件再读文件出来，长度总是和MemoryStream差那么十几个byte。甚是郁闷。</p>
<h3>第二个版本：</h3>
<pre class="brush: c#">
public static byte[] Serialize(object o)
{
  MemoryStream ms = new MemoryStream();
  GZipStream compressedStream =
                        new GZipStream(ms, CompressionMode.Compress, true);
  BinaryFormatter b = new BinaryFormatter();
  b.Serialize(compressedStream, o);
  compressedStream.Flush();
  compressedStream.Close();

  byte[] buffer = new byte[ms.Length];
  ms.Read(buffer, 0, (int)ms.Length);

  ms.Close();
  return buffer;
}
</pre>
<p>这样MemoryStream读取出来的byte组至少在长度上正确了。但是带来一个问题，读出来的byte数组里全是0，没读到数据。Read返回也是0。</p>
<h3>第三个版本：</h3>
<pre class="brush: c#">
public static byte[] Serialize(object o)
{
  MemoryStream ms = new MemoryStream();
  GZipStream compressedStream =
                        new GZipStream(ms, CompressionMode.Compress, true);
  BinaryFormatter b = new BinaryFormatter();
  b.Serialize(compressedStream, o);
  compressedStream.Flush();
  compressedStream.Close();

  ms.Position = 0;
  byte[] buffer = new byte[ms.Length];
  ms.Read(buffer, 0, (int)ms.Length);

  ms.Close();
  return buffer;
}
</pre>
<p>这样终于正常了。这个事情告诉我们一下几个事实：</p>
<ul>
<li>凡是与Stream打交道时遇到的奇奇怪怪的问题多半与缓存有关，试试Flush()会有奇效。“自从缓存发明之后，计算机科学里就再也没有牛B的概念产生了。”</li>
<li>使用MemoryStream时要打破思维定势，记得读取MemoryStream时要首先设置Position到合适的位置再读。</li>
<li><strong>没有做不到的事情。</strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2008/12/why-memerystream-byte-array-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Studio 2008 C#项目代码行统计工具</title>
		<link>http://www.nocoo.us/2008/11/nocoo-code-counter/</link>
		<comments>http://www.nocoo.us/2008/11/nocoo-code-counter/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 01:47:09 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[作品发布]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[心情日记]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3127</guid>
		<description><![CDATA[我写的一个工具，可以打开一个Visual Studio 2008项目的解决方案.sln文件，分析其中的C#项目，统计代码行数。代码目前主要统计总行数、空行数、注释行这三种，计算注释比例和代码循环嵌套深度。 [singlepic=18214] [singlepic=18213,610,392] 目前只对Visual Studio 2008的C#项目做过测试，别的项目我目前用不到，运行会有什么结果我不知道&#8230;不过肯定不会造成损失，放心试试吧。 下载：http://www.redmine.net/projects/list_files/nocoocodecounter]]></description>
			<content:encoded><![CDATA[<p>我写的一个工具，可以打开一个Visual Studio 2008项目的解决方案.sln文件，分析其中的C#项目，统计代码行数。代码目前主要统计总行数、空行数、注释行这三种，计算注释比例和代码循环嵌套深度。</p>
<p>[singlepic=18214]</p>
<p>[singlepic=18213,610,392]</p>
<p>目前只对Visual Studio 2008的C#项目做过测试，别的项目我目前用不到，运行会有什么结果我不知道&#8230;不过肯定不会造成损失，放心试试吧。<br />
<strong>下载：</strong><a href="http://www.redmine.net/projects/list_files/nocoocodecounter">http://www.redmine.net/projects/list_files/nocoocodecounter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2008/11/nocoo-code-counter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>64位Windows Server如何使用PHP</title>
		<link>http://www.nocoo.us/2008/10/php-on-64bit-windows/</link>
		<comments>http://www.nocoo.us/2008/10/php-on-64bit-windows/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 02:38:00 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Windows Server]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=3007</guid>
		<description><![CDATA[本文致力于描述如何在Windows Server 2003下安装配置PHP环境时遇到的问题及解决。 环境说明： 操作系统：Windows Server 2003 Computing Cluster Edition，英文版（由Microsoft支持） 相关软件：Internet Information Services 6.0 PHP：PHP 5.2.6 zip package。（最新版下载地址） PHP装多了，闭着眼也能装好。于是今天早晨却遇到一个诡异的问题。 用了5分钟装好PHP之后，刷新IE，我的index.php里很简单，就是简单的phpinfo： &#60;?php phpinfo();?&#62; 熟悉的界面并没有出来，取而代之是连不上服务器。也不是500内部服务器错误，因为如果是500，说明PHP没配置正确。这次很诡异，就是连不上服务器。是这个样子的： [singlepic=18201,640,480] 我打开IIS的ISAPI Filters，确实PHP的ISAPI是一个红色的向下箭头，加载失败了。 [singlepic=18197] 这是为什么？不应该啊，我玩PHP可不是一年两年了，配过的服务器无数&#8230;怎么会失手&#8230; 赶忙看看静态页能不能显示，创建了一个a.html，能够显示的。 打开Event Viewer，一片错误： [singlepic=18200] 打开一个看一下什么问题： [singlepic=18198] ISAPI Filter &#8216;D:\PHP\php5isapi.dll&#8217; could not be loaded due to a configuration problem. The current configuration only supports loading images built for [...]]]></description>
			<content:encoded><![CDATA[<p>本文致力于描述如何在Windows Server 2003下安装配置PHP环境时遇到的问题及解决。</p>
<h3>环境说明：</h3>
<ul>
<li><strong>操作系统：</strong>Windows Server 2003 Computing Cluster Edition，英文版（由Microsoft支持）</li>
<li><strong>相关软件：</strong>Internet Information Services 6.0</li>
<li><strong>PHP：</strong>PHP 5.2.6 zip package。（<a href="http://www.php.net/downloads.php">最新版下载地址</a>）</li>
</ul>
<p>PHP装多了，闭着眼也能装好。于是今天早晨却遇到一个诡异的问题。<br />
用了5分钟装好PHP之后，刷新IE，我的index.php里很简单，就是简单的phpinfo：</p>
<pre class="brush: c#">
&lt;?php phpinfo();?&gt;
</pre>
<p>熟悉的界面并没有出来，取而代之是连不上服务器。也不是500内部服务器错误，因为如果是500，说明PHP没配置正确。这次很诡异，就是连不上服务器。是这个样子的：</p>
<p>[singlepic=18201,640,480]</p>
<p><span id="more-3007"></span></p>
<p>我打开IIS的ISAPI Filters，确实PHP的ISAPI是一个红色的向下箭头，加载失败了。</p>
<p>[singlepic=18197]</p>
<p>这是为什么？不应该啊，我玩PHP可不是一年两年了，配过的服务器无数&#8230;怎么会失手&#8230;<br />
赶忙看看静态页能不能显示，创建了一个a.html，能够显示的。<br />
打开Event Viewer，一片错误：</p>
<p>[singlepic=18200]</p>
<p>打开一个看一下什么问题：</p>
<p>[singlepic=18198]</p>
<p><strong><br />
ISAPI Filter &#8216;D:\PHP\php5isapi.dll&#8217; could not be loaded due to a configuration problem. The current configuration only supports loading images built for a AMD64 processor architecture. The data field contains the error number. To learn more about this issue, including how to troubleshooting this kind of processor architecture mismatch error, see http://go.microsoft.com/fwlink/?LinkId=29349.</strong></p>
<p><strong>For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.<br />
</strong><br />
这才幡然醒悟：我用的这台服务器安装的是Windows Server 2003 Computing Cluster Edition，只有64位的！64位系统上IIS自然也是64位IIS。<br />
怎么办呢，我总不至于换服务器吧，多麻烦，还得开别的远程桌面&#8230;</p>
<p>Anyway，Google到一个方法，<a href="http://www.iisadmin.co.uk/?p=14">Running PHP on 64-Bit Windows</a>，我试一下。<br />
其实解决64位兼容性问题一般也就两种方式：换64位PHP，或者让IIS在32位方式下运行。下面介绍一下如何让64位系统的IIS在32位模式下运行。</p>
<p>[singlepic=18199]</p>
<p>打开一个Command Prompt，输入：</p>
<pre class="brush: c#">
cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1
</pre>
<p>这样可以或者让IIS在32位方式下运行。这个问题在KB文章<a href="http://support.microsoft.com/?id=895976">Windows Server 2003 SP1 enables WOW64 compatibility for 32-bit Web applications in IIS 6.0</a>和<a href="http://support.microsoft.com/?id=894435">How to switch between the 32-bit versions of ASP.NET 1.1 and the 64-bit version of ASP.NET 2.0 on a 64-bit version of Windows</a>讨论过。</p>
<p>[singlepic=18203]</p>
<p>成功了。重启World Wide Web Publishing Service，Eventlog中没有出现新的警告，IIS的ISAPI中也出现了绿色向上的箭头，PHP加载成功了。<br />
需要说明的是，另一种方法，换64位的PHP，也不是不行的。存在64位PHP项目，<a href="http://www.fusionxlan.com/PHPx64.php">PHP 5.2.1 x64 Project</a>，我没有采用，原因主要是，我认为PHP升级速度还是比较快的，第三方进行的64位PHP项目不一定能跟得上变化吧。希望PHP早日推出64位版本。</p>
<p>[singlepic=18202,640,480]</p>
<p>再次刷新IE，PHPInfo出现了。</p>
<p><strong>本文图片使用<a href="http://www.nocoo.us/support/">Nocoo.Tools</a>提供的工作窗口截图工具<a href="http://www.nocoo.us/2008/10/screen-capture/">ScreenCapture</a>截取。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2008/10/php-on-64bit-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>如何在Windows Server 2008的IIS 7.0下配置MySQL+PHP环境</title>
		<link>http://www.nocoo.us/2008/10/windows-server-2008-iis-php-mysql/</link>
		<comments>http://www.nocoo.us/2008/10/windows-server-2008-iis-php-mysql/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 16:00:29 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Windows Server]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=2994</guid>
		<description><![CDATA[本文致力于描述如何在Windows Server 2008下安装配置用于开发或产品的MySQL及PHP环境。 环境说明： 操作系统：Windows Server 2008 Standard Edition，英文版（由Microsoft DreamSpark支持） 相关软件：Internet Information Services 7.0 MySQL：MySQL 5.0.67, Windows Essentials (x86)。（最新版下载地址） PHP：PHP 5.2.6 zip package。（最新版下载地址） 1. 安装MySQL 这似乎是一个波澜不惊的过程，任何人都能做好。 [singlepic=18162] 安装欢迎界面。 [singlepic=18163] 这一步选Custom自定义安装比较好，指定安装位置，建议安装在D盘，避开系统盘C盘。由于UAC的问题，在Vista和2008下，C盘的文件搞得很特殊，一些原来好好的程序，由于权限问题的存在，会出现莫名奇妙的故障。 [singlepic=18164] 自定义MySQL安装路径到D盘。 [singlepic=18165] 结束了，立即启动配置向导。我在2008下这里点Finish没有效果，配置向导并没有启动，只好在开始菜单启动之。 [singlepic=18166] 配置向导欢迎界面。 [singlepic=18167] 默认使用Detailed Configuration，这样可控制性高些。 [singlepic=18168] 选择MySQL服务器的类型，不同的选项会影响MySQL内存分配策略。 Developer Machine会使用最小的内存； Server Machine指MySQL和其他服务，如Web等共存在一个服务器的情况，将使用中等的内存； Dedicated MySQL Server Machine适用于，此服务器仅仅用于MySQL服务的情况，MySQL将会利用全部内存。 [singlepic=18169] 适用何种数据引擎。 Multifunctional Database：一般通用服务器的选项，InnoDB和MyISAM都可以使用。 Transactional Database [...]]]></description>
			<content:encoded><![CDATA[<p>本文致力于描述如何在Windows Server 2008下安装配置用于开发或产品的MySQL及PHP环境。</p>
<h3>环境说明：</h3>
<ul>
<li><strong>操作系统：</strong>Windows Server 2008 Standard Edition，英文版（由Microsoft DreamSpark支持）</li>
<li><strong>相关软件：</strong>Internet Information Services 7.0</li>
<li><strong>MySQL：</strong>MySQL 5.0.67, Windows Essentials (x86)。（<a href="http://dev.mysql.com/downloads/">最新版下载地址</a>）</li>
<li><strong>PHP：</strong>PHP 5.2.6 zip package。（<a href="http://www.php.net/downloads.php">最新版下载地址</a>）</li>
</ul>
<h3>1. 安装MySQL</h3>
<p>这似乎是一个波澜不惊的过程，任何人都能做好。<br />
[singlepic=18162]<br />
安装欢迎界面。<br />
[singlepic=18163]<br />
这一步选Custom自定义安装比较好，指定安装位置，建议安装在D盘，避开系统盘C盘。由于UAC的问题，在Vista和2008下，C盘的文件搞得很特殊，一些原来好好的程序，由于权限问题的存在，会出现莫名奇妙的故障。<br />
<span id="more-2994"></span><br />
[singlepic=18164]<br />
自定义MySQL安装路径到D盘。<br />
[singlepic=18165]<br />
结束了，立即启动配置向导。我在2008下这里点Finish没有效果，配置向导并没有启动，只好在开始菜单启动之。<br />
[singlepic=18166]<br />
配置向导欢迎界面。<br />
[singlepic=18167]<br />
默认使用Detailed Configuration，这样可控制性高些。<br />
[singlepic=18168]<br />
选择MySQL服务器的类型，不同的选项会影响MySQL内存分配策略。<br />
Developer Machine会使用最小的内存；<br />
Server Machine指MySQL和其他服务，如Web等共存在一个服务器的情况，将使用中等的内存；<br />
Dedicated MySQL Server Machine适用于，此服务器仅仅用于MySQL服务的情况，MySQL将会利用全部内存。<br />
[singlepic=18169]<br />
适用何种数据引擎。<br />
Multifunctional Database：一般通用服务器的选项，InnoDB和MyISAM都可以使用。<br />
Transactional Database Only：在这种情况下，InnoDB是主要的数据引擎并得到性能优化。一般而言，主流开源PHP项目使用MyISAM的还是比较多，如WordPress和Discuz等。但是也有例外，MediaWiki和Gallery 2都使用InnoDB作为其主要数据库表的数据引擎。注意，在这种模式下，MyISAM也可以使用。<br />
None Transactional Database Only：上面一种情况的反面，但是InnoDB就不能用了。可以理解为MySQL 4时代的样子。<br />
[singlepic=18170]<br />
指定数据文件的存储位置，非常重要！<br />
不要把数据存储在C盘，最好存在另外一块物理磁盘，最不济也是其他分区。否则系统挂掉数据也没了。<br />
[singlepic=18171]<br />
并发连接数的假设。<br />
Decision Support（DSS）/OLAP：在这种情况下，数据库服务器主要用于数据存储，而不是并发服务。系统假设某一时刻并发存在约20个同时请求。<br />
Online Transaction Processing（OLAP）：这种情况适用于大部分高负载的Web服务器，同时约有500个请求。注意，这个假设还算相当宽泛的，500个请求是同时并发的，也许此刻有5000人在线，但是同时请求数据（查询数据库）的不会太多。<br />
Manual Setting：手动设置一个数目。我想除非你用了一个超级服务器，不然一般不会去设置这种数目。Linux下调节这个数字会达到性能优化的效果。<br />
[singlepic=18172]<br />
启动TCP/IP服务，监听3306端口。如果Web Server也在本机，不打开穿越防火墙也是可以的，反而安全些。你使用phpMyAdmin管理的时候，那个连接其实还是本机到本机的连接，不通过防火墙。穿越防火墙的访问一般发生在，你在另外的Web Server安装应用，然后把数据库保存在这台服务器，然后使用一个能够远程连接MySQL的帐户来访问的情况。这种情况还是比较少见的（WordPress安装向导里说99%情况都不是这样的）。<br />
[singlepic=18173]<br />
字符集设置，建议选择第二个，Best Support For Multilingualism，这样会默认使用UTF-8字符集，对中文支持好。<br />
[singlepic=18174]<br />
建立Windows服务，自动启动。把MySQL的bin目录加入Path环境变量，这样你可以在命令提示符下直接用mysql或者mysqldump之类的命令。<br />
[singlepic=18175]<br />
设置root用户密码。产品机器上不要打开“Enable root access from remote machines”，也不要建立匿名用户。再次说明，不打开“Enable root access from remote machines”，你同样可以用同一台机器上的phpMyAdmin登陆root帐户。<br />
[singlepic=18176]<br />
设置完成。最近几个版本的MySQL做的好多了，以往这一步第一次从是出错，因为脚本不知道新设置的密码，会给新手不少疑惑。<br />
[singlepic=18177]<br />
打开一个Command Prompt，直接使用mysql命令登陆服务器。<br />
[singlepic=18178]<br />
看下数据库。到这里，MySQL就安装好了。</p>
<h3>2. IIS 7.0下PHP的安装</h3>
<p>我在这里讲最复杂的情况，使用zip安装包安装PHP。<br />
[singlepic=18181,640,480]<br />
首先把PHP解压到一个地方。由于UAC的缘故，最好放在D盘。我在这里放在D:\PHP下。此外，服务器配置的时候，一律不要用带中文的目录（完整路径中不要包含任何中文和其他奇怪的字符）。<br />
[singlepic=18179]<br />
首先先在IIS里的Advanced Setting中，给默认目录改个地方，避开C盘。<br />
[singlepic=18192,640,486]<br />
PHP在IIS里以一种ISAPI的形式出现。据新闻消息，IIS 7.0特别优化了对ISAPI的支持，尤其是对PHP。有机会对比测试一下。<br />
[singlepic=18191,640,482]<br />
Windows Server 2008中最大的好处就是各个组件都可以自定义地安装，而不是Vista般一股脑装好，很好好强大却很慢很复杂。IIS也是如此。IIS可以不装任何ISAPI而成为Apache一样的静态HTML服务器。并不是没有用，作为镜像服务器提供下载之类，这样的高性能服务器是必须的。首先在System Manager中的IIS上，Add Role Services中确认安装了Application Development，否则无法使用ASP.NET和PHP这类服务器脚本。<br />
[singlepic=18193,640,486]<br />
首先在ISAPI Filters里添加PHP。右键Add。<br />
[singlepic=18194]<br />
取个名字叫做PHP，Executable地址选择到PHP的目录下的php5isapi.dll。这一步允许php5isapi.dll这个文件作为ISAPI的形式来运行。<br />
[singlepic=18180,640,486]<br />
然后需要告诉IIS，什么样的文件需要使用这个ISAPI来解释执行。打开Handler Mappings。<br />
[singlepic=18182,640,486]<br />
右键Add Script Map。<br />
[singlepic=18183]<br />
这里告诉IIS，所有符合*.php的文件，都要使用php5isapi.dll这个文件来解释执行，这条规则记做“PHP”。<br />
[singlepic=18184]<br />
Windows Server 2003的IIS6中，新添加的ISAPI默认是禁止的。在IIS7中，刚刚添加的ISAPI会询问是否默认打开。选择Yes，允许这条规则。<br />
[singlepic=18196,640,480]<br />
下面设置些PHP的内容。在PHP安装目录下，把php.ini.recommended这个文件重命名为php.ini，打开编辑之（注意，先编辑再复制到C盘去，否则没权限，提示保存失败。）。编辑的内容主要是PHP扩展，也就是PHP对MySQL的支持之类。<br />
[singlepic=18195,640,486]<br />
首先设置extension_dir这个变量到你的PHP目录下的ext。然后在Windows Extensions里面打开适当的扩展dll。一般，打开bz2，gd2，mbstring，mysql和mysqli就可以了。保存然后把这个文件拷贝到C:\Windows下。此外说一下，有时候你的某个加载项可能会加载失败，这是php.ini误导人的地方，这里的dll是按照英文字典序排序，实际中，某个dll可能有其依赖dll要先于它打开。这时候如果先打开有依赖dll的，就会加载失败。这种情况下，在phpinfo中可以看到其他加载项，唯独看不到这一个。当然，如果别的也看不到，说明配置有问题，ext的全部dll都没找到。<br />
[singlepic=18187,640,480]<br />
可能也是UAC的缘故？按照道理，这样设置应该足以运行了。我的phpinfo仍然加载不了MySQL和MySQLi。我只好把PHP目录下的dll和ext下的dll都拷贝到C:\Windows\System32下。（把PHP目录和ext目录加入Path变量也是无效的，我猜测是加载中需要其他位于C盘的dll，UAC认为不在同一个安全级别下给禁止了。）<br />
[singlepic=18185,640,480]<br />
在Web目录下建立index.php，写入一行代码：</p>
<pre class="brush: c#">
&lt;?php phpinfo();?&gt;
</pre>
<p>这个命令会打印PHP的配置情况。看到上面的界面说明PHP安装成功。<br />
[singlepic=18186,640,480]<br />
关键其实不是看上面的界面，而是看MySQL和MySQLi有没有加载，否则一样用不了MySQL。没有MySQL的PHP，不就像没有一样嘛。MySQL和MySQLi成功加载后，应该可以搜索到上图所示的两段。<br />
[singlepic=18188,640,486]<br />
还有些杂事。IIS中要设置一下默认文档（Default Document），一般情况，按照这个顺序：index.htm；index.html；index.php；default.aspx<br />
[singlepic=18190]<br />
装个phpMyAdmin，设置登陆方式为http（libraries下的config.default.php中，默认是config），这样可以每次登陆时弹出对话框验证用户。<br />
[singlepic=18189,640,384]<br />
进入了phpMyAdmin。然后&#8230;<br />
Do what ever you want.</p>
<p><strong>本文图片使用<a href="http://www.nocoo.us/support/">Nocoo.Tools</a>提供的工作窗口截图工具<a href="http://www.nocoo.us/2008/10/screen-capture/">ScreenCapture</a>截取。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2008/10/windows-server-2008-iis-php-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Server 2008下IIS 7.0 FTP使用教程</title>
		<link>http://www.nocoo.us/2008/10/windows-server-2008-iis-ftp/</link>
		<comments>http://www.nocoo.us/2008/10/windows-server-2008-iis-ftp/#comments</comments>
		<pubDate>Sat, 25 Oct 2008 16:00:21 +0000</pubDate>
		<dc:creator>nocoo</dc:creator>
				<category><![CDATA[开发心得]]></category>
		<category><![CDATA[微软技术]]></category>
		<category><![CDATA[服务器和集群技术]]></category>
		<category><![CDATA[Windows Server]]></category>
		<category><![CDATA[微软]]></category>

		<guid isPermaLink="false">http://www.nocoo.us/?p=2986</guid>
		<description><![CDATA[Windows Server 2008是最新的Windows Server。Windows Server 2008公平地说还是相当不错的，性能和安全性都没有太大的问题，稳定更不用说。 这篇文章里，我会详细介绍如何在Windows Server 2008下，安装使用和配置IIS 7.0的FTP服务。 环境说明： 操作系统：Windows Server 2008 Standard Edition，英文版（由Microsoft DreamSpark支持） 相关软件：Internet Information Services 7.0 首先假定IIS已经安装好。如果不会安装IIS，请参阅其他文章。 1. 安装FTP服务 [singlepic=18135,640,462] 在Server Manager中右键Roles中Web Server(IIS)，添加服务器角色（Add Role Service） [singlepic=18136,640,481] 添加的是FTP Publishing Service，同时要添加其他两个依赖项。 2. 配置FTP服务 [singlepic=18137,640,514] 很遗憾地是，Windows Server 2008中，FTP服务仍然需要老版本IIS6的管理器来管理。在管理工具中打开（Internet Information Services（IIS）6.0 Manager），可以看到一个FTP站点。 [singlepic=18138] FTP Site，如端口等如果不希望是TCP 21，那么在这里修改。 [singlepic=18139] Security Accounts，这是一个很危险的选项，默认打开了匿名访问，一定记得关掉。 [singlepic=18141] Home Directory，这里设置FTP的根目录和权限，以及FTP的目录的列表方式，为了兼容性，我设成了UNIX。 [singlepic=18145] Messages，这里可以设置当用户被FTP禁止、连接、离开和达到最大连接数时收到的消息。 [...]]]></description>
			<content:encoded><![CDATA[<p>Windows Server 2008是最新的Windows Server。Windows Server 2008公平地说还是相当不错的，性能和安全性都没有太大的问题，稳定更不用说。</p>
<p>这篇文章里，我会详细介绍如何在Windows Server 2008下，安装使用和配置IIS 7.0的FTP服务。</p>
<h3>环境说明：</h3>
<ul>
<li><strong>操作系统：</strong>Windows Server 2008 Standard Edition，英文版（由Microsoft DreamSpark支持）</li>
<li><strong>相关软件：</strong>Internet Information Services 7.0</li>
</ul>
<p>首先假定IIS已经安装好。如果不会安装IIS，请参阅其他文章。</p>
<h3>1. 安装FTP服务</h3>
<p>[singlepic=18135,640,462]</p>
<p>在Server Manager中右键Roles中Web Server(IIS)，添加服务器角色（Add Role Service）</p>
<p>[singlepic=18136,640,481]</p>
<p>添加的是FTP Publishing Service，同时要添加其他两个依赖项。</p>
<h3>2. 配置FTP服务</h3>
<p>[singlepic=18137,640,514]</p>
<p>很遗憾地是，Windows Server 2008中，FTP服务仍然需要老版本IIS6的管理器来管理。在管理工具中打开（Internet Information Services（IIS）6.0 Manager），可以看到一个FTP站点。</p>
<p>[singlepic=18138]</p>
<p>FTP Site，如端口等如果不希望是TCP 21，那么在这里修改。</p>
<p>[singlepic=18139]</p>
<p>Security Accounts，这是一个很危险的选项，默认打开了匿名访问，一定记得关掉。</p>
<p>[singlepic=18141]</p>
<p>Home Directory，这里设置FTP的根目录和权限，以及FTP的目录的列表方式，为了兼容性，我设成了UNIX。</p>
<p>[singlepic=18145]</p>
<p>Messages，这里可以设置当用户被FTP禁止、连接、离开和达到最大连接数时收到的消息。</p>
<p>[singlepic=18142]</p>
<p>Directory Security，这里可以设置默认的访问方式，默认是允许所有访问，然后除去下列表中的例外。也可以按照计算机IP打开某些访问，而禁止所有其他的连接。</p>
<h3>3. 添加FTP用户</h3>
<p>[singlepic=18147,640,458]</p>
<p>在Windows FTP中，用户是Windows用户。要想添加一个FTP用户，必须添加一个Windows用户，然后去设权限。在Computer Management中，Local Users and Groups下的Users中添加一个普通Windows用户。</p>
<p>[singlepic=18146,640,458]</p>
<p>也许你会担心添加Windows用户会导致安全问题，比如可以远程桌面连接之类，其实不必。首先，添加的Windows用户是普通用户，这样在权限上低于管理员。其次，一个Windows用户要想远程桌面连接服务器，必须同时是Remote Desktop Users这个组的成员，新建用户默认不是的，所以用户不能连接系统。</p>
<p>[singlepic=18143,640,514]</p>
<p>在IIS6 Manager中，右键FTP Site，选择Permissions，把刚才添加的用户赋予FTP权限。其实就是Add，然后找到刚才的用户，然后添加进列表，赋予相应的权限即可。<br />
到这里，常规的FTP就可以连接了。</p>
<h3>4. 高级应用——如何开启Passive Mode</h3>
<p>主流的FTP客户端一般首选Passive Mode去连接FTP服务器，而Windows默认是不允许的。这样的后果就是在FTP客户端登陆时，可以看到通过了用户名密码认证，在列目录时卡住，不能进行。但是使用PORT Mode则可以连接。其实是可以解决的。方法如下：</p>
<p>[singlepic=18148,640,451]</p>
<p>首先，在IIS6 Manager中，右键整个计算机节点，选择属性。</p>
<p>[singlepic=18149]</p>
<p>然后打开Enable Direct Metabase Edit，允许在IIS运行中改变其配置。</p>
<p>[singlepic=18136,640,481]</p>
<p>然后安装IIS 6.0的脚本工具，默认是不安装的，不安装，则在C盘inetpub中就找不到AdminScripts这个文件夹，因为我们需要AdminScripts下的adsutil.vbs这个脚本。安装方法同添加FTP服务，只不过这次需要勾选“IIS 6 Scripting Tools”，同样有几个依赖项需要安装。</p>
<p>[singlepic=18150]</p>
<p>打开一个命令行（Command Prompt），注意，如果你不是Administrator帐户登陆Windows Server 2008，需要邮件使用“Run as administrator”打开，否则权限不足，会提示：</p>
<pre class="brush: c#">
Permission denied
Err Number: 70 (0x46)
Error Trying To Get the Object: MSFTPSVC
</pre>
<p>正常打开后，输入这条命令：</p>
<pre class="brush: c#">CSCRIPT.exe C:\Inetpub\AdminScripts\adsutil.vbs set /MSFTPSVC/PassivePortRange &quot;5500-5515&quot;</pre>
<p>这样可以允许FTP服务在5500到5515这16个端口中选择端口，供FTP客户端使用。需要说明的是，FTP Passive Mode合法的端口号是从5100到65535，但是都打开是明显不安全的，这个参数要根据你的服务器的并发连接数适当选择。</p>
<p>[singlepic=18151]</p>
<p>执行成功会显示：</p>
<pre class="brush: c#">
Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved.

PassivePortRange                : (STRING) &quot;5500-5515&quot;
</pre>
<p>如果你的防火墙是关闭的，那就结<br />
束了，可以在FTP客户端使用FTP Passive Mode连接了。</p>
<h3>5. 高级应用——配置Windows Firewall with Advanced Security</h3>
<p>[singlepic=18152,640,477]</p>
<p>Windows Server 2008默认配置并打开了Windows Firewall with Advanced Security这个高级Windows防火墙，很好很强大。我们刚才设置的16个端口，现在还通不过防火墙，必须加以配置。<br />
下面开启5500到5515这16个端口的入站操作，也可以作为目的是打开某个端口的配置Windows Firewall with Advanced Security的一般方法。<br />
Windows Firewall with Advanced Security区分Inbound Rules和Outbound Rules，分别对应入站和出站规则。FTP Passive Mode的实质其实是FTP Server选取一个没人（其他FTP客户）占用的端口，然后返还给你的FTP客户端，然后FTP客户端使用这个端口去连接FTP服务，这样可以提高并发连接数及并发连接性能。FTP Passive Mode对服务器来说是一种入站操作。<br />
首先打开Windows Firewall with Advanced Security，然后在Inbound Rules上右键建立新的规则（New Rule）</p>
<p>[singlepic=18153,720,512]</p>
<p>在New Inbound Rule Wizard向导的Rule Type中选择Port，因为我们要配置TCP端口。</p>
<p>[singlepic=18154,720,512]</p>
<p>第二步Protocol and Ports中选择TCP端口，因为FTP属于TCP。下面选择Specific local ports指定特定端口，不要全部打开，否则防火墙变成李雷雷了。<br />
遗憾地是，Windows Firewall with Advanced Security不能使用类似5500-5515的IP段（IP Address Range）表达式。不知道这是出于什么考虑，作为微软技术支持者，我不理解为低下的用户体验，而善意地理解为为了避免管理员图方便打开不必要的端口。因此你必须手工填入这16个端口，并用英文逗号分割。</p>
<p>[singlepic=18155,720,512]</p>
<p>Action中决定，对于前面选择的目标，Windows Firewall with Advanced Security采取何种操作。因为FTP是普通应用，不带安全选项，这里选择Allow the connection。</p>
<p>[singlepic=18156,720,512]</p>
<p>Profile中，可以指定连接来源类型，这是在其他防火墙中少见的一层，可以按照Domain，Private和Public来选择，Domain只允许当前AD中的连接，Private只允许本地网络的连接，Public则是所有连接。不用说，安全性又提高不少。</p>
<p>[singlepic=18157,720,512]</p>
<p>Name中，给这条规则取个名字和描述。将来管理方便，不至于在列表里找不到。</p>
<p>[singlepic=18159,640,477]</p>
<p>我们刚才做了什么？允许5500-5515这16个端口的入站连接。还是很不安全的，因为如果一个端口被打开，而没有相应的监听程序，属于一个安全漏洞。理想的状态是，给这条规则指定程序，指定到Windows FTP的服务。可惜我试了多次不能找到FTP的程序到底是哪一个（本来以为是C:\Windows\system32\inetsrv\inetinfo.exe，因为服务是启动了这一个。也不能只指定到FTP Publishing Service这个服务，连接不上）。<br />
选择刚才添加规则的属性。</p>
<p>[singlepic=18160]</p>
<p>在Programs and Services中，选择Services Settings。</p>
<p>[singlepic=18161]</p>
<p>理想的情况应该是Apply to this service中选中FTP Publishing Service，这样就完美了。可惜这样其实连不上。无奈我只好选择了Apply to services only，只允许到系统服务。这样，除非另一个恶意程序把自己注册为系统服务来监听5500到5515这16个端口，其他普通程序是不可以的，安全性稍微提高了一些。<br />
如此，一个完整的Windows Server 2008下IIS 7.0的FTP（支持Passive Mode）就建立起来了。</p>
<p><strong>本文图片使用<a href="http://www.nocoo.us/support/">Nocoo.Tools</a>提供的工作窗口截图工具<a href="http://www.nocoo.us/2008/10/screen-capture/">ScreenCapture</a>截取。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nocoo.us/2008/10/windows-server-2008-iis-ftp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
