<?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>碧云涛小屋 &#187; microsoft</title>
	<atom:link href="http://blog.axqd.net/categories/tech/microsoft/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.axqd.net</link>
	<description>by aXqd</description>
	<lastBuildDate>Tue, 09 Aug 2011 16:12:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
	<atom:link rel='hub' href='http://blog.axqd.net/?pushpress=hub'/>
		<item>
		<title>VB is ungelivable&#8230;</title>
		<link>http://blog.axqd.net/2010/11/18/vb-is-ungelivable/</link>
		<comments>http://blog.axqd.net/2010/11/18/vb-is-ungelivable/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 07:51:48 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[office]]></category>
		<category><![CDATA[macro]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[outlook]]></category>
		<category><![CDATA[vb]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=1046</guid>
		<description><![CDATA[I hate VB&#8230;no reason&#8230; FMU Outlook Macro<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">无觅猜您也喜欢：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2004%2F08%2F03%2Fsecret-word-functions%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">连比尔盖茨都不知道的Word功能</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2005%2F04%2F27%2Fbasic-question-of-c-sharp%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">关于C#一个基础问题的初步探查</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2004%2F11%2F26%2Fsms-tutorial%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">SMS在企业中的应用—微软系列讲座1</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2005%2F06%2F11%2Fiis6-ssl%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">任务稿：IIS6+SSL Based On 2k3</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></description>
			<content:encoded><![CDATA[<p>I hate VB&#8230;no reason&#8230;</p>
<p><a href="http://blog.axqd.net/wp-content/uploads/2010/11/FMU.txt">FMU Outlook Macro</a></p>
<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">无觅猜您也喜欢：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2004%2F08%2F03%2Fsecret-word-functions%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">连比尔盖茨都不知道的Word功能</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2005%2F04%2F27%2Fbasic-question-of-c-sharp%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">关于C#一个基础问题的初步探查</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2004%2F11%2F26%2Fsms-tutorial%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">SMS在企业中的应用—微软系列讲座1</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2005%2F06%2F11%2Fiis6-ssl%2F&from=http%3A%2F%2Fblog.axqd.net%2F2010%2F11%2F18%2Fvb-is-ungelivable%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">任务稿：IIS6+SSL Based On 2k3</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2010/11/18/vb-is-ungelivable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What The C*nt&#8230;</title>
		<link>http://blog.axqd.net/2009/01/04/what-the-cnt/</link>
		<comments>http://blog.axqd.net/2009/01/04/what-the-cnt/#comments</comments>
		<pubDate>Sun, 04 Jan 2009 06:14:03 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=502</guid>
		<description><![CDATA[其他方面不知道，但UI让我只晃了一眼，就求饶不想再看另一眼的，恐怕也非Windows 2k8 Server Core Edition莫属了。 乍看之下，像是中毒之后，explorer被cmd换掉的产物。 唉，工作了就是惨。见过烂的，没见过这么烂的&#8230;]]></description>
			<content:encoded><![CDATA[<p>其他方面不知道，但UI让我只晃了一眼，就求饶不想再看另一眼的，恐怕也非Windows 2k8 Server Core Edition莫属了。</p>
<p>乍看之下，像是中毒之后，explorer被cmd换掉的产物。</p>
<p>唉，工作了就是惨。见过烂的，没见过这么烂的&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2009/01/04/what-the-cnt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>System.Transactions:实现你自己的Resource Manager</title>
		<link>http://blog.axqd.net/2007/02/18/systemtransactions%e5%ae%9e%e7%8e%b0%e4%bd%a0%e8%87%aa%e5%b7%b1%e7%9a%84resource-manager/</link>
		<comments>http://blog.axqd.net/2007/02/18/systemtransactions%e5%ae%9e%e7%8e%b0%e4%bd%a0%e8%87%aa%e5%b7%b1%e7%9a%84resource-manager/#comments</comments>
		<pubDate>Sun, 18 Feb 2007 01:56:32 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=426</guid>
		<description><![CDATA[System.Transactions:实现你自己的Resource Manager By Sahil Malik .net 2.0所带来最大的变化之一也许就是System.Transactions命名空间的引入。在我以前关于SQLCLR的文章中，也简略的提到过这个命名空间。但是谁说事务的概念只能局限于数据库？难道我们在数据库以外的领域就不需要可靠的代码了么?答案是，我们当然需要! 这正是你不能忽视System.Transactions命名空间的原因，也是她将在下一代微软平台引起深刻变革的原因。让我们首先来看看 System.Transactions是如何工作的。 System.Transactions如何工作? System.Transactions为您提供最简洁明了的方式来实现事务方式的各种操作。你当然可以用各种各样的方式使用她，但也许最典型的一个实现就是如下，将事务操作包裹在TransactionScope(用来构建代码段事务的一个实例变量)里面： using (TransactionScope ts = new TransactionScope()) { // 事务代码放这里 ts.Complete(); } 在上面注释的部分里面，你可以使用持有或实现了resource manager(RM)的类。 事务工作于各种被RM管理着的资源上。RM同其他实体(典型的包括：其他进程或者被称为transaction managers(TMs)的服务)协同工作。 RM与TM在事务中协同工作的方式常被称为&#8221;两段提交过程&#8221;。 下面是典型的“两段提交过程”工作流： 1.RM加入事务； 2.RM做完准备工作后，向TM发送第一阶段完成信号。这个阶段也被称为&#8221;准备阶段&#8221;； 3.TM在所有RMs成功执行完准备工作后，向所有RMs发送绿灯信号； 4.RMs获得绿灯信号后实际开始提交工作(如果收到红灯信号，则回滚他们自己的工作)。这是第二个阶段&#8211;&#8221;提交阶段&#8221;； 5.否则，事务协调器同所有RMs进行协调以保证他们要么成功，要么一起回滚； 上面提到的整个过程都由System.Transactions框架提供，例如，使用MSDTC(Microsoft分布式事务协调器)作为TMs。为了使用System.Transactions来管理参与事务操作的资源，你必须要么使用现有的RM或者实现你自己的RM。 就目前而论， System.Transactions已可以使用，但实际能应用的RMs却很少，所以很多程序员可能会发现实现自己的RM非常有用。在这之后，可以将这些RMs同未来.net框架中或第三方提供的TM协同工作。另外，同.net 2.0一同发布的一个很常用的RM就是SqlConnection类。本文中会以此类和一个自定义的RM为例，描述它们究竟如何同TM一起工作。但是，如果你确实不得不实现自己的RM，最重要的问题恐怕就是&#8211;&#8221;RM究竟要做些什么?&#8221; RM究竟要做些什么? 影响实现你自己的RM的一个关键问题就是：这个RM管理的资源本身的特性是持久的还是易变的? 在典型的&#8221;两段提交过程&#8221;中，持久的资源需要&#8221;失败恢复&#8221;。一个很好的例子就是事务文件拷贝。如果你不得不实现一个RM来封装拷贝文件的操作到一个事务中，文件可以在第一个阶段被实际拷贝。如果RM失败，恢复策略将保证在回滚过程中，TM有足够的信息来恢复原来的状态。具体来说，可能就是指删除文件或者用以前存在的文件来代替。这种资源的收集操作，使用System.Transactions.Transaction.EnlistDurable方法。 反之，易变资源是不需要&#8221;失败恢复&#8221;的。同样一个很好的例子，就是持有在内存中的数据。封装这类操作到事务中的RM使用System.Transactions.Transaction.EnlistVolatile方法。 另外一种收集资源的方式是PSPE(可提升的单段式收集)。这种方式由持久的RM拥有事务，当条件改变时，可以逐步升级为由TM管理。因为持久的资源收集比易变的资源收集代价更大，PSPE提供了一种很有吸引力的持久资源收集的实现方式，但是这种方式在许多地方是以牺牲性能为代价的。 在选好资源收集的方式后，接下来你需要实现IEnlistmentNotification接口，以使你从TM获得必要的回调来进行恰当的提交或回滚。 Windows平台的TMs的例子是适合易变资源收集的LTM(轻量级的事务管理器)以及适合分布式或者持久资源收集的MSDTC。 话不多说，下面的例子将向你示范如何实现这些概念。 使用易变资源收集方式实现RM 下面的例子示范了在事务中写成员变量的RM： public class VolatileRM : IEnlistmentNotification { private int [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>System.Transactions:实现你自己的Resource Manager</strong></p>
<p style="text-align: right;">By Sahil Malik</p>
<p>.net 2.0所带来最大的变化之一也许就是System.Transactions命名空间的引入。在我以前关于SQLCLR的文章中，也简略的提到过这个命名空间。但是谁说事务的概念只能局限于数据库？难道我们在数据库以外的领域就不需要可靠的代码了么?答案是，我们当然需要! 这正是你不能忽视System.Transactions命名空间的原因，也是她将在下一代微软平台引起深刻变革的原因。让我们首先来看看 System.Transactions是如何工作的。</p>
<p><strong>System.Transactions如何工作?</strong></p>
<p>System.Transactions为您提供最简洁明了的方式来实现事务方式的各种操作。你当然可以用各种各样的方式使用她，但也许最典型的一个实现就是如下，将事务操作包裹在TransactionScope(用来构建代码段事务的一个实例变量)里面：</p>
<p><code>using (TransactionScope ts = new TransactionScope())<br />
{<br />
// 事务代码放这里<br />
ts.Complete();<br />
}</code></p>
<p>在上面注释的部分里面，你可以使用持有或实现了resource manager(RM)的类。</p>
<p>事务工作于各种被RM管理着的资源上。RM同其他实体(典型的包括：其他进程或者被称为transaction managers(TMs)的服务)协同工作。</p>
<p>RM与TM在事务中协同工作的方式常被称为&#8221;两段提交过程&#8221;。</p>
<p>下面是典型的“两段提交过程”工作流：</p>
<p>1.RM加入事务；<br />
2.RM做完准备工作后，向TM发送第一阶段完成信号。这个阶段也被称为&#8221;准备阶段&#8221;；<br />
3.TM在所有RMs成功执行完准备工作后，向所有RMs发送绿灯信号；<br />
4.RMs获得绿灯信号后实际开始提交工作(如果收到红灯信号，则回滚他们自己的工作)。这是第二个阶段&#8211;&#8221;提交阶段&#8221;；<br />
5.否则，事务协调器同所有RMs进行协调以保证他们要么成功，要么一起回滚；</p>
<p>上面提到的整个过程都由System.Transactions框架提供，例如，使用MSDTC(Microsoft分布式事务协调器)作为TMs。为了使用System.Transactions来管理参与事务操作的资源，你必须要么使用现有的RM或者实现你自己的RM。</p>
<p>就目前而论， System.Transactions已可以使用，但实际能应用的RMs却很少，所以很多程序员可能会发现实现自己的RM非常有用。在这之后，可以将这些RMs同未来.net框架中或第三方提供的TM协同工作。另外，同.net 2.0一同发布的一个很常用的RM就是SqlConnection类。本文中会以此类和一个自定义的RM为例，描述它们究竟如何同TM一起工作。但是，如果你确实不得不实现自己的RM，最重要的问题恐怕就是&#8211;&#8221;RM究竟要做些什么?&#8221;</p>
<p><strong>RM究竟要做些什么?</strong></p>
<p>影响实现你自己的RM的一个关键问题就是：这个RM管理的资源本身的特性是持久的还是易变的?</p>
<p>在典型的&#8221;两段提交过程&#8221;中，持久的资源需要&#8221;失败恢复&#8221;。一个很好的例子就是事务文件拷贝。如果你不得不实现一个RM来封装拷贝文件的操作到一个事务中，文件可以在第一个阶段被实际拷贝。如果RM失败，恢复策略将保证在回滚过程中，TM有足够的信息来恢复原来的状态。具体来说，可能就是指删除文件或者用以前存在的文件来代替。这种资源的收集操作，使用System.Transactions.Transaction.EnlistDurable方法。</p>
<p>反之，易变资源是不需要&#8221;失败恢复&#8221;的。同样一个很好的例子，就是持有在内存中的数据。封装这类操作到事务中的RM使用System.Transactions.Transaction.EnlistVolatile方法。</p>
<p>另外一种收集资源的方式是PSPE(可提升的单段式收集)。这种方式由持久的RM拥有事务，当条件改变时，可以逐步升级为由TM管理。因为持久的资源收集比易变的资源收集代价更大，PSPE提供了一种很有吸引力的持久资源收集的实现方式，但是这种方式在许多地方是以牺牲性能为代价的。</p>
<p>在选好资源收集的方式后，接下来你需要实现IEnlistmentNotification接口，以使你从TM获得必要的回调来进行恰当的提交或回滚。 Windows平台的TMs的例子是适合易变资源收集的LTM(轻量级的事务管理器)以及适合分布式或者持久资源收集的MSDTC。</p>
<p>话不多说，下面的例子将向你示范如何实现这些概念。</p>
<p>使用易变资源收集方式实现RM</p>
<p>下面的例子示范了在事务中写成员变量的RM：</p>
<p><code>public class VolatileRM : IEnlistmentNotification<br />
{<br />
private int memberValue = 0;<br />
private int oldMemberValue = 0;<br />
public int MemberValue<br />
{<br />
get { return memberValue; }<br />
}<br />
public void SetMemberValue(int newMemberValue)<br />
{<br />
Transaction currentTx = Transaction.Current;<br />
if (currentTx != null)<br />
{<br />
Console.WriteLine("VolatileRM: SetMemberValue - EnlistVolatile");<br />
currentTx.EnlistVolatile(this, EnlistmentOptions.None);<br />
}<br />
oldMemberValue = memberValue;<br />
memberValue = newMemberValue;<br />
}<br />
IEnlistmentNotification Members#region IEnlistmentNotification Members<br />
public void Commit(Enlistment enlistment)<br />
{<br />
Console.WriteLine("VolatileRM: Commit");<br />
// Clear out oldMemberValue<br />
oldMemberValue = 0;<br />
}<br />
public void InDoubt(Enlistment enlistment)<br />
{<br />
Console.WriteLine("VolatileRM: InDoubt");<br />
}<br />
public void Prepare(PreparingEnlistment preparingEnlistment)<br />
{<br />
Console.WriteLine("VolatileRM: Prepare");<br />
preparingEnlistment.Prepared();<br />
}<br />
public void Rollback(Enlistment enlistment)<br />
{<br />
Console.WriteLine("VolatileRM: Rollback");<br />
// Restore previous state<br />
memberValue = oldMemberValue;<br />
oldMemberValue = 0;<br />
}<br />
}</code></p>
<p>正如你所看到的那样，我们在SetMemberValue中首先检查了现在是否在事务中。如果是的话，它如下所示，将自己收集进易变事务中，并且为可能的回滚做一些必要的操作：</p>
<p><code>public void SetMemberValue(int newMemberValue)<br />
{<br />
Transaction currentTx = Transaction.Current;<br />
if (currentTx != null)<br />
{<br />
Console.WriteLine("VolatileRM: SetMemberValue - EnlistVolatile");<br />
currentTx.EnlistVolatile(this, EnlistmentOptions.None);<br />
}<br />
oldMemberValue = memberValue;<br />
memberValue = newMemberValue;<br />
}</code></p>
<p>示例中也实现了一系列其他的方法。提交(Commit)、回滚(RollBack)，顾名思义，要么提交工作，要么回滚工作。TM调用Prepare方法来通知RM它正请求第一阶段的事务提交工作，并且测试你的RM是否为工作做好了准备。这里，你有下面三种选择：</p>
<p>1.调用preparingEnlistment.Prepare()方法。</p>
<p>这通知TM你已做好准备，并且正等待下一步提交的通知。</p>
<p>2.调用preparingEnlistment.ForceRollBack()方法或者指定preparingEnlistment.RecoveryInformation。</p>
<p>在重新收集资源的时候，这将提供新的RM实例和完成恢复工作所需要的充足的信息。但是现在你还不必为此担心。</p>
<p>3.调用preparingEnlistment.Done()方法。</p>
<p>这将RM作为旁观者。只观察事务，但并不参与其中。通过调用Done方法，TM不会给你第二阶段的通知。</p>
<p>既然你已经建好了RM，你现在能够依赖框架来编写简单可靠的代码。使用上面的RM是相当轻松惬意的一件事情。例如，键入下面的代码：</p>
<p><code>VolatileRM vrm = null ;<br />
using (TransactionScope txSc = new TransactionScope())<br />
{<br />
vrm = new VolatileRM();<br />
vrm.SetMemberValue(3);<br />
txSc.Complete();<br />
}<br />
Console.WriteLine("Member Value:" + vrm.MemberValue);</code></p>
<p>上面代码产生下面的输出：</p>
<p><code>VolatileRM: SetMemberValue - EnlistVolatile<br />
VolatileRM: Prepare<br />
VolatileRM: Commit<br />
Member Value:3</code></p>
<p>如你所见，成员值被更新了，并且RM在准备和提交阶段得到了相应的通知。</p>
<p>如果你想通过RM实现强制回滚，你可以如下简单的修改RM的Prepare方法：</p>
<p><code>public void Prepare(PreparingEnlistment preparingEnlistment)<br />
{<br />
Console.WriteLine("VolatileRM: Prepare");<br />
preparingEnlistment.ForceRollback();<br />
}</code></p>
<p>这将引起如下异常:</p>
<p><code>The Transaction Has Aborted.</code></p>
<p>事实上，你可以通过适当的preparingEnlistment.RollBack重载方法引起自定义的异常。</p>
<p>另外一种引起回滚的方法是简单的删掉TransactionScope.Complete语句或者在同一个事务中收集其他引起回滚的RM。</p>
<p><code>VolatileRM vrm = null ;<br />
using (TransactionScope txSc = new TransactionScope())<br />
{<br />
vrm = new VolatileRM();<br />
vrm.SetMemberValue(3);<br />
// txSc.Complete();<br />
}<br />
Console.WriteLine("Member Value:" + vrm.MemberValue);</code></p>
<p>当你运行这段代码的时候，将产生如下输出：</p>
<p><code>VolatileRM: SetMemberValue - EnlistVolatile<br />
VolatileRM: Rollback<br />
Member Value: 0</code></p>
<p>你可能觉得这个范例有点不知所云。其实，你通过这个范例可以看到，你能够如此有效的创建与其他RM协同工作的事务代码。例如，你能够将这个非数据库操作的修改成员变量的操作同数据库的事务操作放在同一个事务中。你能够使用如下的T-SQL代码轻松建立数据库：</p>
<p><code>Create Database Test<br />
Go<br />
Create Table Demo<br />
(<br />
DemoValue varchar(5)<br />
)</code></p>
<p>然后通过下面的代码将VolatileRM和两个SqlConnection实例收入同一个事务中：</p>
<p><code>private static string connStr = "Data Source=(local);Initial Catalog=Test;Integrated Security=True";<br />
static void Main(string[] args)<br />
{<br />
VolatileRM vrm = null ;<br />
using (TransactionScope txSc = new TransactionScope())<br />
{<br />
vrm = new VolatileRM();<br />
vrm.SetMemberValue(3);<br />
using (SqlConnection cn = new SqlConnection(connStr))<br />
{<br />
SqlCommand cmd = cn.CreateCommand();<br />
cmd.CommandText = "Insert into Demo(DemoValue) Values ('XXX')";<br />
cn.Open();<br />
cmd.ExecuteNonQuery();<br />
cn.Close();<br />
}<br />
using (SqlConnection cn = new SqlConnection(connStr))<br />
{<br />
SqlCommand cmd = cn.CreateCommand();<br />
cmd.CommandText = "Insert into Demo(DemoValue) Values ('YYY')";<br />
cn.Open();<br />
cmd.ExecuteNonQuery();<br />
cn.Close();<br />
}<br />
Console.WriteLine( "Transaction identifier:" + Transaction.Current.TransactionInformation.DistributedIdentifier);<br />
txSc.Complete();<br />
}<br />
Console.WriteLine("Member Value:" + vrm.MemberValue);<br />
}</code></p>
<p>框架能够通过PSPE自动识别出你的SqlConnection实例已经参与到事务中。当第二个SqlConnection实例出现时，它将在第二个 cn.Open方法被调用时自动将事务提升至MSDTC。你能够通过&#8221;控制面板-&gt;管理工具-&gt;组件服务&#8221;中观察这些操作:</p>
<p>提示: 连接至SQL Server 2005的SqlConnection采用PSPE方式，而连接至SQL Server 2000或更低版本的SqlConnection将采用持久方式，即使在当前事务中仅有一个RM。</p>
<p>当你运行程序时，产生如下输出：</p>
<p><code>VolatileRM: SetMemberValue - EnlistVolatile<br />
Transaction identifier:c40015f6-5086-4688-b565-c65db1cbc8e7<br />
VolatileRM: Prepare<br />
VolatileRM: Commit<br />
Member Value:3</code></p>
<p>如你所见，你依然在收集易变资源。但是，如果需要，你的事务将自动提升至MSDTC，并且获得分布式ID。如果你是架构师，这将给予你两个最好的世界：事务集成和可能最好的性能。你获得这些仅仅需要写如下的简单的代码：</p>
<p><code>Transaction<br />
{<br />
Operation A ;<br />
Operation B ;<br />
....<br />
....<br />
Commit();<br />
}</code></p>
<p>实现基于System.Transactions的事务</p>
<p>现在你已经具备了基于System.Transactions实现事务处理的基础知识。你学到了各种各样的将资源收集到当前事务中的方法，并且看到了自定义RM收集易变资源是多么的简单。</p>
<p><strong>下载代码</strong></p>
<p>下载相关代码，点击<a href="http://www.developer.com/img/2005/11/ResourceMgr.zip">这里</a>。</p>
<p><strong>关于作者</strong></p>
<p>Sahil Malik熟悉从Dos至.Net等许多尖端的微软科技。他是Pro ADO.NET 2.0的作者以及Pro ADO.NET with VB.NET 1.1的合著者。Sahil目前也在基于ADO.NET 2.0的多媒体领域有所建树。他曾被授予微软MVP称号。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2007/02/18/systemtransactions%e5%ae%9e%e7%8e%b0%e4%bd%a0%e8%87%aa%e5%b7%b1%e7%9a%84resource-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>梦寐以求，太强了，自己看，不爽砍我</title>
		<link>http://blog.axqd.net/2005/12/22/perfect/</link>
		<comments>http://blog.axqd.net/2005/12/22/perfect/#comments</comments>
		<pubDate>Thu, 22 Dec 2005 11:07:34 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=418</guid>
		<description><![CDATA[1:拼写检查 2:智能探测Filter 3:色彩 4:无前缀、非前缀智能补写+“结构体”自动补全 还不满足，还有功能不爽，看看附件里面的图，再对照自己的比较一下，差距啊:) 厚道的放出链接: http://www.wholetomato.com/index.html 破解都找到了，我太好了T T Crack for VA_X_Setup1438.exe]]></description>
			<content:encoded><![CDATA[<p>1:拼写检查<br />
<a href="http://blog.axqd.net/wp-content/uploads/2008/07/o_animatespell.gif"><img class="alignnone size-medium wp-image-417" title="Spell Check" src="http://blog.axqd.net/wp-content/uploads/2008/07/o_animatespell.gif" alt="Spell Check" width="285" height="60" /></a></p>
<p>2:智能探测Filter<br />
<a href="http://blog.axqd.net/wp-content/uploads/2008/07/o_animatefilter.gif"><img class="alignnone size-medium wp-image-416" title="Filter" src="http://blog.axqd.net/wp-content/uploads/2008/07/o_animatefilter.gif" alt="Filter" width="254" height="274" /></a></p>
<p>3:色彩<br />
<a href="http://blog.axqd.net/wp-content/uploads/2008/07/o_animatecolor.gif"><img class="alignnone size-medium wp-image-415" title="Color" src="http://blog.axqd.net/wp-content/uploads/2008/07/o_animatecolor-300x50.gif" alt="Color" width="300" height="50" /></a></p>
<p>4:无前缀、非前缀智能补写+“结构体”自动补全<br />
<a href="http://blog.axqd.net/wp-content/uploads/2008/07/o_animateacronym.gif"><img class="alignnone size-medium wp-image-414" title="Acronym" src="http://blog.axqd.net/wp-content/uploads/2008/07/o_animateacronym.gif" alt="Acronym" width="258" height="60" /></a></p>
<p>还不满足，还有功能不爽，看看附件里面的图，再对照自己的比较一下，差距啊:)</p>
<p>厚道的放出链接:</p>
<p>http://www.wholetomato.com/index.html</p>
<p>破解都找到了，我太好了T T</p>
<p><a href="http://blog.axqd.net/wp-content/uploads/2008/07/crack.rar">Crack for VA_X_Setup1438.exe</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/12/22/perfect/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Browser Helper Object</title>
		<link>http://blog.axqd.net/2005/12/16/browser-helper-object/</link>
		<comments>http://blog.axqd.net/2005/12/16/browser-helper-object/#comments</comments>
		<pubDate>Fri, 16 Dec 2005 10:59:00 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=411</guid>
		<description><![CDATA[那天有个信息安全实验室的博士生叫我们做IE插件，主要用于拦截IE浏览器的各项消息，从而做出我们自己的处理。 实现方法，当然千奇百怪，全局钩子函数，进程注入，消息拦截等等都可以，不过我最终选择了全局钩子函数，感觉应该好做一点。 由于最近比较多接触C#，第一反映当然还是.net framework。 MSDN-&#62;Filter:c#-&#62;“全局钩子”一找，郁闷死人： 在 .NET 框架中不支持全局挂钩 您无法在 Microsoft .NET 框架中实现全局挂钩。若要安装全局挂钩，挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个 DLL 导出，而 .NET 框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念，因为这些函数是动态构建的代理。 [http://support.microsoft.com/kb/318804] 当然，其实这段文字本身有点问题，先不说网上有人说好像并不是所有的全局挂钩都不能加载，但就.net支持对非受控代码的访问这点，就可以通过在中间增加一层Managed Code-&#62;UnManaged Code-&#62;Managed Code实现调用。 但是这样的实现难度陡增，很是麻烦。不过在搜索结果中看到一个比较乖的咚咚：Browser Helper Object，看起来感觉比较象。 记得以前有篇写Office Doc Object架构的文章很有名(好像小排发过吧)，不过记忆中，当时看了一点就放弃了，感觉挺麻烦的。特别是针对COM组件的调用部分，看着就头大。 话说回来，调用COM组件在.net环境下，还是C++来得方便快捷，毕竟都是非受控的代码，不用处理太多受控、非受控对象之间的交互问题。不过C++.net依然还是VC++6.0的模样，看着都恶心，于是乎放弃:P 粗粗看了看Browser Helper Object(BHO)的机理，这个咚咚主要用于下面的场景： 想实现一个浏览器，提供一些自己的功能，但是如果用IE Control来写的话，还要自己写很多很多很多诸如：前进、后退、历史记录等等IE已经提供的功能，所以更简便的方法是给扩展、修改IE的功能，直接使用IE来实现。这方面，当然不能不提很多人深恶痛绝的3721，他提供了一个个性化的浏览器，却只写了很少的代码，其余的都是IE自带的内容。 打开一个IE，打开Spy++，再结合Internet Explorer 4.0 Architecture的图看看 举个例子，如果想要获取IE地址栏的内容： IEExplorer-&#62;IEFrame-&#62;WorkerW-&#62;ReBarWindow32-&#62;ComboBoxEx32-&#62;ComboBox-&#62;Edit 这就是他的层次结构 IE和Explorer在启动新线程的时候(Explorer要看看选项里面是否选择了在新的线程中打开窗口)，会检查注册表项： [HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects] 他下面有很多子项，每一个子项就是一个GUID 例如： {06849E9F-C8D7-4D59-B87D-784B7D6BE0B3} 这个GUID对应一个BHO组件(其实就是一个COM组件) 这个组件在[HKLM\SOFTWARE\Classes\CLSID]下面进行描述，包括dll路径，签名等等信息 IE或Explorer在每个线程里会依次实例化每个在上述路径注册的BHO对象，从而BHO对象实际上运行在IE或Explorer的地址空间内，并且能够访问IE的几乎所有资源，拦截几乎所有事件，挂载自己的事件处理函数，而不需要跨进程调用和传消息。 看来完全符合最初的应用要求并且是最简单的方法了。 接下来的问题，就只剩下COM组件的使用了。.NET对COM组件的调用提供了很方便的100% pure [...]]]></description>
			<content:encoded><![CDATA[<p>那天有个信息安全实验室的博士生叫我们做IE插件，主要用于拦截IE浏览器的各项消息，从而做出我们自己的处理。</p>
<p>实现方法，当然千奇百怪，全局钩子函数，进程注入，消息拦截等等都可以，不过我最终选择了全局钩子函数，感觉应该好做一点。</p>
<p>由于最近比较多接触C#，第一反映当然还是.net framework。<br />
MSDN-&gt;Filter:c#-&gt;“全局钩子”一找，郁闷死人：</p>
<p>在 .NET 框架中不支持全局挂钩</p>
<p>您无法在 Microsoft .NET 框架中实现全局挂钩。若要安装全局挂钩，挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个 DLL 导出，而 .NET 框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念，因为这些函数是动态构建的代理。<br />
[http://support.microsoft.com/kb/318804]</p>
<p>当然，其实这段文字本身有点问题，先不说网上有人说好像并不是所有的全局挂钩都不能加载，但就.net支持对非受控代码的访问这点，就可以通过在中间增加一层Managed Code-&gt;UnManaged Code-&gt;Managed Code实现调用。</p>
<p>但是这样的实现难度陡增，很是麻烦。不过在搜索结果中看到一个比较乖的咚咚：Browser Helper Object，看起来感觉比较象。</p>
<p>记得以前有篇写Office Doc Object架构的文章很有名(好像小排发过吧)，不过记忆中，当时看了一点就放弃了，感觉挺麻烦的。特别是针对COM组件的调用部分，看着就头大。</p>
<p>话说回来，调用COM组件在.net环境下，还是C++来得方便快捷，毕竟都是非受控的代码，不用处理太多受控、非受控对象之间的交互问题。不过C++.net依然还是VC++6.0的模样，看着都恶心，于是乎放弃:P</p>
<p>粗粗看了看Browser Helper Object(BHO)的机理，这个咚咚主要用于下面的场景：</p>
<p>想实现一个浏览器，提供一些自己的功能，但是如果用IE Control来写的话，还要自己写很多很多很多诸如：前进、后退、历史记录等等IE已经提供的功能，所以更简便的方法是给扩展、修改IE的功能，直接使用IE来实现。这方面，当然不能不提很多人深恶痛绝的3721，他提供了一个个性化的浏览器，却只写了很少的代码，其余的都是IE自带的内容。</p>
<p>打开一个IE，打开Spy++，再结合Internet Explorer 4.0 Architecture的图看看</p>
<p><a href="http://blog.axqd.net/wp-content/uploads/2008/07/o_internet-explorer-40-architecture.jpg"><img class="alignnone size-medium wp-image-412" title="Internet Explorer 4.0 Architecture" src="http://blog.axqd.net/wp-content/uploads/2008/07/o_internet-explorer-40-architecture-300x191.jpg" alt="Internet Explorer 4.0 Architecture" width="300" height="191" /></a></p>
<p>举个例子，如果想要获取IE地址栏的内容：<br />
IEExplorer-&gt;IEFrame-&gt;WorkerW-&gt;ReBarWindow32-&gt;ComboBoxEx32-&gt;ComboBox-&gt;Edit<br />
这就是他的层次结构</p>
<p>IE和Explorer在启动新线程的时候(Explorer要看看选项里面是否选择了在新的线程中打开窗口)，会检查注册表项：</p>
<p><code>[HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects]</code></p>
<p>他下面有很多子项，每一个子项就是一个GUID<br />
例如：<br />
{06849E9F-C8D7-4D59-B87D-784B7D6BE0B3}</p>
<p>这个GUID对应一个BHO组件(其实就是一个COM组件)<br />
这个组件在[HKLM\SOFTWARE\Classes\CLSID]下面进行描述，包括dll路径，签名等等信息</p>
<p>IE或Explorer在每个线程里会依次实例化每个在上述路径注册的BHO对象，从而BHO对象实际上运行在IE或Explorer的地址空间内，并且能够访问IE的几乎所有资源，拦截几乎所有事件，挂载自己的事件处理函数，而不需要跨进程调用和传消息。</p>
<p>看来完全符合最初的应用要求并且是最简单的方法了。</p>
<p>接下来的问题，就只剩下COM组件的使用了。.NET对COM组件的调用提供了很方便的100% pure 受控的访问方式 &#8211; Interop， Marshal。查错过程比较艰辛，因为每次重新生成都要重启Explorer.exe T T并且调试的时候，要先开IE，再下断点，再将VS .NET附加到IE进程，再点新建IE窗口&#8230;</p>
<p>COM组件的使用：<br />
首先，当然是用Create GUID工具生成我们自己BHO组件的GUID({B29E305D-BC4D-4a80-B522-B0ABC9EBDFFC})，然后添加对 Microsoft Internet Controls COM组件(%systemroot%\ShDocVw.dll)的引用。VS.NET会自动Wrapper之为 Interop.SHDocVw.dll，值得注意的是，这里由于最后要使用BHO注册，所以要求这个COM组件必须用私钥签名，从而使用强名机制。具体步骤如下：<br />
1、sn -k BHO.key生成Bho.key文件，也就是我们的私钥。<br />
2、设置项目属性，ActiveX/COM对象的包装程序集-&gt;包装程序集密钥文件，指向Bho.key<br />
3、添加COM引用(此时查看相关信息就可以看到强名选项已设为true)<br />
4、设置AssemblyInfo.cs填写key字段，指向Bho.key</p>
<p>然后，就可以声明我们要继承的各项接口：</p>
<p><code> using SHDocVw;<br />
 #region 引入IObjectWithSite接口<br />
 [ComImport(), Guid("fc4801a3-2ba9-11cf-a229-00aa003d7352")]<br />
 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]<br />
 public interface IObjectWithSite<br />
 {<br />
  void SetSite([In ,MarshalAs(UnmanagedType.IUnknown)] object site);<br />
  void GetSite(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object site);<br />
 }<br />
 #endregion<br />
 #region 定义默认BHO COM接口<br />
 [GuidAttribute("181C179B-7CC9-4457-8C1D-4B45E7C8589D")]<br />
 [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]<br />
 public interface IObserver<br />
 {<br />
 }<br />
 #endregion</code></p>
<p>然后定义我们自己的BHO类：</p>
<p><code> /// &lt;summary&gt;<br />
 ///定义BHO类,此类由浏览器实例化<br />
 /// &lt;/summary&gt;<br />
 [ClassInterfaceAttribute(ClassInterfaceType.None)]<br />
 [GuidAttribute("B29E305D-BC4D-4a80-B522-B0ABC9EBDFFC")]//由CreateGUID程序生成<br />
 [ProgIdAttribute("Observer.BrowserMonitor")]<br />
 public class BrowserMonitor : IObserver, IObjectWithSite<br />
 {}</code></p>
<p>这个类里面如下引入定义：</p>
<p><code>  protected IWebBrowser2 browser; //浏览器对象<br />
  protected DWebBrowserEvents2_Event  browserEvents;//浏览器事件</code></p>
<p>并且实现IObjectWithSite接口：</p>
<p><code>  #region IObjectWithSite 成员<br />
  /// &lt;summary&gt;<br />
  /// IE调用此方法,并传递指向容器Site的IUnknown指针,由此我们可以获得IWebBrowser2接口<br />
  /// 并挂载DWebBrowserEvents2事件<br />
  /// &lt;/summary&gt;<br />
  /// &lt;param name="site"&gt;容器Site的IUnknown指针&lt;/param&gt;<br />
  public void SetSite(object site)<br />
  {<br />
   // TODO:  添加 BrowserMonitor.SetSite 实现<br />
   #region 取得 IWebBrowser2 引用<br />
   if (browser != null)<br />
    Release();<br />
   if (site == null)<br />
    return;<br />
   browser = site as IWebBrowser2;<br />
   #endregion<br />
   #region 检查名称,当且仅当为IEXPLORE.EXE时加载<br />
   string hostName = browser.FullName;<br />
   if (!(hostName.ToUpper().EndsWith("IEXPLORE.EXE")))<br />
   {<br />
    Release();<br />
    return;<br />
   }<br />
   #endregion<br />
   #region 挂载浏览器事件<br />
   browserEvents = browser as DWebBrowserEvents2_Event ;<br />
   if (browserEvents != null)<br />
   {<br />
    browserEvents.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);<br />
   }<br />
   else<br />
   {<br />
    Release();<br />
    return;<br />
   }<br />
   #endregion<br />
  }<br />
  /// &lt;summary&gt;<br />
  /// 调用者调用此方法以获得前面浏览器发送给SetSite()方法的浏览器对象<br />
  /// &lt;/summary&gt;<br />
  /// &lt;param name="guid"&gt;请求Site接口对象的GUID&lt;/param&gt;<br />
  /// &lt;param name="site"&gt;返回的Site接口对象&lt;/param&gt;<br />
  public void GetSite(ref System.Guid guid, out object site)<br />
  {<br />
   // TODO:  添加 BrowserMonitor.GetSite 实现<br />
   site = null;<br />
   if (browser != null)<br />
   {<br />
    IntPtr pSite = IntPtr.Zero;<br />
    IntPtr pUnk = Marshal.GetIUnknownForObject(browser); //引用计数增加<br />
    Marshal.QueryInterface(pUnk, ref guid, out pSite); //引用计数增加<br />
    Marshal.Release(pUnk);  //引用计数减少<br />
    Marshal.Release(pUnk); //引用计数减少<br />
    if (!pSite.Equals(IntPtr.Zero))<br />
    {<br />
     site = pSite;<br />
    }<br />
    else<br />
    {<br />
     // 若找不到请求的接口，将返回E_NOINTERFACE<br />
     Release();<br />
     Marshal.ThrowExceptionForHR(E_NOINTERFACE);<br />
    }<br />
   }<br />
   else<br />
   {<br />
    // 若找不到请求的接口对象，将返回E_FAIL<br />
    Release();<br />
    Marshal.ThrowExceptionForHR(E_FAIL);<br />
   }<br />
  }<br />
  #endregion</code></p>
<p>这里挂载了我们自己的事件处理函数，处理DocumentComplete事件，此外还有很多事件可以使用，例如：</p>
<p><code> DownloadBegin<br />
 DownloadComplete<br />
 BeforeNavigate2<br />
 CommandStateChange<br />
 FileDownload<br />
 NavigateComplete<br />
 NewWindow<br />
 FullScreen<br />
 MenuBar<br />
 Quit<br />
 FrameBeforeNavigate<br />
 FrameNavigateComplete<br />
 FrameNewWindow<br />
 ProgressChange<br />
 PropertyChange<br />
 StatusTextChange<br />
 TitleChange<br />
 WindowActivate<br />
 WindowMove<br />
 WindowResize</code></p>
<p><code> using System.IO;<br />
 #region 用于挂载的自定义函数<br />
 protected void OnDocumentComplete(object display, ref object url)<br />
 {<br />
  try<br />
  {<br />
   if (Marshal.Equals(browser, display))<br />
   {<br />
    StreamWriter sw = new StreamWriter(@"C:\Test.txt", true);<br />
    sw.WriteLine(url.ToString());<br />
    sw.Close();<br />
   }<br />
  }<br />
  catch<br />
  {<br />
   Release();<br />
   Marshal.ThrowExceptionForHR(E_FAIL);<br />
  }<br />
 }<br />
 #endregion</code></p>
<p>此外，关于错误处理，由于涉及包裹为受控组件的非受控组件，所以需要使用以下方式抛出异常：</p>
<p><code>  #region 定义HRESULT值 : 预定义的COMException值<br />
  //在未检查的上下文中，如果表达式产生目标类型范围之外的值，则结果被截断<br />
  const int E_FAIL = unchecked((int)0x80004005);//失败<br />
  const int E_NOINTERFACE = unchecked((int)0x80004002);//QueryInterface时,接口不存在<br />
  #endregion<br />
  Marshal.ThrowExceptionForHR(E_FAIL);<br />
  Marshal.ThrowExceptionForHR(E_NOINTERFACE);</code></p>
<p>使用一下方式，释放对象：</p>
<p><code>  #region Release操作<br />
  protected void Release()<br />
  {<br />
   if (browserEvents != null)<br />
   {<br />
    Marshal.ReleaseComObject(browserEvents);<br />
    browserEvents = null;<br />
   }<br />
   if (browser != null)<br />
   {<br />
    Marshal.ReleaseComObject(browser);<br />
    browser = null;<br />
   }<br />
  }<br />
  #endregion</code></p>
<p>至此已基本完成，但是要想自动注册BHO组件，还需要做几件事情：</p>
<p><code>  #region 挂载注册/注销操作<br />
  /// &lt;summary&gt;<br />
  /// 在注册COM组件时,由运行时调用<br />
  /// &lt;/summary&gt;<br />
  [ComRegisterFunctionAttribute]<br />
  public static void Register(Type type)<br />
  {<br />
   // 注册BHO组件<br />
   string guid = type.GUID.ToString("B");<br />
   RegistryKey rkey =<br />
    Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects");<br />
   RegistryKey rkeyBHO = rkey.CreateSubKey(guid);<br />
  }<br />
  /// &lt;summary&gt;<br />
  /// 在注销COM组件时,由运行时调用<br />
  /// &lt;/summary&gt;<br />
  [ComUnregisterFunctionAttribute]<br />
  public static void Unregister(Type type)<br />
  {<br />
   // 注销BHO组件<br />
   string guid = type.GUID.ToString("B");<br />
   RegistryKey rkey =<br />
    Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects");<br />
   rkey.DeleteSubKey(guid,false);<br />
  }<br />
  #endregion</code></p>
<p>由这些可见.NET平台对于COM组件的调用支持还是相当强大的，可以在受控环境下实现100% pure的COM访问能力。</p>
<p>PS:<br />
结尾怎么写成这样了，写一写的就有点偏题了- -</p>
<p><a href='http://blog.axqd.net/wp-content/uploads/2008/07/bho.rar'>BHO Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/12/16/browser-helper-object/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Cached FlyWeight</title>
		<link>http://blog.axqd.net/2005/12/07/cached-flyweight/</link>
		<comments>http://blog.axqd.net/2005/12/07/cached-flyweight/#comments</comments>
		<pubDate>Wed, 07 Dec 2005 10:53:49 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=409</guid>
		<description><![CDATA[其实因为C#语言自身的一些特点，和FlyWeight的实现方式不太一样- - 初学，不足之处见谅:) 详细叙述见附件 ======2005-12-13====== 作了一些修改，使用方式不变，不过加入了对任何单参数构造函数的支持。 有人问，为什么不支持任何多参数构造函数， 因为实际上参数就是缓存时用于查找的Key，多参数生成Key的时候较麻烦而已：） 最后，说明一点，本FlyWeight在Scavenging的时候，会根据使用的情况，删除最不常使用的Key ======2006-1-19======= VS2005发布后，更新版本 Download Fly Weight]]></description>
			<content:encoded><![CDATA[<p>其实因为C#语言自身的一些特点，和FlyWeight的实现方式不太一样- -</p>
<p>初学，不足之处见谅:)</p>
<p>详细叙述见附件</p>
<p>======2005-12-13======</p>
<p>作了一些修改，使用方式不变，不过加入了对任何单参数构造函数的支持。</p>
<p>有人问，为什么不支持任何多参数构造函数， 因为实际上参数就是缓存时用于查找的Key，多参数生成Key的时候较麻烦而已：）</p>
<p>最后，说明一点，本FlyWeight在Scavenging的时候，会根据使用的情况，删除最不常使用的Key</p>
<p>======2006-1-19=======</p>
<p>VS2005发布后，更新版本</p>
<p><a href="http://blog.axqd.net/wp-content/uploads/2008/07/axqd_design.rar">Download Fly Weight</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/12/07/cached-flyweight/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>C#中调用Windows API的要点</title>
		<link>http://blog.axqd.net/2005/11/26/c-sharp-and-windows-api/</link>
		<comments>http://blog.axqd.net/2005/11/26/c-sharp-and-windows-api/#comments</comments>
		<pubDate>Sat, 26 Nov 2005 08:50:20 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=312</guid>
		<description><![CDATA[在.Net Framework SDK文档中，关于调用Windows API的指示比较零散，并且其中稍全面一点的是针对Visual Basic .net讲述的。本文将C#中调用API的要点汇集如下，希望给未在C#中使用过API的朋友一点帮助。另外如果安装了Visual Studio .net的话，在C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\Technologies\Interop\PlatformInvoke\WinAPIs\CS 目录下有大量的调用API的例子。 一、调用格式 using System.Runtime.InteropServices; //引用此名称空间，简化后面的代码 ... //使用DllImportAttribute特性来引入api函数，注意声明的是空方法，即方法体为空。 [DllImport("user32.dll")] public static extern ReturnType FunctionName(type arg1,type arg2,...); //调用时与调用其他方法并无区别，可以使用字段进一步说明特性，用逗号隔开，如： [ DllImport( "kernel32", EntryPoint="GetVersionEx" )] DllImportAttribute特性的公共字段如下： 1、CallingConvention 指示向非托管实现传递方法参数时所用的CallingConvention 值。 CallingConvention.Cdecl : 调用方清理堆栈。它使您能够调用具有 varargs 的函数。 CallingConvention.StdCall : 被调用方清理堆栈。它是从托管代码调用非托管函数的默认约定。 2、CharSet 控制调用函数的名称版本及指示如何向方法封送 String 参数。 此字段被设置为 CharSet 值之一。如果 CharSet 字段设置为 Unicode，则所有字符串参数在传递到非托管实现之前都转换成 [...]]]></description>
			<content:encoded><![CDATA[<p>在.Net Framework SDK文档中，关于调用Windows API的指示比较零散，并且其中稍全面一点的是针对Visual Basic .net讲述的。本文将C#中调用API的要点汇集如下，希望给未在C#中使用过API的朋友一点帮助。另外如果安装了Visual Studio .net的话，在C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\Technologies\Interop\PlatformInvoke\WinAPIs\CS 目录下有大量的调用API的例子。</p>
<p><strong>一、调用格式</strong><br />
<code>using System.Runtime.InteropServices; //引用此名称空间，简化后面的代码<br />
...<br />
//使用DllImportAttribute特性来引入api函数，注意声明的是空方法，即方法体为空。<br />
[DllImport("user32.dll")]<br />
public static extern ReturnType FunctionName(type arg1,type arg2,...);<br />
//调用时与调用其他方法并无区别，可以使用字段进一步说明特性，用逗号隔开，如：<br />
[ DllImport( "kernel32", EntryPoint="GetVersionEx" )]</code></p>
<p>DllImportAttribute特性的公共字段如下：</p>
<p><strong>1、CallingConvention 指示向非托管实现传递方法参数时所用的CallingConvention 值。</strong><br />
CallingConvention.Cdecl : 调用方清理堆栈。它使您能够调用具有 varargs 的函数。<br />
CallingConvention.StdCall : 被调用方清理堆栈。它是从托管代码调用非托管函数的默认约定。</p>
<p><strong>2、CharSet 控制调用函数的名称版本及指示如何向方法封送 String 参数。</strong><br />
此字段被设置为 CharSet 值之一。如果 CharSet 字段设置为 Unicode，则所有字符串参数在传递到非托管实现之前都转换成 Unicode 字符。这还导致向 DLL EntryPoint 的名称中追加字母“W”。如果此字段设置为 Ansi，则字符串将转换成 ANSI 字符串，同时向 DLL EntryPoint 的名称中追加字母“A”。大多数 Win32 API 使用这种追加“W”或“A”的约定。如果 CharSet 设置为 Auto，则这种转换就是与平台有关的（在 Windows NT 上为 Unicode，在 Windows 98 上为 Ansi）。CharSet 的默认值为 Ansi。CharSet 字段也用于确定将从指定的 DLL 导入哪个版本的函数。CharSet.Ansi 和 CharSet.Unicode 的名称匹配规则大不相同。<br />
对于 Ansi 来说，如果将 EntryPoint 设置为“MyMethod”且它存在的话，则返回“MyMethod”。如果 DLL 中没有“MyMethod”，但存在“MyMethodA”，则返回“MyMethodA”。对于 Unicode 来说则正好相反。如果将 EntryPoint 设置为“MyMethod”且它存在的话，则返回“MyMethodW”。如果 DLL 中不存在“MyMethodW”，但存在“MyMethod”，则返回“MyMethod”。如果使用的是 Auto，则匹配规则与平台有关（在 Windows NT 上为 Unicode，在 Windows 98 上为 Ansi）。如果 ExactSpelling 设置为 true，则只有当 DLL 中存在“MyMethod”时才返回“MyMethod”。</p>
<p><strong>3、EntryPoint 指示要调用的 DLL 入口点的名称或序号。</strong><br />
如果你的方法名不想与api函数同名的话，一定要指定此参数,例如：<br />
<code>[DllImport("user32.dll",CharSet="CharSet.Auto",EntryPoint="MessageBox")]<br />
public static extern int MsgBox(IntPtr hWnd,string txt,string caption, int type);</code></p>
<p><strong>4、ExactSpelling 指示是否应修改非托管 DLL 中的入口点的名称，以与 CharSet 字段中指定的 CharSet 值相对应。</strong><br />
如果为 true，则当 DllImportAttribute.CharSet 字段设置为 CharSet 的 Ansi 值时，向方法名称中追加字母 A，当 DllImportAttribute.CharSet 字段设置为 CharSet 的 Unicode 值时，向方法的名称中追加字母 W。此字段的默认值是 false。</p>
<p><strong>5、PreserveSig 指示托管方法签名不应转换成返回 HRESULT、并且可能有一个对应于返回值的附加 [out, retval] 参数的非托管签名。</strong></p>
<p><strong>6、SetLastError 指示被调用方在从属性化方法返回之前将调用 Win32 API SetLastError。</strong><br />
true 指示调用方将调用 SetLastError，默认为 false。运行时封送拆收器将调用 GetLastError 并缓存返回的值，以防其被其他 API 调用重写。用户可通过调用 GetLastWin32Error 来检索错误代码。</p>
<p><strong>二、参数类型：</strong><br />
<strong>1、数值型直接用对应的就可。（DWORD -&gt; int , WORD -&gt; Int16）</strong></p>
<p><strong>2、API中字符串指针类型 -&gt; .net中string</strong></p>
<p><strong>3、API中句柄 (dWord) -&gt; .net中IntPtr</strong></p>
<p><strong>4、API中结构 -&gt; .net中结构或者类。</strong><br />
注意这种情况下，要先用StructLayout特性限定声明结构或类<br />
公共语言运行库利用StructLayoutAttribute控制类或结构的数据字段在托管内存中的物理布局,即类或结构需要按某种方式排列。如果要将类传递给需要指定布局的非托管代码，则显式控制类布局是重要的。它的构造函数中用LayoutKind值初始化 StructLayoutAttribute 类的新实例。 LayoutKind.Sequential 用于强制将成员按其出现的顺序进行顺序布局。<br />
LayoutKind.Explicit 用于控制每个数据成员的精确位置。利用 Explicit，每个成员必须使用 FieldOffsetAttribute 指示此字段在类型中的位置。如：<br />
<code>[StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]<br />
public class MySystemTime<br />
{<br />
[FieldOffset(0)]public ushort wYear;<br />
[FieldOffset(2)]public ushort wMonth;<br />
[FieldOffset(4)]public ushort wDayOfWeek;<br />
[FieldOffset(6)]public ushort wDay;<br />
[FieldOffset(8)]public ushort wHour;<br />
[FieldOffset(10)]public ushort wMinute;<br />
[FieldOffset(12)]public ushort wSecond;<br />
[FieldOffset(14)]public ushort wMilliseconds;<br />
}</code><br />
下面是针对API中OSVERSIONINFO结构，在.net中定义对应类或结构的例子：<br />
<code>/**********************************************<br />
* API中定义原结构声明<br />
* OSVERSIONINFOA STRUCT<br />
* dwOSVersionInfoSize DWORD ?<br />
* dwMajorVersion DWORD ?<br />
* dwMinorVersion DWORD ?<br />
* dwBuildNumber DWORD ?<br />
* dwPlatformId DWORD ?<br />
* szCSDVersion BYTE 128 dup (?)<br />
* OSVERSIONINFOA ENDS<br />
*<br />
* OSVERSIONINFO equ<br />
*********************************************/<br />
//.net中声明为类<br />
[ StructLayout( LayoutKind.Sequential )]<br />
public class OSVersionInfo<br />
{<br />
public int OSVersionInfoSize;<br />
public int majorVersion;<br />
public int minorVersion;<br />
public int buildNumber;<br />
public int platformId;<br />
[MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]<br />
public String versionString;<br />
}<br />
//或者<br />
//.net中声明为结构<br />
[ StructLayout( LayoutKind.Sequential )]<br />
public struct OSVersionInfo2<br />
{<br />
public int OSVersionInfoSize;<br />
public int majorVersion;<br />
public int minorVersion;<br />
public int buildNumber;<br />
public int platformId;<br />
[MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]<br />
public String versionString;<br />
}</code><br />
此例中用到MashalAs特性，它用于描述字段、方法或参数的封送处理格式。用它作为参数前缀并指定目标需要的数据类型。例如，以下代码将两个参数作为数据类型长指针封送给 Windows API 函数的字符串 (LPStr)：<br />
<code>[MarshalAs(UnmanagedType.LPStr)]<br />
String existingfile;<br />
[MarshalAs(UnmanagedType.LPStr)]<br />
String newfile;</code><br />
注意结构作为参数时候，一般前面要加上ref修饰符，否则会出现错误：对象的引用没有指定对象的实例。<br />
<code>[DllImport("kernel32", EntryPoint="GetVersionEx")]<br />
public static extern bool GetVersionEx2(ref OSVersionInfo2 osvi);</code></p>
<p><strong>三、如何保证使用托管对象的平台调用成功？</strong><br />
如果在调用平台 invoke 后的任何位置都未引用托管对象，则垃圾回收器可能将完成该托管对象。这将释放资源并使句柄无效，从而导致平台invoke 调用失败。用 HandleRef 包装句柄可保证在平台 invoke 调用完成前，不对托管对象进行垃圾回收。<br />
例如下面：<br />
<code>FileStream fs = new FileStream( "a.txt", FileMode.Open );<br />
StringBuilder buffer = new StringBuilder( 5 );<br />
int read = 0;<br />
ReadFile(fs.Handle, buffer, 5, out read, 0 ); //调用Win API中的ReadFile函数</code><br />
由于fs是托管对象，所以有可能在平台调用还未完成时候被垃圾回收站回收。将文件流的句柄用HandleRef包装后，就能避免被垃圾站回收:<br />
<code>[DllImport( "Kernel32.dll" )]<br />
public static extern bool ReadFile(<br />
HandleRef hndRef,<br />
StringBuilder buffer,<br />
int numberOfBytesToRead,<br />
out int numberOfBytesRead,<br />
ref Overlapped flag );<br />
......<br />
......<br />
FileStream fs = new FileStream( "HandleRef.txt", FileMode.Open );<br />
HandleRef hr = new HandleRef( fs, fs.Handle );<br />
StringBuilder buffer = new StringBuilder( 5 );<br />
int read = 0;<br />
// platform invoke will hold reference to HandleRef until call ends<br />
ReadFile( hr, buffer, 5, out read, 0 );</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/11/26/c-sharp-and-windows-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>发布Web Services</title>
		<link>http://blog.axqd.net/2005/09/30/%e5%8f%91%e5%b8%83web-services/</link>
		<comments>http://blog.axqd.net/2005/09/30/%e5%8f%91%e5%b8%83web-services/#comments</comments>
		<pubDate>Fri, 30 Sep 2005 10:40:49 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=404</guid>
		<description><![CDATA[笔记本上Release后一切正常的Web Services，部署到另外一台2003的服务器上，出现两个问题： 1、Critical Error： &#8230;没有权限访问注册表 其实只是在写入EventLog的时候ASPNET的权限不够，不过奇怪的是把ASPNET和匿名帐户加入Administrator组，重启，好像权限还是不够&#62;.&#60; 查看其列出的跟踪堆栈，发现好像是Enterprise Library中ADO.NET连接数据库的问题，在网上查了查，有用的文章不多，最后居然就在EntLib的FAQ里,发现是没有正确部署EnterLib程序集的问题。 安装程序工具(Installutil.exe) 允许通过执行指定程序集的安装程序组件来安装和卸载服务器资源。 注意: 在“%windir%\Microsoft.NET\Framework\v1.1.xxxx”中可以找到Installutil.exe，其中xxxx是您使用的 .NET Framework 的内部版本号。 Installutil Microsoft.Practices.EnterpriseLibrary.Common.dll Installutil Microsoft.Practices.EnterpriseLibrary.Configuration.dll Installutil Microsoft.Practices.EnterpriseLibrary.Data.dll 一切恢复正常。 不过还是不知道为什么他的程序集部署的时候必须Install，而自己的dll就不用这一步。 PS: 删除用 Installutil /u xxx.dll 2、localhost访问没有问题，但用www.xxx.com访问，出错 在 .NET Framework 1.1 远程环境中，默认情况下 HTTP GET 和 HTTP POST 同时被禁用。这是出于安全方面的考虑。 当 Web 服务升级到 .NET Framework 1.1 后，应用程序使用 HTTP GET 或 HTTP POST 调用 Web 服务时会失败。 [...]]]></description>
			<content:encoded><![CDATA[<p>笔记本上Release后一切正常的Web Services，部署到另外一台2003的服务器上，出现两个问题：</p>
<p>1、Critical Error：</p>
<p>&#8230;没有权限访问注册表</p>
<p>其实只是在写入EventLog的时候ASPNET的权限不够，不过奇怪的是把ASPNET和匿名帐户加入Administrator组，重启，好像权限还是不够&gt;.&lt;</p>
<p>查看其列出的跟踪堆栈，发现好像是Enterprise Library中ADO.NET连接数据库的问题，在网上查了查，有用的文章不多，最后居然就在EntLib的FAQ里,发现是没有正确部署EnterLib程序集的问题。</p>
<p>安装程序工具(Installutil.exe)<br />
允许通过执行指定程序集的安装程序组件来安装和卸载服务器资源。<br />
注意: 在“%windir%\Microsoft.NET\Framework\v1.1.xxxx”中可以找到Installutil.exe，其中xxxx是您使用的 .NET Framework 的内部版本号。</p>
<p><code>Installutil Microsoft.Practices.EnterpriseLibrary.Common.dll<br />
Installutil Microsoft.Practices.EnterpriseLibrary.Configuration.dll<br />
Installutil Microsoft.Practices.EnterpriseLibrary.Data.dll</code></p>
<p>一切恢复正常。</p>
<p>不过还是不知道为什么他的程序集部署的时候必须Install，而自己的dll就不用这一步。</p>
<p>PS:<br />
删除用<br />
Installutil /u xxx.dll</p>
<p>2、localhost访问没有问题，但用www.xxx.com访问，出错</p>
<p>在 .NET Framework 1.1 远程环境中，默认情况下 HTTP GET 和 HTTP POST 同时被禁用。这是出于安全方面的考虑。<br />
当 Web 服务升级到 .NET Framework 1.1 后，应用程序使用 HTTP GET 或 HTTP POST 调用 Web 服务时会失败。<br />
这些应用程序会收到以下一条错误信息 System.Net.WebException指出无法识别请求格式。</p>
<p>由于使用POST，现在已基本不可能转成SOAP协议，只有将其打开，更改Web.Config文件：<br />
<code>&lt;configuration&gt;<br />
&lt;system.web&gt;<br />
&lt;webServices&gt;<br />
&lt;protocols&gt;<br />
&lt;!--<br />
&lt;add name="HttpGet"&gt;<br />
--&gt;<br />
&lt;add name="HttpPost"/&gt;<br />
&lt;/protocols&gt;<br />
&lt;/webServices&gt;<br />
&lt;/system.web&gt;<br />
&lt;/configuration&gt;</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/09/30/%e5%8f%91%e5%b8%83web-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>任务稿：IIS6+SSL Based On 2k3</title>
		<link>http://blog.axqd.net/2005/06/11/iis6-ssl/</link>
		<comments>http://blog.axqd.net/2005/06/11/iis6-ssl/#comments</comments>
		<pubDate>Sat, 11 Jun 2005 08:43:23 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[iis]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=388</guid>
		<description><![CDATA[IIS提供了SSL安全加密传输功能，如下配置： 1、证书请求文件生成： 进入“控制面板→管理工具→Internet 信息服务（IIS）管理器”，在IIS管理器窗口中展开“网站”目录，右键点击要使用SSL安全加密机制功能的网站，在弹出菜单中选择“属性”，然后切换到“目录安全性”标签页，接着点击“服务器证书”按钮。在“IIS证书向导”窗口中选择“新建证书”选项，点击“下一步”，选中“现在准备证书请求，但稍后发送”，接着在“名称”栏中为该证书起个名字，在“位长”下拉列表中选择“密钥的位长”，这里要注意，位长不能设置的过大，否则会影响通信质量；接着设置证书的单位、部门、和地理信息，在站点“公用名称栏”中输入该网站的域名，然后指定证书请求文件的保存位置，这里笔者将该证书请求文本文件保存在 “certreq．txt”。这样就完成了证书请求文件的生成。 2、安装证书服务： 在“控制面板”中运行“添加或删除程序”，切换到“添加/删除Windows组件”页，在“Windows组件向导”对话框中，选中“证书服务”选项，接下来选择CA类型，这里笔者选择“独立根CA”，然后为该CA服务器起个名字，设置证书的有效期限，建议使用默认值“5年”即可，最后指定证书数据库和证书数据库日志的位置后，就完成了证书服务的安装。 3、使用证书请求文件申请证书： 运行Internet Explorer浏览器，在地址栏中输入“http://localhost/CertSrv/default.asp”。接着在“Microsoft 证书服务”欢迎窗口中点击“申请一个证书”链接，然后在证书申请类型中点击“高级证书申请”链接，在高级证书申请窗口中点击“使用BASE64编码的 CMC或PKCS#10文件提交&#8230;”链接，接着将证书请求文件的内容复制到“保存的申请”输入框中，这里笔者的证书请求文件内容保存在 “certreq.txt”，最后点击“提交”按钮。虽然完成了IIS网站证书的申请后，但这时它还处于挂起状态，需要颁发后才能生效。 4、颁发证书： 在“控制面板-&#62;管理工具”中，运行“证书颁发机构”程序。在“证书颁发机构”左侧窗口中展开目录，选中“挂起的申请”目录，在右侧窗口找到刚才申请的证书，鼠标右键点击该证书，选择“所有任务→颁发”。 5、备份证书： 打开刚刚颁发成功的证书，在 “证书”对话框中切换到“详细信息”标签页。点击“复制到文件”按钮，弹出证书导出对话框，一路下一步，在“要导出的文件”栏中指定文件名，这里笔者保存证书路径为“backup.cer”，最后点击“完成”。 6、使用证书： 进入“控制面板-&#62;管理工具-&#62;Internet 信息服务（IIS）管理器”，在IIS管理器窗口中展开“网站”目录，右键点击要使用SSL安全加密机制功能的网站，在弹出菜单中选择“属性”，然后切换到“目录安全性”标签页，接着点击“服务器证书”按钮。使用“IIS证书向导”窗口配置SSL，注意端口的选择，默认443。]]></description>
			<content:encoded><![CDATA[<p>IIS提供了SSL安全加密传输功能，如下配置：</p>
<p>1、证书请求文件生成：</p>
<p>进入“控制面板→管理工具→Internet 信息服务（IIS）管理器”，在IIS管理器窗口中展开“网站”目录，右键点击要使用SSL安全加密机制功能的网站，在弹出菜单中选择“属性”，然后切换到“目录安全性”标签页，接着点击“服务器证书”按钮。在“IIS证书向导”窗口中选择“新建证书”选项，点击“下一步”，选中“现在准备证书请求，但稍后发送”，接着在“名称”栏中为该证书起个名字，在“位长”下拉列表中选择“密钥的位长”，这里要注意，位长不能设置的过大，否则会影响通信质量；接着设置证书的单位、部门、和地理信息，在站点“公用名称栏”中输入该网站的域名，然后指定证书请求文件的保存位置，这里笔者将该证书请求文本文件保存在 “certreq．txt”。这样就完成了证书请求文件的生成。</p>
<p>2、安装证书服务：</p>
<p>在“控制面板”中运行“添加或删除程序”，切换到“添加/删除Windows组件”页，在“Windows组件向导”对话框中，选中“证书服务”选项，接下来选择CA类型，这里笔者选择“独立根CA”，然后为该CA服务器起个名字，设置证书的有效期限，建议使用默认值“5年”即可，最后指定证书数据库和证书数据库日志的位置后，就完成了证书服务的安装。</p>
<p>3、使用证书请求文件申请证书：</p>
<p>运行Internet Explorer浏览器，在地址栏中输入“http://localhost/CertSrv/default.asp”。接着在“Microsoft 证书服务”欢迎窗口中点击“申请一个证书”链接，然后在证书申请类型中点击“高级证书申请”链接，在高级证书申请窗口中点击“使用BASE64编码的 CMC或PKCS#10文件提交&#8230;”链接，接着将证书请求文件的内容复制到“保存的申请”输入框中，这里笔者的证书请求文件内容保存在 “certreq.txt”，最后点击“提交”按钮。虽然完成了IIS网站证书的申请后，但这时它还处于挂起状态，需要颁发后才能生效。</p>
<p>4、颁发证书：</p>
<p>在“控制面板-&gt;管理工具”中，运行“证书颁发机构”程序。在“证书颁发机构”左侧窗口中展开目录，选中“挂起的申请”目录，在右侧窗口找到刚才申请的证书，鼠标右键点击该证书，选择“所有任务→颁发”。</p>
<p>5、备份证书：</p>
<p>打开刚刚颁发成功的证书，在 “证书”对话框中切换到“详细信息”标签页。点击“复制到文件”按钮，弹出证书导出对话框，一路下一步，在“要导出的文件”栏中指定文件名，这里笔者保存证书路径为“backup.cer”，最后点击“完成”。</p>
<p>6、使用证书：</p>
<p>进入“控制面板-&gt;管理工具-&gt;Internet 信息服务（IIS）管理器”，在IIS管理器窗口中展开“网站”目录，右键点击要使用SSL安全加密机制功能的网站，在弹出菜单中选择“属性”，然后切换到“目录安全性”标签页，接着点击“服务器证书”按钮。使用“IIS证书向导”窗口配置SSL，注意端口的选择，默认443。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/06/11/iis6-ssl/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>关于C#一个基础问题的初步探查</title>
		<link>http://blog.axqd.net/2005/04/27/basic-question-of-c-sharp/</link>
		<comments>http://blog.axqd.net/2005/04/27/basic-question-of-c-sharp/#comments</comments>
		<pubDate>Wed, 27 Apr 2005 08:18:08 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=384</guid>
		<description><![CDATA[关于C#一个弱弱问题的初步探查 在书上看到这样一个例子： 已知： interface IControl { void Paint(); } class Control : IControl { public void Paint(){ ... } } class TextBox : Control { new public void Paint(){ ... } } 问: IControl it = new TextBox(); it.Paint(); //调用哪个Paint()? 书上的结论是Control::Paint(),并且吹了一通什么没有virtual关键字或者让TextBox直接继承至IControl就是静态决议，什么如果Control::Paint()加上virtual又怎么怎么，如果TextBox::Paint()去掉new又怎么怎么,感觉甚是繁琐、复杂和多变，让人如坠万丈深渊，万劫不复&#8230;(- -) 就我原来从C++带来的理解：IControl是个interface，其实隐含IControl::Paint()是abstract 以及 public，只是不能显式写出；所以成员函数的调用决议应该是运行期完成，也就是说为TextBox::Paint(); 实际上机测试结果，令人汗颜，他的结果的确是正确的，但是他的后续所有解释都是错误的；不管如何加virtual、去掉new，最后的结果都是一个&#8212;Control::Paint(),程序代码如下： using System; namespace TestInterface { interface IControl { void [...]]]></description>
			<content:encoded><![CDATA[<p>关于C#一个弱弱问题的初步探查</p>
<p>在书上看到这样一个例子：</p>
<p>已知：<br />
<code>interface IControl<br />
{<br />
 void Paint();<br />
}<br />
class Control : IControl<br />
{<br />
 public void Paint(){ ... }<br />
}<br />
class TextBox : Control<br />
{<br />
 new public void Paint(){ ... }<br />
}</code><br />
问:<br />
<code>IControl it = new TextBox();<br />
it.Paint(); //调用哪个Paint()?</code></p>
<p>书上的结论是Control::Paint(),并且吹了一通什么没有virtual关键字或者让TextBox直接继承至IControl就是静态决议，什么如果Control::Paint()加上virtual又怎么怎么，如果TextBox::Paint()去掉new又怎么怎么,感觉甚是繁琐、复杂和多变，让人如坠万丈深渊，万劫不复&#8230;(- -)</p>
<p>就我原来从C++带来的理解：IControl是个interface，其实隐含IControl::Paint()是abstract 以及 public，只是不能显式写出；所以成员函数的调用决议应该是运行期完成，也就是说为TextBox::Paint();</p>
<p>实际上机测试结果，令人汗颜，他的结果的确是正确的，但是他的后续所有解释都是错误的；不管如何加virtual、去掉new，最后的结果都是一个&#8212;Control::Paint(),程序代码如下：<br />
<code>using System;<br />
namespace TestInterface<br />
{<br />
 interface IControl<br />
 {<br />
  void Paint();<br />
 }<br />
 class Control : IControl<br />
 {<br />
  public void Paint()<br />
  {<br />
   Console.WriteLine("Control::Paint()");<br />
  }<br />
 }<br />
 ///<br />
<summary>
 /// TextBox 的摘要说明。<br />
 /// </summary>
<p> class TextBox : Control<br />
 {<br />
  new public void Paint()<br />
  {<br />
   Console.WriteLine("TextBox::Paint()");<br />
  }<br />
 }<br />
 ///<br />
<summary>
 /// TestInterface 的摘要说明。<br />
 /// </summary>
<p> class TestInterface<br />
 {<br />
  ///<br />
<summary>
  /// 应用程序的主入口点。<br />
  /// </summary>
<p>  [STAThread]<br />
  static void Main(string[] args)<br />
  {<br />
   //<br />
   // TODO: 在此处添加代码以启动应用程序<br />
   //<br />
   IControl it = new TextBox();<br />
   it.Paint();<br />
  }<br />
 }<br />
}</code></p>
<p>如果去掉new当然仅仅会导致警告，实际上还是覆盖。</p>
<p>书中还提到“我们的误解来自一个假设：Control::Paint()被自动视为vitrual”,根据实际上机测试，这个假设的确是成立的，而不是什么误解，至于加上virtual和去掉virtual所带来的区别仅仅在于是否加入关键字final。如果没有加上了virtual，那么Control::Paint()会自动视为final(IL中)，有例为证：</p>
<p><code>Contorl::Paint()<br />
.method public hidebysig newslot virtual final //如果加上vitrual则这里去掉final<br />
        instance void  Paint() cil managed<br />
{<br />
  // 代码大小       11 (0xb)<br />
  .maxstack  1<br />
  IL_0000:  ldstr      "Control::Paint()"<br />
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)<br />
  IL_000a:  ret<br />
} // end of method Control::Paint<br />
TextBox::Paint()<br />
.method public hidebysig instance void  Paint() cil managed<br />
{<br />
  // 代码大小       11 (0xb)<br />
  .maxstack  1<br />
  IL_0000:  ldstr      "TextBox::Paint()"<br />
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)<br />
  IL_000a:  ret<br />
} // end of method TextBox::Paint</code></p>
<p>而在Main()中仅是简单调用IControl::Paint()</p>
<p><code>.method private hidebysig static void  Main(string[] args) cil managed<br />
{<br />
  .entrypoint<br />
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )<br />
  // 代码大小       13 (0xd)<br />
  .maxstack  1<br />
  .locals init ([0] class TestInterface.IControl it)<br />
  IL_0000:  newobj     instance void TestInterface.TextBox::.ctor()<br />
  IL_0005:  stloc.0<br />
  IL_0006:  ldloc.0<br />
  IL_0007:  callvirt   instance void TestInterface.IControl::Paint()<br />
  IL_000c:  ret<br />
} // end of method TestInterface::Main</code></p>
<p>===== 华丽的分割线 =====<br />
呵呵,以上就是我初步的分析,特别混乱,不要见笑,下面我做个总结(个人意见、仅供参考)</p>
<p>原来的C++到C#，在函数重载这一块有一个很明显的区别，那就是override关键字。如果重载必须显式的指明override关键字，如果没有，将隐藏基类成员。这点是很自然的，但是本例的特别之处在于interface的引入。</p>
<p>&#8212;&#8211; interface &#8212;&#8211;<br />
interface默认为abstract类，但是和普通abstract类不同的是，他并没有派生自System.Object；其内接口也默认为abstract virtual如下：</p>
<p><code>.class interface private abstract auto ansi IControl<br />
{<br />
} // end of class IControl<br />
.method public hidebysig newslot abstract virtual<br />
        instance void  Paint() cil managed<br />
{<br />
} // end of method IControl::Paint</code></p>
<p>之所以interface被默认为public(指其内接口，而interface本身可以不为public)，abstract就不用解释了，但是明示出来反而会出错；<br />
&#8212;&#8211; interface end &#8212;&#8211;</p>
<p>&#8212;&#8211; interface implement &#8212;&#8211;<br />
<code>.class private auto ansi beforefieldinit Control<br />
       extends [mscorlib]System.Object<br />
       implements TestInterface.IControl<br />
{<br />
} // end of class Control<br />
.method public hidebysig newslot virtual final //如果加上vitrual则这里去掉final<br />
        instance void  Paint() cil managed<br />
{<br />
  // 代码大小       11 (0xb)<br />
  .maxstack  1<br />
  IL_0000:  ldstr      "Control::Paint()"<br />
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)<br />
  IL_000a:  ret<br />
} // end of method Control::Paint</code></p>
<p>这里太有趣了(- -,过分了&#8230;还是说稍微有点意思)interface接口的实现会在IL中自动加上virtual关键字，而不像刚才书上说的，什么误解，这是为什么呢？因为如果像本例中一样，用IControl调用Paint()，而IControl本身是不会实现Paint()的，所以他的实现必须在IL中以virtual关键字标明，让动态决议的时候，能够考虑到这个实现，不然IControl::Paint()的调用就会出问题。</p>
<p>至于这里提到的final，也是interface implement比较独特的一点。override会使得本身重载基类成员，并且本身成为virtual，所以自己的子类也可以重载自己。在程序中，若想重载基类成员，但又不想让子类继续重载，就会使用override sealed关键字，这里IL中的final关键字实际上就是指的sealed。</p>
<p>由此，我们一般写一个函数:</p>
<p><code>public void foo();</code></p>
<p>子类都无法override，除非函数改为：</p>
<p><code>virtual void foo();</code></p>
<p>但是这里由于interface implement本身需要申明为override(IL中仍为virtual)，所以为了延续惯例，用sealed(IL中为final)封闭之，除非你显示的指示virtual，这样就和我们通常的观念保持一致鸟~~~~<br />
&#8212;&#8211; interface implement end &#8212;&#8211;</p>
<p>&#8212;&#8211; extended classes &#8212;&#8211;<br />
<code>.class private auto ansi beforefieldinit TextBox<br />
       extends TestInterface.Control<br />
{<br />
} // end of class TextBox<br />
extends TestInterface.Control<br />
.method public hidebysig instance void  Paint() cil managed<br />
{<br />
  // 代码大小       11 (0xb)<br />
  .maxstack  1<br />
  IL_0000:  ldstr      "TextBox::Paint()"<br />
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)<br />
  IL_000a:  ret<br />
} // end of method TextBox::Paint</code></p>
<p>这里不管你是否采用new关键字，实际上都起到了覆盖的作用，只是如果没有new关键字会引发警告，提醒你是否确实是想覆盖，如果你想关闭警告，就必须显示的告诉编译器我想覆盖&#8212;就是使用new关键字。</p>
<p>值得一提的有两点：<br />
1、如果程序中直接写virtual而不用override，其实还是覆盖。可以从IL中看出：<br />
程序<->IL<br />
virtual<->newslot virtual<br />
override<->virtual<br />
2、如果这个类直接多重继承IControl，像这样：<br />
<code> class TextBox : Control, IControl<br />
 {<br />
  ...<br />
 }</code><br />
实际上这个类就不再属于extended classes了，而是interface implement。由于对于interface implement的选择是virtual的，所以很自然会调用TextBox::Paint();<br />
&#8212;&#8211; extended classes end &#8212;&#8211;</p>
<p>如果以上的讨论正确，本例就很好解释鸟~~~</p>
<p>IControl::Paint()由于是virtual，他会先行寻找可行函数，再进行最佳决议；</p>
<p>由于new关键字的覆盖函数并未override，所以他连可行函数都算不上。自然无论如何都不可能被调用。相反，可能函数只有Control::Paint();</p>
<p>如果让TextBox::Paint()用override修饰(自然Control::Paint()需要用virtual修饰),那么可能函数有Control::Paint(),TextBox.Paint(),其中根据动态决议,最佳为TextBox.Paint();</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/04/27/basic-question-of-c-sharp/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>ZTMD宁愿重写，也不排错</title>
		<link>http://blog.axqd.net/2005/04/09/ztm/</link>
		<comments>http://blog.axqd.net/2005/04/09/ztm/#comments</comments>
		<pubDate>Sat, 09 Apr 2005 08:14:10 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>
		<category><![CDATA[WEB]]></category>
		<category><![CDATA[心情日记]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=383</guid>
		<description><![CDATA[奋战了一个星期的简易登陆系统排错，最后的结果让人汗颜： 将Web.Config里面的 &#60;authentication mode="Windows"&#62; &#60;/authentication&#62; 改为 &#60;authentication mode="Forms"&#62; &#60;forms name="TheSky" path="/" loginUrl="/TheSky/WebModules/Users/Login.aspx" protection="All" timeout="30"&#62; &#60;/forms&#62; &#60;/authentication&#62; 我一直没有查Web.Config。唉，已经欲哭无泪了，呜呜&#8230; ps：ztmd,ztmD,ztMd,zTmd,Ztmd,ztMD,zTmD,ZtmD,zTMd,ZtMd,ZTmd,zTMD,ZtMD,ZTmD,ZTMd,ZTMD]]></description>
			<content:encoded><![CDATA[<p>奋战了一个星期的简易登陆系统排错，最后的结果让人汗颜：<br />
将Web.Config里面的<br />
<code>&lt;authentication mode="Windows"&gt;<br />
&lt;/authentication&gt;</code><br />
改为<br />
<code>&lt;authentication mode="Forms"&gt;<br />
&lt;forms name="TheSky" path="/" loginUrl="/TheSky/WebModules/Users/Login.aspx" protection="All" timeout="30"&gt;<br />
&lt;/forms&gt;<br />
&lt;/authentication&gt;</code><br />
我一直没有查Web.Config。唉，已经欲哭无泪了，呜呜&#8230;</p>
<p>ps：ztmd,ztmD,ztMd,zTmd,Ztmd,ztMD,zTmD,ZtmD,zTMd,ZtMd,ZTmd,zTMD,ZtMD,ZTmD,ZTMd,ZTMD</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/04/09/ztm/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>假期意识流</title>
		<link>http://blog.axqd.net/2005/02/26/vacation/</link>
		<comments>http://blog.axqd.net/2005/02/26/vacation/#comments</comments>
		<pubDate>Sat, 26 Feb 2005 09:12:24 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[.NET框架]]></category>
		<category><![CDATA[WEB]]></category>
		<category><![CDATA[心情日记]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[scu]]></category>
		<category><![CDATA[uestc]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=380</guid>
		<description><![CDATA[意识流 &#8212;假期生活乱纪 这个假期不堪回首，单调得可怕，除了4本书之外，记忆中仅存的就全是某大学的研究生会的网站了。网站说来更不堪回首，完全算得上“赶鸭子上架”的典型（我“可爱”的姐在网站“八字还没有一撇”的时候，居然就敢将“网站建设费”挥霍一空，后来备受挫折后，无力还债，于是栽赃到了我的头上- -！）。下面将网站建设过程中的点点滴滴乱纪下来，想到哪里写到哪里，逻辑未免混乱，各位大虾莫要见笑。目的也很简单，让各位看看一个新手眼中的网站建设过程。 1、 研究生会： 因为这个网站，我就已经堂而皇之成为某大学研究生会编制中的一员，这种“海纳百川”的“气势”令我无不拜倒- -！ 2、 网站需求： 刚开始的网站需求很“明确”&#8212;“美观、大方、展现当代研究生风采”。让我感到在这种“派头”的指导老师手下干起事情来一定比较“自由”，但是后来事实证明我错了，这种指导老师也有开始变“聪明”的时候。 需求增加了一条&#8212;“采用最新的Asp.Net技术，并且务必使用SQL Server最新版本”，我在深入理解这条需求之后，对于各个软件、框架的版本甚是犹豫，不知beta版是否也计算在内- -！ 3、 美工： 这个我没有发言权，反正阿梅和阿楠看过（因为当时我不会用PS分页- -！） 4、 VS .NET环境： 由于以前习惯于Borland的BCB，于是“疏”在于没RAD就不活了，“密”在于任何东西都希望有根有据，简单明了。对于VC++6.0从未涉猎，因为当时第一印象就觉得不像是拿来编程的，加之MFC的封装没有一定的实力，定会感到极其莫名其妙，那消息映射的编程方式更是使得局势错综复杂，不像VCL里面虽然依然有很多不懂，但至少容易把握过程。 介于上述原因，所以当我观之Visual Studio .NET的时候还是大吃一惊，惊叹微软也终于RAD了一把。于是看了本《C# Primer》上手就干。 但是现实总是残酷的，虽然很多东西感觉用起很顺手，但还是有很多极其不习惯： 首当其冲的就是一个解决方案里面的类、函数等等，不用.h，不用#include好像就能够在各个文件中可见，原因可能是采用namespace的组织方式，但是老是觉得没有#include &#60;*.h&#62;就是不爽（我理想中的世界应该是把文件include过来后，再在namespace里面避免污染，而不要在一个解决方案里面的文件到处都可见似的）。 其次就是所谓的大名鼎鼎的“Code Behind”，这个倒是在很大程度上解决了网页程序设计中的版权问题，并且使代码和外观分离，便于和传统窗口编程靠拢。但是对于新手而言，在不具备驾驭的能力的情况下，无非是场灾难，代码直接生成DLL，不用export，不用声明，只需assembly一下，就可以使用，随便咋看都极其莫名其妙。 介于以上，我终于放弃了使用VS .NET，本来想选择同出Borland之手的C# Builder，但是令人郁闷的是没有找到注册码- -！所以最后我还是选择了以前写ASP程序时候采用的Dreamweaver+EditPlus+MSDN，本来记事本足已，但是少了调试器，要是连行号都看不到，那我还是直接跳楼算了。 5、 风格： 回头看我写的代码，感觉很多地方看起来还是像用ASP写的：P，不过因为毕竟是ASP.NET的东西，还是初步感受了一下ASP.NET的便利，诸如：DataGrid、DataList、Page_Load、还有在连接SQL数据库时候的便利等等等等。 6、 语言： 这个是我最无语的一点，由于C# 是刚学的，所以开始的时候还是在尝试VB，在花了很长时间都没有发现下面代码为什么通不过之后，我还是痛下决心用C# 吧- -！ #region code &#60;script language=”VB” runat=server&#62; sub foo(object sender,eventargs e) { //---------- [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>意识流</strong></p>
<p style="text-align: right;">&#8212;假期生活乱纪</p>
<p>这个假期不堪回首，单调得可怕，除了4本书之外，记忆中仅存的就全是某大学的研究生会的网站了。网站说来更不堪回首，完全算得上“赶鸭子上架”的典型（我“可爱”的姐在网站“八字还没有一撇”的时候，居然就敢将“网站建设费”挥霍一空，后来备受挫折后，无力还债，于是栽赃到了我的头上- -！）。下面将网站建设过程中的点点滴滴乱纪下来，想到哪里写到哪里，逻辑未免混乱，各位大虾莫要见笑。目的也很简单，让各位看看一个新手眼中的网站建设过程。</p>
<p>1、  研究生会：</p>
<p>因为这个网站，我就已经堂而皇之成为某大学研究生会编制中的一员，这种“海纳百川”的“气势”令我无不拜倒- -！</p>
<p>2、  网站需求：</p>
<p>刚开始的网站需求很“明确”&#8212;“美观、大方、展现当代研究生风采”。让我感到在这种“派头”的指导老师手下干起事情来一定比较“自由”，但是后来事实证明我错了，这种指导老师也有开始变“聪明”的时候。</p>
<p>需求增加了一条&#8212;“采用最新的Asp.Net技术，并且务必使用SQL Server最新版本”，我在深入理解这条需求之后，对于各个软件、框架的版本甚是犹豫，不知beta版是否也计算在内- -！</p>
<p>3、  美工：</p>
<p>这个我没有发言权，反正阿梅和阿楠看过（因为当时我不会用PS分页- -！）</p>
<p>4、  VS .NET环境：</p>
<p>由于以前习惯于Borland的BCB，于是“疏”在于没RAD就不活了，“密”在于任何东西都希望有根有据，简单明了。对于VC++6.0从未涉猎，因为当时第一印象就觉得不像是拿来编程的，加之MFC的封装没有一定的实力，定会感到极其莫名其妙，那消息映射的编程方式更是使得局势错综复杂，不像VCL里面虽然依然有很多不懂，但至少容易把握过程。</p>
<p>介于上述原因，所以当我观之Visual Studio .NET的时候还是大吃一惊，惊叹微软也终于RAD了一把。于是看了本《C# Primer》上手就干。</p>
<p>但是现实总是残酷的，虽然很多东西感觉用起很顺手，但还是有很多极其不习惯：</p>
<p>首当其冲的就是一个解决方案里面的类、函数等等，不用.h，不用#include好像就能够在各个文件中可见，原因可能是采用namespace的组织方式，但是老是觉得没有#include &lt;*.h&gt;就是不爽（我理想中的世界应该是把文件include过来后，再在namespace里面避免污染，而不要在一个解决方案里面的文件到处都可见似的）。</p>
<p>其次就是所谓的大名鼎鼎的“Code Behind”，这个倒是在很大程度上解决了网页程序设计中的版权问题，并且使代码和外观分离，便于和传统窗口编程靠拢。但是对于新手而言，在不具备驾驭的能力的情况下，无非是场灾难，代码直接生成DLL，不用export，不用声明，只需assembly一下，就可以使用，随便咋看都极其莫名其妙。</p>
<p>介于以上，我终于放弃了使用VS .NET，本来想选择同出Borland之手的C# Builder，但是令人郁闷的是没有找到注册码- -！所以最后我还是选择了以前写ASP程序时候采用的Dreamweaver+EditPlus+MSDN，本来记事本足已，但是少了调试器，要是连行号都看不到，那我还是直接跳楼算了。</p>
<p>5、  风格：</p>
<p>回头看我写的代码，感觉很多地方看起来还是像用ASP写的：P，不过因为毕竟是ASP.NET的东西，还是初步感受了一下ASP.NET的便利，诸如：DataGrid、DataList、Page_Load、还有在连接SQL数据库时候的便利等等等等。</p>
<p>6、  语言：</p>
<p>这个是我最无语的一点，由于C# 是刚学的，所以开始的时候还是在尝试VB，在花了很长时间都没有发现下面代码为什么通不过之后，我还是痛下决心用C# 吧- -！</p>
<p><code>#region code<br />
&lt;script language=”VB” runat=server&gt;<br />
sub foo(object sender,eventargs e)<br />
{<br />
//----------<br />
}<br />
&lt;/script&gt;<br />
#endregion</code></p>
<p>接踵而来的转化工作，幸好还不算很困难，但确实很烦，下面将我在转化时的主要工作总结一下：</p>
<p>a）  大小写：VB里面的标识符不区分大小写，如：page_load、datagrid也可以通过，但是到了C# 里面就必须区分大小写了（这里是改得最郁闷的了，对照到MSDN一个一个挨到改，想当初写VB Script的时候不偷懒就好了）</p>
<p>b）  索引（Item）：VB里面使用object（index）就可以索引了，但是到了C#里面索引可必须使用object[index]符号，不过如果你使用Item调用就一致了，不过新手一般都不会那样做。</p>
<p>其他可能还有很多转化工作，不过我倒是幸运的没有碰到。</p>
<p>7、  基本代码组织方式：</p>
<p>由于那个网站大量的都是带图像文本处理，所以基本上前台采用的是把分页后形成的静态页面里面的动态部分挖空，以iframe填充之，iframe的src里面要不就指向list.aspx文件（显示前多少项，以及more按钮），并传入类别、css、行数、列数作为参数控制外观；要不就指向multilist.aspx文件（显示所有内容，以DataGrid进行分页控制），传入的外观控制参数一致。并且二者都接受hot=1参数，若设置了，则排序的方式由order by subdate desc变为order by 点击次数 desc</p>
<p>8、  前台：</p>
<p>前台如前述方式架构，我觉得最有用的就是DataGrid与DataList的基本使用及外观控制，如果实在觉得不方便，新手还是用&lt;ItemTemplate&gt;来得快：），另外在进行数据绑定的时候，我基本上就只用到了下面一条语句：</p>
<p><code>&lt;%#  ((DataRowView)Container.DataItem)["foo"]  %&gt;</code></p>
<p>9、  后台管理：</p>
<p>a）FreeTextBox：</p>
<p>说起后台管理自然想到了熟悉的DormForce Blog的后台，那里的那个输入控件，令人感觉甚爽，在IE里面察看源，发现名字叫做FreeTextBox- -！这个名字实在是…</p>
<p>于是Google后下载了一个，感觉封装得很好，使用也很方便，直接register就可以用了，令我倍感ASP.NET还是很爽的，也对Web Control产生了一丝眷恋。但是问题也出来了，他的“插入图片”按钮令人极其郁闷，只能插入图片URL，而没有提供上传，本来想在FTB控件旁边单独提供一个UploadImg按钮，提供上传然后返回URL，供使用FTB插入之需。</p>
<p>但是在看了“宝玉”的文章后突然发现FTB对于Button提供了接口ToolBarButton，于是可以把上传的工作集成到按钮里面。用宝玉提供的方法，在VS .NET里面“依样画葫芦”很快便搞定了，其实就是直接从ToolBarButton直接继承构造新的Button就可以了。</p>
<p>但是问题是我没有用Code Behind的方式，而且找了半天也没有发现，如果不用Code Behind，把类的定义写在哪里？所以只有自己想办法，看了半天英文版的FTB帮助，终于找到了方法：</p>
<p><code>&lt;FTB:TOOLBARBUTTON title="插入图片"<br />
runat="server" ScriptBlock="myOpenFunc();" ButtonImage="insertimage" /&gt;</code></p>
<p>其中的ButtonImage指定名称后会自动从aspnet_client目录调用图片资源，若要更换可以直接替换文件即可，不过注意保持长宽比（不然会很难看的）。另外我感觉aspnet_client这个名字很可疑，可能有特殊的用途，诸如用于客户端的啥子东西，没有敢改名字：（</p>
<p>其中的ScriptBlock直接在FTB生成的Html页面里面加入内容，如上例就生成如下咚咚：</p>
<p><code>… = new FTBButton(… function(){myOpenFunc();} …)…</code></p>
<p>myOpenFunc()为调用此FTB控件页面上&lt;script&gt;内定义的函数。藉由此实现runat=server代码对于本机函数的调用，即通常所谓的Response.Write法。</p>
<p>另外，我还需要从本机函数调取runat=server中控件的属性。想了半天，找到了如下的不是办法的办法：</p>
<p><code>function myOpenFunc(){<br />
var dt=eval('myForm.myDataTable');<br />
var tempurl='../inc/uploadimg.aspx?tab=';<br />
tempurl = tempurl+dt.value;<br />
window.open(tempurl,'_uploadimg','width=300 height=50');<br />
}</code></p>
<p>其中myForm、myDataTable分别为runat=server里面Form和DropDownList的Id名称，使得本机获得的html页面里的form和select的id为这二者，从而为本机函数的实现提供可能性。</p>
<p>在uploadimg.aspx中只需完成上传文件，调用opener.top.InsertText(…)方法传入图片地址即可，而在myOpenFunc()所在页面中定义InsertText方法完成插入。</p>
<p>b）  编辑区域：</p>
<p>编辑区域的实质，宝玉已经说得比较清楚了，其实就是一个document.designMode设为on的Iframe。因此可以方便的用本机函数进行各种编辑工作以及调用focus()获取焦点。</p>
<p>c）  DropDownList的数据绑定：</p>
<p>由于需要，选定一个DropDownList后要对另外一个重新进行数据绑定，实现方式如下：</p>
<p>指定DropDownList的属性OnSelectedIndexChanged=&#8221;SelectionChangeFunc&#8221; AutoPostBack=&#8221;true&#8221;，SelectionChangeFunc会传送给一个delegate型别从而起到类似函数指针的作用。</p>
<p><code>void SelectionChangeFunc(Object sender, System.EventArgs e)<br />
{<br />
myDataClass.DataSource = CreateDataSource(...);<br />
myDataClass.DataTextField = "TextField";<br />
myDataClass.DataValueField = "ValueField";<br />
myDataClass.DataBind();<br />
myDataClass.SelectedIndex = 0;<br />
}<br />
ICollection CreateDataSource(…)<br />
{<br />
System.Data.DataTable myDt = new System.Data.DataTable();<br />
myDt.Columns.Add(new System.Data.DataColumn("TextField", typeof(String)));<br />
myDt.Columns.Add(new System.Data.DataColumn("ValueField", typeof(String)));<br />
...<br />
myDt.Rows.Add(CreateRow("…", "…", myDt));<br />
...<br />
System.Data.DataView myDv = new System.Data.DataView(dt);<br />
return myDv;<br />
}<br />
System.Data.DataRow CreateRow(String Text, String Value, System.Data.DataTable dt)<br />
{<br />
System.Data.DataRow myDr = dt.NewRow();<br />
dr[0] = Text;<br />
dr[1] = Value;<br />
return myDr;<br />
}</code></p>
<p>d）  DataGrid的CommandButton：</p>
<p>column字段：<code>&lt;asp:ButtonColumn HeaderText="Del Button"<br />
Text="Del" CommandName="DelBtn" /&gt;</code></p>
<p>指定DataGrid属性OnItemCommand=&#8221;Grid_DelCommand&#8221;</p>
<p>通过Grid_DelCommand函数处理所有的CommandButton信息，而Grid_DelCommand函数只需根据CommandName指定的值选择操作即可。</p>
<p><code>void Grid_DelCommand(Object sender, DataGridCommandEventArgs e)<br />
{<br />
if(((LinkButton)e.CommandSource).CommandName == "DelBtn")<br />
{<br />
...<br />
}<br />
}</code></p>
<p>这里有两个问题：</p>
<p>其一，好像DataGrid被提交的时候也会调用此OnItemCommand函数，因为当时由于只有一个command，没有用if判断CommandName值的时候，一提交就要出错，而且是在这个函数里面出错的。所以建议就算只有一个command也用if后者select判断一下。</p>
<p>其二，我本来是把&lt;asp:ButtonColumn&gt;定义为“PushButton”的，但是在进行强制类型转换的时候没有找到相应的类型，不管是Button、PushButton都不对，所以只好换用默认的LinkButton才调试通过。</p>
<p>e）  DataGrid的分页：</p>
<p>设置DataGrid的</p>
<p>AllowPaging=True<br />
PagerStyle-Mode=NumericPages<br />
PagerStyle-HorizontalAlign=Right<br />
OnPageIndexChanged=&#8221;Change_Page_Index&#8221;属性</p>
<p>定义下列函数：</p>
<p><code>void Change_Page_Index(Object sender, DataGridPageChangedEventArgs e)<br />
{<br />
myDataGrid.CurrentPageIndex=e.NewPageIndex;<br />
...<br />
myDataGrid.DataBind();<br />
}<br />
void PagerButtonClick(Object sender, EventArgs e)<br />
{<br />
String arg = ((LinkButton)sender).CommandArgument;<br />
switch(arg)<br />
{<br />
case ("next"):<br />
if (myDataGrid.CurrentPageIndex &lt; (myDataGrid.PageCount - 1))<br />
myDataGrid.CurrentPageIndex ++;<br />
break;<br />
case ("prev"):<br />
if (myDataGrid.CurrentPageIndex &gt; 0)<br />
myDataGrid.CurrentPageIndex --;<br />
break;<br />
case ("last"):<br />
myDataGrid.CurrentPageIndex = (myDataGrid.PageCount - 1);<br />
break;<br />
default:<br />
myDataGrid.CurrentPageIndex = Convert.ToInt32(arg);<br />
break;<br />
}<br />
myDataGrid.DataBind();<br />
}</code></p>
<p>这里注意的是换了页要重新DataBind()一下。</p>
<p>f）  SQL：</p>
<p>不多说了，下面是我觉得常用的函数：</p>
<p><code>System.Data.DataSet MyQuery(String querystring)<br />
{<br />
String connectionString = @"...";<br />
System.Data.IDbConnection dbConnection = new<br />
System.Data.SqlClient.SqlConnection(connectionString);<br />
System.Data.IDbCommand dbCommand = new<br />
System.Data.SqlClient.SqlCommand();<br />
dbCommand.CommandText = querystring;<br />
dbCommand.Connection = dbConnection;<br />
System.Data.IDbDataAdapter dataAdapter = new<br />
System.Data.SqlClient.SqlDataAdapter();<br />
dataAdapter.SelectCommand = dbCommand;<br />
System.Data.DataSet dataSet = new System.Data.DataSet();<br />
dataAdapter.Fill(dataSet);<br />
return dataSet;<br />
}<br />
int MyDelete(String delString)<br />
{<br />
String connectionString = @"...";<br />
System.Data.IDbConnection dbConnection = new<br />
System.Data.SqlClient.SqlConnection(connectionString);<br />
System.Data.IDbCommand dbCommand = new<br />
System.Data.SqlClient.SqlCommand();<br />
dbCommand.CommandText = delString;<br />
dbCommand.Connection = dbConnection;<br />
int rowsAffected = 0;<br />
dbConnection.Open();<br />
try<br />
{<br />
rowsAffected = dbCommand.ExecuteNonQuery();<br />
}<br />
finally<br />
{<br />
dbConnection.Close();<br />
}<br />
return rowsAffected;<br />
}<br />
int MyInsert(...)<br />
{<br />
String connString = "...";<br />
System.Data.IDbConnection dbConnection = new<br />
System.Data.SqlClient.SqlConnection(connString);<br />
String queryString = "INSERT INTO [...]([...], ...) VALUES (";<br />
queryString +="@..., ...)";<br />
System.Data.IDbCommand dbCommand = new<br />
System.Data.SqlClient.SqlCommand();<br />
dbCommand.CommandText = queryString;<br />
dbCommand.Connection = dbConnection;<br />
System.Data.IDataParameter dbParam_... = new<br />
System.Data.SqlClient.SqlParameter();<br />
dbParam_...ParameterName = "@...";<br />
dbParam_...Value = ...;<br />
dbParam_...DbType = System.Data.DbType.String;<br />
dbCommand.Parameters.Add(dbParam_...);<br />
...<br />
int rowsAffected = 0;<br />
dbConnection.Open();<br />
try {<br />
rowsAffected = dbCommand.ExecuteNonQuery();<br />
}<br />
finally {<br />
dbConnection.Close();<br />
}<br />
return rowsAffected;<br />
}</code></p>
<p>10、    其他点点滴滴：</p>
<p>a）  去掉图片加链接后外包框：</p>
<p><code>&lt;img border=0&gt;</code></p>
<p>b）  去掉IE图片悬停工具栏：<br />
<code><br />
&lt;img galleryimg=”no”&gt;或者&lt;meta http-equiv="imagetoolbar" content="no"&gt;</code></p>
<p>c）  去掉链接点击后的虚线：</p>
<p><code>&lt;a href="…" onFocus="this.blur()"&gt;&lt;/a&gt;</code></p>
<p>d）  使iframe自适应长宽：</p>
<p><code>&lt;iframe src="..."<br />
onload="this.height =<br />
this.document.body.offsetHeight;this.width=this.document.body.offsetWidth;"&gt;<br />
&lt;/iframe&gt;</code></p>
<p>另外千万注意不要漏了&lt;/iframe&gt;，网页被撑开了，我查了半天才发现是这个原因。</p>
<p>e）  连续滚动：</p>
<p>一般的marquee会两次滚动间会有一段时间的空白，采用<a href="http://blog.axqd.net/wp-content/uploads/2008/07/4marquee.rar">此处的代码</a>可以使得其连续滚动。</p>
<p>上面这些就是这个网站的点点滴滴，没有什么技术含量，只是写篇乱纪，以标明这个颓废的寒假。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2005/02/26/vacation/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Windows Update Services概述&#8212;微软系列讲座3</title>
		<link>http://blog.axqd.net/2004/12/13/wus/</link>
		<comments>http://blog.axqd.net/2004/12/13/wus/#comments</comments>
		<pubDate>Mon, 13 Dec 2004 03:19:48 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wus]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=377</guid>
		<description><![CDATA[主讲人：王辉 职业：微软认证讲师&#8212;苏州索迪高级培训中心 本次讲座不涉及 WUS Chain 防火墙需求 80 443 WUS可使用自定义端口（若80占用，8530，不可配置） http://www.microsoft.com/windowsserversystem/content/sus/popper.html SUS 必须先下载全部补丁，才能下载catelog 只有使用SUSLogView等第三方工具检测用户更新 windowsupdate.log，对域的话用MBSA，不够友好 不能对微软应用、驱动程序分发update 在WUS部署中使用计算机分组 Approve时对某组进行应用： 如：测试组；高危组 内置：All Computers Group；Unassigned Computer 实现分组： Server－Side Client－Side（使用组策略修改） WUS数据库 WMSDE=MSDE(WINDOWS)只能在server2003上，连接数目，数据库大小没有限制 MSDE(SQL)可以在2000/server2003上，5个连接数目，数据库2G SQL SERVER 2000(SP3a) 数据库存放的信息： WUS服务器配置信息 每个更新的metadata（即catalog） 客户端信息及客户端需要哪些更新 更新分为两部分： 1、metadata 2、文件 磁盘空间：最小6G 建议30G 可以从微软的更新站点下载WUS批准的安装，即从WUS下载catalog，而从微软下载文件，以节约外网带宽 Store update file on WUS/Microsoft 带宽优化 * 自动批准检测和自动批准安装 * 可以按更新类型设定是否对某些类别自动批准/安装 * 批准删除 管理员可以先批准检测，用户可以先收到catalog，然后管理员可以根据用户的选择的报表选定某些批准安装 延时下载更新：即只有批准安装的更新才会下载 [...]]]></description>
			<content:encoded><![CDATA[<p>主讲人：王辉<br />
职业：微软认证讲师&#8212;苏州索迪高级培训中心<br />
本次讲座不涉及<br />
WUS Chain</p>
<p>防火墙需求<br />
80 443<br />
WUS可使用自定义端口（若80占用，8530，不可配置）</p>
<p>http://www.microsoft.com/windowsserversystem/content/sus/popper.html</p>
<p>SUS<br />
必须先下载全部补丁，才能下载catelog</p>
<p>只有使用SUSLogView等第三方工具检测用户更新</p>
<p>windowsupdate.log，对域的话用MBSA，不够友好</p>
<p>不能对微软应用、驱动程序分发update</p>
<p>在WUS部署中使用计算机分组</p>
<p>Approve时对某组进行应用：<br />
 如：测试组；高危组<br />
 内置：All Computers Group；Unassigned Computer<br />
 实现分组：<br />
  Server－Side  Client－Side（使用组策略修改）<br />
WUS数据库</p>
<p>WMSDE=MSDE(WINDOWS)只能在server2003上，连接数目，数据库大小没有限制<br />
MSDE(SQL)可以在2000/server2003上，5个连接数目，数据库2G<br />
SQL SERVER 2000(SP3a)</p>
<p>数据库存放的信息：<br />
WUS服务器配置信息<br />
每个更新的metadata（即catalog）<br />
客户端信息及客户端需要哪些更新</p>
<p>更新分为两部分：<br />
1、metadata<br />
2、文件</p>
<p>磁盘空间：最小6G 建议30G</p>
<p>可以从微软的更新站点下载WUS批准的安装，即从WUS下载catalog，而从微软下载文件，以节约外网带宽</p>
<p>Store update file on WUS/Microsoft</p>
<p>带宽优化<br />
* 自动批准检测和自动批准安装<br />
* 可以按更新类型设定是否对某些类别自动批准/安装<br />
* 批准删除</p>
<p>管理员可以先批准检测，用户可以先收到catalog，然后管理员可以根据用户的选择的报表选定某些批准安装</p>
<p>延时下载更新：即只有批准安装的更新才会下载</p>
<p>一般自动批准检测，再手工批准安装</p>
<p>批准状态：</p>
<p>可以根据计算机组更改批准状态</p>
<p>设置最后期限：(DeadLine)</p>
<p>如果用户过了这个时间还没有安装，则强制安装</p>
<p>如果发现office的更新在客户端无法安装，那么先需要在客户端安装windows installer 3.0</p>
<p>Express installation files<br />
比较差异，生成diff文件，然后更新<br />
节约局域网带宽，浪费广域网带宽，从微软网站下载的文件更大</p>
<p>使用BITS（后台只能传输服务）进行所有文件的传输工作<br />
断点续传、带宽控制（如果目前使用60%带宽，则WUS只使用40％带宽）</p>
<p>强大的report功能<br />
report详尽，并且支持filter<br />
客户端更新状态报告</p>
<p>管理与internet断开的网络<br />
导出与导入：建议使用增量备份<br />
1、比对export和import服务器同步高级选项，保证设置一致<br />
2、复制更新：<br />
* 使用ntbackup备份export服务器存放更新的文件夹，默认为WUSWusContent<br />
* 在import服务器使用ntbackup还原备份，还原时选择“Alternate location”路径不变<br />
3、复制metadata<br />
* 从export服务器数据库导出<br />
* wusutil export c:export.cab c:export.log<br />
* 将metadata导入import服务器<br />
* wusutil import c:export.cab c:export.log</p>
<p>数据库一定要独立（不能一个sql支持多个WUS）</p>
<p>硬件考虑<br />
500客户端以下：<br />
CPU 最小 300MHz 推荐 1G<br />
RAM 最小 256MHz 推荐 1G<br />
DB  最小 WMSDE/MSDE 推荐 WMSDE/MSDE</p>
<p>500客户端以上<br />
CPU 最小 1G  推荐 2G<br />
RAM 最小 1G  推荐 1G<br />
DB  最小 SQLSERVER2K 推荐 SQLSERVER2K</p>
<p>磁盘 最少6G 推荐30G</p>
<p>软件：<br />
IIS5.0<br />
BITS2.0<br />
Server2003:.Net Framwork1.1 SP1<br />
2000:IE6.0SP1<br />
 .net Framwork1.1 SP1<br />
 SQL Server 2000 Desktop Engine(MSDE2000)<br />
WUS自动配置：ASP.Net version 1.1<br />
  WMSDE</p>
<p>selfupdate client<br />
2000sp3<br />
xpsp2<br />
server2003</p>
<p>每隔22个小时检测，可通过组策略调整</p>
<p>下载后会再次确认在服务器是否依然有效且被批准</p>
<p>最新的管理模板（％windir％infwuau.adm）可从sp2中获得</p>
<p>即时检测wuauclt.exe /detectnow</p>
<p>客户端cookie过期，其中包含组成员信息（client side）</p>
<p>远程的SQL Server限制：</p>
<p>前端或后端的服务器都不可以为win2000 server<br />
前端或后端的服务器都不可以为域控制器<br />
后端数据库不可以为wmsde或者msde</p>
<p>实现步骤：</p>
<p>在前端服务器安装WUS<br />
wussetup.exe /F<br />
在后端服务器安装WUS<br />
wussetup.exe /B<br />
在后端服务器设置权限<br />
配置前端服务器使用后端</p>
<p>装后端服务器前一定要先把准备工作做好，如sql服务器、sp等等<br />
wussetup.exe /B /V &#8220;CONTENT_LOCAL=1&#8243; CONTENT_DIR=&#8221;E:WUS&#8221;</p>
<p>local_machinesoftwareMicrosoftWindowsUpdateServicesServerSetupSqlServerName</p>
<p>最后启动WUS服务</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/12/13/wus/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>灵活利用组策略做网络管理&#8212;微软系列讲座2</title>
		<link>http://blog.axqd.net/2004/12/02/gpedit/</link>
		<comments>http://blog.axqd.net/2004/12/02/gpedit/#comments</comments>
		<pubDate>Thu, 02 Dec 2004 03:15:55 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=376</guid>
		<description><![CDATA[主讲人：孔文达 职业：微软金牌讲师（有这种职业吗？晕~~） MSN：kongwenda@hotmail.com EMAIL：kongwenda@itgoldenbridge.com 随堂笔记（较乱，请见谅！） [组策略功能] 软件安装 开机、登陆、注销、关机脚本 文件重定向 控制IE属性 控制用户操作系统的诸多属性 [组策略组成（嵌入形式）] GPO（Group Policy Object） 存储于活动目录数据库中的对象 包括以下两部分： 1、GPC（Container）：存储于活动目录数据库，保存版本信息，如是否改变等等，占用空间较小； 2、GPT（Template）：存储于SYSVOL文件夹（安装活动目录时创建）中，包含调整的所有内容； SYSVOL目录包含以下最为重要两个文件： Default Main Policy Default Domain Control Policy [组策略应用] 结构： Site Domain OU OU&#8230; 如果设置冲突，则按如下原则解决： 下级优先：OU&#62;Domain&#62;Site [组策略的存储] 域控制器选项： PDC模拟器：第一台DC 活动目录管理单元：当前DC 任何可用域控制器：所有当前有效DC [组策略四大功能] 1、GPMC&#8212;编辑组策略的软件，推荐使用 2、软件安装 只是显示在开始程序里面，并提示新安装了程序，但是只有第一次使用才会进行安装 计算机配置：开机时生效 用户配置：登陆时生效 3、设定开机、登陆、注销、关机脚本 4、文件夹重定向 个人文件夹都存在指定位置了，方便管理，用户文件，即使管理员也不能查看 只能指定如下文件： Application Data 桌面 我的文档 开始菜单 [...]]]></description>
			<content:encoded><![CDATA[<p>主讲人：孔文达<br />
职业：微软金牌讲师（有这种职业吗？晕~~）<br />
MSN：kongwenda@hotmail.com<br />
EMAIL：kongwenda@itgoldenbridge.com</p>
<p>随堂笔记（较乱，请见谅！）</p>
<p>[组策略功能]<br />
软件安装<br />
开机、登陆、注销、关机脚本<br />
文件重定向<br />
控制IE属性<br />
控制用户操作系统的诸多属性</p>
<p>[组策略组成（嵌入形式）]<br />
GPO（Group Policy Object）<br />
存储于活动目录数据库中的对象<br />
包括以下两部分：<br />
1、GPC（Container）：存储于活动目录数据库，保存版本信息，如是否改变等等，占用空间较小；<br />
2、GPT（Template）：存储于SYSVOL文件夹（安装活动目录时创建）中，包含调整的所有内容；<br />
SYSVOL目录包含以下最为重要两个文件：<br />
Default Main Policy<br />
Default Domain Control Policy</p>
<p>[组策略应用]<br />
结构：<br />
Site<br />
Domain<br />
OU<br />
OU&#8230;<br />
如果设置冲突，则按如下原则解决：<br />
下级优先：OU&gt;Domain&gt;Site</p>
<p>[组策略的存储]<br />
域控制器选项：<br />
PDC模拟器：第一台DC<br />
活动目录管理单元：当前DC<br />
任何可用域控制器：所有当前有效DC</p>
<p>[组策略四大功能]</p>
<p>1、GPMC&#8212;编辑组策略的软件，推荐使用<br />
2、软件安装<br />
只是显示在开始程序里面，并提示新安装了程序，但是只有第一次使用才会进行安装<br />
计算机配置：开机时生效<br />
用户配置：登陆时生效<br />
3、设定开机、登陆、注销、关机脚本<br />
4、文件夹重定向<br />
个人文件夹都存在指定位置了，方便管理，用户文件，即使管理员也不能查看<br />
只能指定如下文件：<br />
Application Data<br />
桌面<br />
我的文档<br />
开始菜单<br />
5、控制用户操作系统的诸多属性<br />
举例：<br />
软件限制策略<br />
删除运行&#8230;</p>
<p>WMI筛选器<br />
如：判断C：剩余空间<br />
SELECT * FROM win32_logicaldisk WHERE name = &#8220;c&#8221; and freespace &lt; 100000000(字节)</p>
<p>注意：组策略可自己扩展</p>
<p>[常用工具]<br />
WMI tools：辅助写WMI筛选器<br />
WinInstallLE：制作msi<br />
DCGPOFix(resource-kit)：生成刚才提到的误删除的两个极其重要的默认的policy</p>
<p>[常见问题]<br />
设置了 并且注销重新登陆后依然没有生效?<br />
法一、等待2小时<br />
法二、使用命令gpupdate /force强制客户端和DC同步</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/12/02/gpedit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SMS在企业中的应用&#8212;微软系列讲座1</title>
		<link>http://blog.axqd.net/2004/11/26/sms-tutorial/</link>
		<comments>http://blog.axqd.net/2004/11/26/sms-tutorial/#comments</comments>
		<pubDate>Fri, 26 Nov 2004 10:10:20 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[sms]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=375</guid>
		<description><![CDATA[今天在网上逛，突然发现有关于SMS的在线讲座，想到翔帅叫看看关于SMS的咚咚，顺便进去听了听。中国人讲的，不过ppt和操作系统是英文的:( 感觉还不错，不过就是普通话太差。待会儿我会把我的随堂笔记贴在下面，比较乱，希望大家不要介意哈，一个字，一个字打得哦，连复制都不行（视频），我容易吗我？呜呜&#8230; 听完后，感觉要想应用sms，现在还不现实，因为现在网管会整个网络系统还没有采用域来管理，所以如果用SMS的话，只有采用最低效的Network模式（详见笔记），意义不大。 算了，不想说了，感冒阿，太惨了!!!贴!!! ===== 华丽的分界线 ===== SMS在企业中的应用 中科院软件研究所 史震 一、体系架构： * 操作架构 Based on Windows Server 2003： Like DNS,DHCP,ISA Server(Security),SQL Server(DataBase),SMS Server * 应用程序架构 Based on Application Center 2000 * 信息流架构 Based on Exchange2003 二、SMS应用范围： * Asset Management:Hardware * Software Distribution:Software * Security Update:Update(Better than SUS:Not only Server SP,Office SP) * Remote Computer Support:Remote [...]]]></description>
			<content:encoded><![CDATA[<p>今天在网上逛，突然发现有关于SMS的在线讲座，想到翔帅叫看看关于SMS的咚咚，顺便进去听了听。中国人讲的，不过ppt和操作系统是英文的:(</p>
<p>感觉还不错，不过就是普通话太差。待会儿我会把我的随堂笔记贴在下面，比较乱，希望大家不要介意哈，一个字，一个字打得哦，连复制都不行（视频），我容易吗我？呜呜&#8230;</p>
<p>听完后，感觉要想应用sms，现在还不现实，因为现在网管会整个网络系统还没有采用域来管理，所以如果用SMS的话，只有采用最低效的Network模式（详见笔记），意义不大。</p>
<p>算了，不想说了，感冒阿，太惨了!!!贴!!!</p>
<p>===== 华丽的分界线 =====</p>
<p><strong>SMS在企业中的应用</strong></p>
<p>中科院软件研究所 史震</p>
<p>一、体系架构：</p>
<p>* 操作架构</p>
<p>Based on Windows Server 2003：<br />
Like DNS,DHCP,ISA Server(Security),SQL Server(DataBase),SMS Server</p>
<p>* 应用程序架构</p>
<p>Based on Application Center 2000</p>
<p>* 信息流架构</p>
<p>Based on Exchange2003</p>
<p>二、SMS应用范围：</p>
<p>* Asset Management:Hardware<br />
* Software Distribution:Software<br />
* Security Update:Update(Better than SUS:Not only Server SP,Office SP)<br />
* Remote Computer Support:Remote Help<br />
* Mobility Support:移动用户流量本地化</p>
<p>三、Features of SMS:</p>
<p>* Hardware and software inventory:</p>
<p>Hardware software change<br />
Software inventory<br />
Example:<br />
Forbidden QQ,MSN LIKE Program</p>
<p>*           Software Distribution:</p>
<p>Noman setup<br />
活动目录中的组策略只能基于域来分发软件，如果只属于某个工作组则无能为力了</p>
<p>*           Software metering:</p>
<p>盗版软件<br />
软件使用信息，使用者，启动、停止时间、频率<br />
Example:<br />
某台计算机安装了Office2000但一直没有使用，或使用特别少，再购买时减少购买Office2003数量</p>
<p>*           Remote Tools:</p>
<p>减少时间成本</p>
<p>* Software Update Management:</p>
<p>Test<br />
Distribution<br />
Compared to SUS:<br />
Not only Windows Service Pack<br />
But also Office,SQL,Exchange,RRS Service Pack</p>
<p>四、Administrative Support Features:</p>
<p>*         Reporting:</p>
<p>IE Explorer report viewer:<br />
1、软件，硬件资产清单；<br />
2、计算机详细配置、状态<br />
3、分发软件、分布时问题，软件使用情况</p>
<p>Feature：<br />
1、可定制<br />
2、可Filter：</p>
<p>如：没有安装xp SP2的计算机</p>
<p>* Status viewing:</p>
<p>某个组件执行特定活动的特征串</p>
<p>* Performance viewing:</p>
<p>Example：大量广播排查</p>
<p>*         Backup and recovery tools:</p>
<p>备份恢复SMS站点</p>
<p>* Remote Control</p>
<p>五、Mixed version Hierarchy Considerations:</p>
<p>Certain operating systems and features are no longer supported</p>
<p>SMS 2.0 ok,SMS 2003 no：</p>
<p>*         Windows 3.1,3.1.1,95,Before NT 4.0 sp5 pre,ME，XP Home Edition，PE，<br />
*         Novel<br />
*         Before Sql 7.0 sp2<br />
*         SBS(Small Bussiness Server)<br />
*         Alpha CPU System</p>
<p>六、Explaining SMS Hierarchies</p>
<p>SMS Site：</p>
<p>* 管理资源<br />
* 三位代码唯一标示<br />
* 主（父子）、辅站点（子）<br />
* 主：数据库支持，存储数据，SQL Server，管理工具<br />
* 父子信任关系<br />
* 有广域网连接时考虑分层结构</p>
<p>七、Key Components:</p>
<p>* Site Server</p>
<p>* Site System Roles:<br />
Client Access Point<br />
Management Point<br />
Reporing Point<br />
Distribution Point<br />
Server Locator Point</p>
<p>* Site Database</p>
<p>* Advanced Client:2000 later</p>
<p>* Legacy Client:windows98,NT 4.0 SP6</p>
<p>* Client &#8212; Site System Roles &#8212; Site Server &#8212; Database</p>
<p>八、Services that Site System Provide:</p>
<p>*        CAP(Client Access Point): For Legacy Client<br />
Legacy Client通过活动目录AB的查询找到SLP(Server Locator Point),然后找到CAP</p>
<p>* Distribute Point:<br />
安装软件时</p>
<p>*        Management Point:For Advanced Client</p>
<p>* Reporing Point:<br />
直接访问数据库</p>
<p>九、The Role of an SMS Client</p>
<p>* 安装SMS Client Agent</p>
<p>* Key Tasks:</p>
<p>* 接受处理SMS数据指令</p>
<p>* 扫描信息，报告SMS站点服务器</p>
<p>* 安装程序和更新</p>
<p>十、What are Collections?</p>
<p>* 对特定资源的划分</p>
<p>* 创建集合（在服务器端）：</p>
<p>* Example:<br />
对All Windows XP System Collection分发XP SP2<br />
创建发现模式&#8212;创建Collection（通过模式）</p>
<p>十一、Explaning SMS Site-to-Site Communication</p>
<p>* Consideration for creating multiple site:</p>
<p>Network Performance<br />
Number of resources(数据库宿主主机性能)<br />
Features required by users（SMS2003 plus SMS2.0）<br />
International consideration（语言考虑）<br />
Corporate structure<br />
Domain structure（也可考虑修改不合理的域结构）</p>
<p>* How information flows form site to site:</p>
<p>Management Instructions and Data:From parent to Child<br />
Resource Report and Client data:From Child to parent</p>
<p>十二、Explaining SMS Site:</p>
<p>* What are SMS Site Boundaries?<br />
活动目录站点边界（AD Name）<br />
Legacy：必须位于AD内<br />
Advanced：Mobile，可指定</p>
<p>* 资源搜集模式：<br />
Network网络发现：Based on IP Address，多个LAN，多个站点，信息统一于父站点<br />
AD系统发现：从AD数据库中读取<br />
AD User发现<br />
AD System Group发现<br />
Windows User Domain Account发现<br />
Windows Group Domain Account发现<br />
Heartbeat发现：必须维持联系（一般都要启用）</p>
<p>十三、答疑时间：</p>
<p>1、SMS，MOM（Microsoft Operations Manager）差别?<br />
SMS静态、MOM动态</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/11/26/sms-tutorial/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>参加电子设计大赛的入</title>
		<link>http://blog.axqd.net/2004/10/19/electronic-design-competition/</link>
		<comments>http://blog.axqd.net/2004/10/19/electronic-design-competition/#comments</comments>
		<pubDate>Tue, 19 Oct 2004 06:12:15 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[沈弘]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=355</guid>
		<description><![CDATA[前日有同学问起，特此分享： http://blog.axqd.net/2004/10/19/serial-communication-with-borland-c-builder/ http://blog.axqd.net/2004/10/19/serial-communication/]]></description>
			<content:encoded><![CDATA[<p>前日有同学问起，特此分享：</p>
<p>http://blog.axqd.net/2004/10/19/serial-communication-with-borland-c-builder/</p>
<p>http://blog.axqd.net/2004/10/19/serial-communication/</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/10/19/electronic-design-competition/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>在C++ Builder中利用串行通信控件编程</title>
		<link>http://blog.axqd.net/2004/10/19/serial-communication/</link>
		<comments>http://blog.axqd.net/2004/10/19/serial-communication/#comments</comments>
		<pubDate>Tue, 19 Oct 2004 06:06:18 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[borland]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[沈弘]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=354</guid>
		<description><![CDATA[摘要：串口是常用的计算机与外部串行设备之间的数据传输通道，由于串行通信方便易行，所以应用广泛。本文介绍了在C++ Builder中如何利用串行通信控件进行串行通信编程。 一、引言 目前，在用计算机进行数据传输时，常用的是串行通信方式。用C＋＋ Builder来编写串行通信程序时，可以调用Windows API函数，也可以利用VB中的MSComm控件。 利用 API函数编写实际应用程序时，往往要考虑多线程的问题，这样编出来的程序不但十分庞大，而且结构比较复杂，继承性差，维护困难。但是使用串行通信控件就相对简单一些，而且功能强大，性能安全可靠。本文就简单的介绍一下在C++ Builder中利用MSComm控件进行编程。 二、MSComm控件的常用属性和事件 MSComm 控件通过串行端口传输和接收数据，为应用程序提供串行通讯功能。具体的来说，它提供了两种处理通信问题的方法：一是事件驱动(Event－driven)方法，一是查询法。 事件驱动方式 在使用事件驱动法设计程序时，每当有新字符到达，或端口状态改变，或发生错误时，MSComm控件将解发OnComm事件，而应用程序在捕获该事件后，通过检查MSComm控件的CommEvent属性可以获知所发生的事件或错误，从而采取相应的操作。这种方法的优点是程序响应及时，可靠性高。 查询方式 查询方式实质上还是事件驱动，但在有些情况下，这种方式显得更为便捷。在程序的每个关键功能之后，可以通过检查 CommEvent 属性的值来查询事件和错误。如果应用程序较小，并且是自保持的，这种方法可能是更可取的。 1.MSComm 控件的常用属性 CommPort属性：设置或返回通讯端口号，可以设置为1到16之间的任何值，本系统采用缺省值2； Settings属性：以字符串形式设置或返回波特率、奇偶校验、数据位和停止位，本系统采用缺省值&#8221;9600，n，8，1&#8243;; PortOpen属性：设置或返回通讯口的状态以及打开和关闭端口，可通过把该属性设置为true或者false来打开或者关闭端口； InBufferSize和OutBufferSize属性：分别设置接收和发送缓冲区分配的内存数量，单位为字节，缺省值分别为1024byte和512byte； InputLen属性：确定希望从接收缓冲区移出的字符数量，当InputLen＝0时，一次把接收缓冲区的字符全部移出； Input属性：从接收缓冲区中读出数据，然后将该数据从缓冲区移走。 OutPut属性：向发送缓冲区传递待发送的数据。 InBufferCount和OutBufferCount属性：分别确定当前驻留在接收缓冲区等待被取出和发送缓冲区准备发送的字符数量，这两个属性设置为0，接收和发送缓冲区的内容将被清除； InputMode属性：设置接收传入数据的格式，设置为0采用文本形式，设置为1采用二进制格式，本系统设置为二进制格式进行发送和接收； SThreshold属性：保存一个产生发送OnComm事件的界限值，本系统设置该属性为0，发送数据时不产生OnComm事件； RThreshold属性：设定当接收几个字符时触发OnComm事件，本系统设置该属性为1，每接收一个字符就产生一个OnComm事件； 2．MSComm控件的事件 MSCOMM控件只使用一个事件OnComm，用属性CommEvent的十七个值来区分不同的触发时机。主要有以下几个： (1)CommEvent=1时：传输缓冲区中的字符个数已少于Sthreshold(可设置的属性值)个。 (2)CommEvent=2时：接收缓冲区中收到Rthreshold(可设置的属性值)个字符，利用此事件可编写接收数据的过程。 (3)CommEvent=3时：CTS线发生变化。 (4)CommEvent=4时：DSR线发生变化。 (5)CommEvent=5时：CD线发生变化。 (6)CommEvent=6时：检测到振铃信号。 另外十种情况是通信错误时产生，即错误代码。 三、程序的实现 1.注册MSComm控件 众所周知，C++Builder本身并不提供串行通讯控件MSComm，但我们却可以通过注册后直接使用它。启动C++Builder5.0后，然后选择C++Builder主菜单中的Component菜单项，单击Import Active Control命令，弹出Import Active窗口，选择Microsoft Comm Control6.0，再选择Install按钮执行安装命令,系统将自动进行编译,编译完成后即完成MSComm控件在C++Builder中的注册, 系统默认安装在控件板的Active页,接下来我们就可以像使用C++Builder本身提供的控件那样使用新注册的MSComm控件了。（前提条件是你的机子上安装了Visual Basic，或者有它的库） 2.具体实现 新建一个工程Project1，把注册好的MSComm控件加入到窗体中，然后再加入5个ComboBox用来设置串口的属性，4个Button分别用来&#8221;打开串口&#8221; &#8220;关闭串口&#8221;"发送数据&#8221;"保存数据&#8221; ，2个Memo控件分别用来显示接收到的数据和发送的数据。再加入一个Shape控件用来标明串口是否打开。 ComboBox1用来设置串口号，通过它的Items属性设置1，2，3，4四个列表项分别表示COM1,COM2,COM3,COM4口。 [...]]]></description>
			<content:encoded><![CDATA[<p>摘要：串口是常用的计算机与外部串行设备之间的数据传输通道，由于串行通信方便易行，所以应用广泛。本文介绍了在C++ Builder中如何利用串行通信控件进行串行通信编程。</p>
<p><strong><span style="color: #ff0000;">一、引言</span></strong></p>
<p>目前，在用计算机进行数据传输时，常用的是串行通信方式。用C＋＋ Builder来编写串行通信程序时，可以调用Windows API函数，也可以利用VB中的MSComm控件。 利用 API函数编写实际应用程序时，往往要考虑多线程的问题，这样编出来的程序不但十分庞大，而且结构比较复杂，继承性差，维护困难。但是使用串行通信控件就相对简单一些，而且功能强大，性能安全可靠。本文就简单的介绍一下在C++ Builder中利用MSComm控件进行编程。</p>
<p><span style="color: #ff0000;"><strong>二、MSComm控件的常用属性和事件</strong></span></p>
<p>MSComm 控件通过串行端口传输和接收数据，为应用程序提供串行通讯功能。具体的来说，它提供了两种处理通信问题的方法：一是事件驱动(Event－driven)方法，一是查询法。</p>
<p><strong>事件驱动方式</strong></p>
<p>在使用事件驱动法设计程序时，每当有新字符到达，或端口状态改变，或发生错误时，MSComm控件将解发OnComm事件，而应用程序在捕获该事件后，通过检查MSComm控件的CommEvent属性可以获知所发生的事件或错误，从而采取相应的操作。这种方法的优点是程序响应及时，可靠性高。</p>
<p><strong>查询方式</strong></p>
<p>查询方式实质上还是事件驱动，但在有些情况下，这种方式显得更为便捷。在程序的每个关键功能之后，可以通过检查 CommEvent 属性的值来查询事件和错误。如果应用程序较小，并且是自保持的，这种方法可能是更可取的。</p>
<p>1.MSComm 控件的常用属性</p>
<p>CommPort属性：设置或返回通讯端口号，可以设置为1到16之间的任何值，本系统采用缺省值2；<br />
Settings属性：以字符串形式设置或返回波特率、奇偶校验、数据位和停止位，本系统采用缺省值&#8221;9600，n，8，1&#8243;;<br />
PortOpen属性：设置或返回通讯口的状态以及打开和关闭端口，可通过把该属性设置为true或者false来打开或者关闭端口；<br />
InBufferSize和OutBufferSize属性：分别设置接收和发送缓冲区分配的内存数量，单位为字节，缺省值分别为1024byte和512byte；<br />
InputLen属性：确定希望从接收缓冲区移出的字符数量，当InputLen＝0时，一次把接收缓冲区的字符全部移出；<br />
Input属性：从接收缓冲区中读出数据，然后将该数据从缓冲区移走。<br />
OutPut属性：向发送缓冲区传递待发送的数据。<br />
InBufferCount和OutBufferCount属性：分别确定当前驻留在接收缓冲区等待被取出和发送缓冲区准备发送的字符数量，这两个属性设置为0，接收和发送缓冲区的内容将被清除；<br />
InputMode属性：设置接收传入数据的格式，设置为0采用文本形式，设置为1采用二进制格式，本系统设置为二进制格式进行发送和接收；<br />
SThreshold属性：保存一个产生发送OnComm事件的界限值，本系统设置该属性为0，发送数据时不产生OnComm事件；<br />
RThreshold属性：设定当接收几个字符时触发OnComm事件，本系统设置该属性为1，每接收一个字符就产生一个OnComm事件；</p>
<p>2．MSComm控件的事件<br />
MSCOMM控件只使用一个事件OnComm，用属性CommEvent的十七个值来区分不同的触发时机。主要有以下几个：</p>
<p>(1)CommEvent=1时：传输缓冲区中的字符个数已少于Sthreshold(可设置的属性值)个。<br />
(2)CommEvent=2时：接收缓冲区中收到Rthreshold(可设置的属性值)个字符，利用此事件可编写接收数据的过程。<br />
(3)CommEvent=3时：CTS线发生变化。<br />
(4)CommEvent=4时：DSR线发生变化。<br />
(5)CommEvent=5时：CD线发生变化。<br />
(6)CommEvent=6时：检测到振铃信号。</p>
<p>另外十种情况是通信错误时产生，即错误代码。</p>
<p><span style="color: #ff0000;"><strong>三、程序的实现</strong></span></p>
<p>1.注册MSComm控件</p>
<p>众所周知，C++Builder本身并不提供串行通讯控件MSComm，但我们却可以通过注册后直接使用它。启动C++Builder5.0后，然后选择C++Builder主菜单中的Component菜单项，单击Import Active Control命令，弹出Import Active窗口，选择Microsoft Comm Control6.0，再选择Install按钮执行安装命令,系统将自动进行编译,编译完成后即完成MSComm控件在C++Builder中的注册, 系统默认安装在控件板的Active页,接下来我们就可以像使用C++Builder本身提供的控件那样使用新注册的MSComm控件了。（前提条件是你的机子上安装了Visual Basic，或者有它的库）</p>
<p>2.具体实现</p>
<p>新建一个工程Project1，把注册好的MSComm控件加入到窗体中，然后再加入5个ComboBox用来设置串口的属性，4个Button分别用来&#8221;打开串口&#8221; &#8220;关闭串口&#8221;"发送数据&#8221;"保存数据&#8221; ，2个Memo控件分别用来显示接收到的数据和发送的数据。再加入一个Shape控件用来标明串口是否打开。</p>
<p>ComboBox1用来设置串口号，通过它的Items属性设置1，2，3，4四个列表项分别表示COM1,COM2,COM3,COM4口。 ComboBox2用来设置波特率，ComboBox3用来设置奇偶校验位，ComboBox4用来设置数据位，ComboBox5用来设置停止位。他们的缺省值分别是9600，n，8，1。</p>
<p>Button1用来打开串口，Button2用来关闭串口，Button3用来发送数据，Button4用来保存数据。Memo1用来显示发送的数据，Memo2显示接收的数据。Shape1的Shape属性设置为stCircle。<br />
下面给出部分源码：</p>
<p><code>__fastcall TForm1::TForm1(TComponent* Owner)<br />
: TForm(Owner)<br />
{<br />
if(MSComm1-&gt;PortOpen==true)<br />
{<br />
Button1-&gt;Enabled=false;<br />
Button2-&gt;Enabled=true;<br />
Button3-&gt;Enabled=true;<br />
Button4-&gt;Enabled=true;<br />
Shape1-&gt;Brush-&gt;Color=clGreen;<br />
}<br />
else<br />
{<br />
Button2-&gt;Enabled=true;<br />
Button2-&gt;Enabled=false;<br />
Button3-&gt;Enabled=false;<br />
Button4-&gt;Enabled=false;<br />
Shape1-&gt;Brush-&gt;Color=clRed;<br />
}<br />
}<br />
void __fastcall TForm1::Button1Click(TObject *Sender) / /打开串口<br />
{<br />
if(MSComm1-&gt;PortOpen!=true)<br />
{<br />
MSComm1-&gt;CommPort=StrToInt(ComboBox1-&gt;Text);//选择串口号<br />
MSComm1-&gt;Settings=<br />
ComboBox2-&gt;Text+","+<br />
ComboBox3-&gt;Text+","+<br />
ComboBox4-&gt;Text+","+<br />
ComboBox5-&gt;Text; file://设置串口的属性波特率、奇偶校验、数据位和、//停止位。<br />
MSComm1-&gt;InputMode=0;//设置传入数据的格式，0表示文本形式<br />
MSComm1-&gt;PortOpen=true;//打开串口<br />
Button1-&gt;Enabled=false;<br />
Button2-&gt;Enabled=true;<br />
Button3-&gt;Enabled=true;<br />
Button4-&gt;Enabled=true;<br />
Shape1-&gt;Brush-&gt;Color=clGreen;<br />
}<br />
}<br />
void __fastcall TForm1::Button2Click(TObject *Sender) / /关闭串口<br />
{<br />
if(MSComm1-&gt;PortOpen!=false)<br />
{<br />
MSComm1-&gt;PortOpen=false;<br />
Button1-&gt;Enabled=true;<br />
Button2-&gt;Enabled=false;<br />
Button3-&gt;Enabled=false;<br />
Button4-&gt;Enabled=false;<br />
Shape1-&gt;Brush-&gt;Color=clRed;<br />
}<br />
else<br />
{<br />
Button1-&gt;Enabled=false;<br />
Button2-&gt;Enabled=true;<br />
Shape1-&gt;Brush-&gt;Color=clRed;<br />
}<br />
}</code></p>
<p>MSComm控件的Input和Output属性在Object Inspector中是看不到的，而且在C++Builder环境下这两个属性已不在是VB、VC中的原类型，而是OleVariant类型，也就是 Ole万能变量，这就需要我们在发送接收数据时要把数据转换成Ole类型。</p>
<p><code>void __fastcall TForm1::Button3Click(TObject *Sender) file://发送Memo2中的数据<br />
{<br />
MSComm1-&gt;Output=StringToOleStr(Memo2-&gt;Text); file://把AnsiString型转化成//Ole形式。<br />
}</code></p>
<p>通过OnComm事件接收数据，必须把MSComm的RThreshold属性设置为大于0，只有这样在接收到字符时才会产生一个OnComm事件。</p>
<p><code>void __fastcall TForm1::MSComm1Comm(TObject *Sender)<br />
{<br />
AnsiString str; file://声明一个AnsiString类型的变量<br />
OleVariant s; file://声明一个用于接收数据的OleVariant变量。<br />
if(MSComm1-&gt;CommEvent==comEvReceive)<br />
// 接收缓冲区中是否收到Rthreshold个字符。<br />
{<br />
if(MSComm1-&gt;InBufferCount)// 是否有字符驻留在接收缓冲区等待被取出<br />
{<br />
s=MSComm1-&gt;Input;//接收数据<br />
str=s.AsType(varString); file://把接收到的OleVariant变量转换成AnsiString类型<br />
Memo1-&gt;Text=Memo1-&gt;Text+str;//把接收到的数据显示在Memo1中。<br />
}<br />
}<br />
}</code></p>
<p>要保存数据应该再加入一个SaveDialog模块</p>
<p><code>void __fastcall TForm1::Button4Click(TObject *Sender)<br />
file://把Memo1中的数据保存在指定的文件中<br />
{<br />
AnsiString filename1;<br />
SaveDialog1-&gt;Filter="Text files (*.txt)|*.txt|All files (*.*)|*.*";//文件类型过滤器<br />
SaveDialog1-&gt;FilterIndex=2;<br />
if(SaveDialog1-&gt;Execute())<br />
{<br />
filename1=SaveDialog1-&gt;FileName;<br />
Memo1-&gt;Lines-&gt;SaveToFile(filename1);//把收到的数据保存在文件filename1中<br />
}<br />
}</code></p>
<p><span style="color: #ff0000;"><strong>四、结束语</strong></span></p>
<p>上面给出了C++ Builder中利用MSComm控件进行串行通信编程的实现和部分源码，有了上面的参照读者可以根据实际需要编写出具有发送文件和接收文件功能的程序。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/10/19/serial-communication/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Serial Communication with Borland C++ Builder</title>
		<link>http://blog.axqd.net/2004/10/19/serial-communication-with-borland-c-builder/</link>
		<comments>http://blog.axqd.net/2004/10/19/serial-communication-with-borland-c-builder/#comments</comments>
		<pubDate>Tue, 19 Oct 2004 05:44:15 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[borland]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[沈弘]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=353</guid>
		<description><![CDATA[David Poinsett November 1999 d.poinsett@traverse.com Introduction&#8230; I wish this site had been around when I was trying to figure out how to make serial communications work in Windows95. I, like many programmers, was hit with the double-whammy of having to learn Windows programming and Win95 serial comm programming at the same time. I found both [...]]]></description>
			<content:encoded><![CDATA[<p>David Poinsett<br />
November 1999<br />
d.poinsett@traverse.com</p>
<p><strong>Introduction&#8230;</strong></p>
<p>I wish this site had been around when I was trying to figure out how to make serial communications work in Windows95. I, like many programmers, was hit with the double-whammy of having to learn Windows programming and Win95 serial comm programming at the same time. I found both tasks confusing at best. It was particularly frustrating because I had, over the years, written so much stuff (including lots of serial comm software) for the DOS environment and numerous embedded applications. Interrupt driven serial comm, DMA transfer serial comm, TSR serial comm, C, assembler, various processors&#8230;you name it, it had written it. Yet, everything I knew seemed upside-down in the message-driven-callback world of Windows.</p>
<p>After spending lots of money on books and seemingly endless effort, I have finally gotten enough of a handle on Win95 and serial comm programming to write something usable in this environment. Borland&#8217;s C++ Builder has done a lot to help make Win95 programming easier and, once you know the tricks, the serial communications stuff is pretty easy, too.</p>
<p>The purpose of this site is to spare you hardship of my early efforts and get you up and running with your Win9x/NT serial comm programming as quickly as possible. If you&#8217;re already familiar with using BCB to develop Windows programs, the example code should be plenty to get you going. You can also download the source code in BCBComm.zip. Good luck.</p>
<p><strong>The Example&#8230; </strong></p>
<p>In the example that follows we&#8217;re going to write a bare-bones program to do serial communication. It will consist of a Form with a Memo object (for text I/O) and a Thread object that handles incoming serial data. There are no menus or other features to distract us from focusing on the serial comm aspect of the program. Obviously, you&#8217;ll want to add these and other elements to a fully functioning program.</p>
<p>Fire up BCB and start a New Project. Place a Memo object on Form1. Using the Object Inspector, set Memo1 properties as follows:</p>
<p><code>Alignment = alClient<br />
MaxLength = 0<br />
ScrollBars = ssVertical<br />
WantReturns = true<br />
WantTabs = false<br />
WordWrap = true</code></p>
<p>Next, under the File | New menu, add a Thread Object. Use TRead for the class name when asked.</p>
<p>You should now have two Unit files: Unit1.cpp for Form1 activity and Unit2.cpp for the thread.</p>
<p>Using the Object Inspector again, create event handlers for the following events. The easiest way to create events handlers is as follows:</p>
<p>Go to the event tab sheet in Object Inspector.<br />
Find the event of interest.<br />
Double-click the blank space next to the event name.<br />
If you follow this scheme, Object Inspector will create and automatically name the event handlers to the same name used in our examples. OK, here are the objects and the events we need to handle:</p>
<p><code>Form1 OnCreate<br />
Form1 OnClose<br />
Memo1 OnKeyPress</code></p>
<p>The framework for Unit1.cpp is now in place. Using the following listing as a guide, fill in Unit1.cpp with the following code. Be sure to note the #includes and global variables. If the framework for event handlers is missing in your program, DO NOT put it there by typing in the framework code! Go back and figure out what you missed. BCB MUST CREATE THE FRAMEWORK FOR YOU.</p>
<p><strong>The Main Form&#8230;</strong></p>
<p><code>//---------------------------------------------------------------------------<br />
#include &lt;vclvcl.h&gt;<br />
#pragma hdrstop<br />
#include "Unit1.h"<br />
// YOU MUST INCLUDE THE HEADER FOR UNIT2 (THE THREAD UNIT)<br />
#include "Unit2.h"<br />
// GLOBAL VARIABLES<br />
HANDLE hComm = NULL;<br />
TRead *ReadThread;<br />
COMMTIMEOUTS ctmoNew = {0}, ctmoOld;<br />
//---------------------------------------------------------------------------<br />
#pragma resource "*.dfm"<br />
TForm1 *Form1;<br />
//---------------------------------------------------------------------------<br />
__fastcall TForm1::TForm1(TComponent* Owner)<br />
: TForm(Owner)<br />
{<br />
}<br />
//---------------------------------------------------------------------------<br />
void __fastcall TForm1::FormCreate(TObject *Sender)<br />
{<br />
DCB dcbCommPort;<br />
// OPEN THE COMM PORT.<br />
// REPLACE "COM2" WITH A STRING OR "COM1", "COM3", ETC. TO OPEN<br />
// ANOTHER PORT.<br />
hComm = CreateFile("COM2",<br />
GENERIC_READ | GENERIC_WRITE,<br />
0,<br />
0,<br />
OPEN_EXISTING,<br />
0,<br />
0);<br />
// IF THE PORT CANNOT BE OPENED, BAIL OUT.<br />
if(hComm == INVALID_HANDLE_VALUE) Application-&gt;Terminate();<br />
// SET THE COMM TIMEOUTS IN OUR EXAMPLE.<br />
GetCommTimeouts(hComm,&amp;ctmoOld);<br />
ctmoNew.ReadTotalTimeoutConstant = 100;<br />
ctmoNew.ReadTotalTimeoutMultiplier = 0;<br />
ctmoNew.WriteTotalTimeoutMultiplier = 0;<br />
ctmoNew.WriteTotalTimeoutConstant = 0;<br />
SetCommTimeouts(hComm, &amp;ctmoNew);<br />
// SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.<br />
// THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST.<br />
// IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER<br />
// THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING.<br />
// ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING.<br />
dcbCommPort.DCBlength = sizeof(DCB);<br />
GetCommState(hComm, &amp;dcbCommPort);<br />
BuildCommDCB("9600,N,8,1", &amp;dcbCommPort);<br />
SetCommState(hComm, &amp;dcbCommPort);<br />
// ACTIVATE THE THREAD. THE FALSE ARGUMENT SIMPLY MEANS IT HITS THE<br />
// GROUND RUNNING RATHER THAN SUSPENDED.<br />
ReadThread = new TRead(false);<br />
}<br />
//---------------------------------------------------------------------------<br />
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &amp;Action)<br />
{<br />
// TERMINATE THE THREAD.<br />
ReadThread-&gt;Terminate();<br />
// WAIT FOR THREAD TO TERMINATE,<br />
// PURGE THE INTERNAL COMM BUFFER,<br />
// RESTORE THE PREVIOUS TIMEOUT SETTINGS,<br />
// AND CLOSE THE COMM PORT.<br />
Sleep(250);<br />
PurgeComm(hComm, PURGE_RXABORT);<br />
SetCommTimeouts(hComm, &amp;ctmoOld);<br />
CloseHandle(hComm);<br />
}<br />
//---------------------------------------------------------------------------<br />
void __fastcall TForm1::Memo1KeyPress(TObject *Sender, char &amp;Key)<br />
{<br />
// TRANSMITS ANYTHING TYPED INTO THE MEMO AREA.<br />
TransmitCommChar(hComm, Key);<br />
// THIS PREVENTS TYPED TEXT FROM DISPLAYING GARBAGE ON THE SCREEN.<br />
// IF YOU ARE CONNECTED TO A DEVICE THAT ECHOES CHARACTERS, SET<br />
// Key = 0 WITHOUT THE OTHER STUFF.<br />
if(Key != 13 &amp;&amp; (Key &lt; ' ' || Key &gt; 'z')) Key = 0;<br />
}<br />
//---------------------------------------------------------------------------</code></p>
<p>Now we turn our attention to the thread code in Unit2.cpp. The framework should already be in place. Use this listing as a guide and fill in Unit2.cpp with the following code.</p>
<p><strong>The Thread&#8230;</strong></p>
<p><code>//---------------------------------------------------------------------------<br />
#include &lt;vclvcl.h&gt;<br />
#pragma hdrstop<br />
// YOU MUST INCLUDE THE HEADER FOR UNIT1<br />
#include "Unit1.h"<br />
#include "Unit2.h"<br />
extern HANDLE hComm;<br />
char InBuff[100];<br />
//---------------------------------------------------------------------------<br />
// Important: Methods and properties of objects in VCL can only be<br />
// used in a method called using Synchronize, for example:<br />
//<br />
// Synchronize(UpdateCaption);<br />
//<br />
// where UpdateCaption could look like:<br />
//<br />
// void __fastcall TRead::UpdateCaption()<br />
// {<br />
//  Form1-&gt;Caption = "Updated in a thread";<br />
// }<br />
//---------------------------------------------------------------------------<br />
__fastcall TRead::TRead(bool CreateSuspended)<br />
: TThread(CreateSuspended)<br />
{<br />
}<br />
//---------------------------------------------------------------------------<br />
void __fastcall TRead::DisplayIt()<br />
{<br />
// NOTE THAT IN THIS EXAMPLE, THERE IS NO EFFORT TO MONITOR<br />
// HOW MUCH TEXT HAS GONE INTO Memo1. IT CAN ONLY HOLD ABOUT 32K.<br />
// ALSO, NOTHING IS BEING DONE ABOUT NON-PRINTABLE CHARACTERS<br />
// OR CR-LF'S EMBEDDED IN THE STRING.<br />
// DISPLAY THE RECEIVED TEXT.<br />
Form1-&gt;Memo1-&gt;SetSelTextBuf(InBuff);<br />
}<br />
//---------------------------------------------------------------------------<br />
void __fastcall TRead::Execute()<br />
{<br />
//---- Place thread code here ----<br />
DWORD dwBytesRead;<br />
// MAKE THE THREAD OBJECT AUTOMATICALLY DESTROYED WHEN THE THREAD<br />
// TERMINATES.<br />
FreeOnTerminate = true;<br />
while(1)<br />
{<br />
// TRY TO READ CHARACTERS FROM THE SERIAL PORT.<br />
// IF THERE ARE NONE, IT WILL TIME OUT AND TRY AGAIN.<br />
// IF THERE ARE, IT WILL DISPLAY THEM.<br />
ReadFile(hComm, InBuff, 50, &amp;dwBytesRead, NULL);<br />
if(dwBytesRead)<br />
{<br />
InBuff[dwBytesRead] = 0; // NULL TERMINATE THE STRING<br />
Synchronize(DisplayIt);<br />
}<br />
}<br />
}<br />
//---------------------------------------------------------------------------</code></p>
<p><strong>One last thing&#8230;</strong></p>
<p>To do a synchronized call to DisplayIt() from within the thread&#8217;s Execute() function, DisplayIt() it must be declared as a __fastcall type in the header file. Here&#8217;s how to do it.</p>
<p>Open the header file &#8220;unit2.h&#8221; and add the DisplayIt() line as shown below:</p>
<p><code>//---------------------------------------------------------------------------<br />
class TRead : public TThread<br />
{<br />
private:<br />
protected:<br />
void __fastcall DisplayIt(void); // ADD THIS LINE<br />
void __fastcall Execute();<br />
public:<br />
__fastcall TRead(bool CreateSuspended);<br />
};<br />
//---------------------------------------------------------------------------</code></p>
<p><strong>Notes&#8230;</strong></p>
<p>As mentioned earlier this example focuses strictly on the core elements that make the serial communication functions work. In its present form it&#8217;s unlikely to be particularly useful or acceptable in an actual application. In other words, you need to add what&#8217;s missing. If you&#8217;ve followed along this far, that should not be too difficult. To minimize any confusion on what&#8217;s missing, I&#8217;ll highlight some of the areas that should be addressed:</p>
<p>There is little or no provision for error handling<br />
The 32K display limit of the Memo object is not handled<br />
For proper text display in Memo, ignore linefeeds and replace carriage returns with a CR-LF pair<br />
Menus<br />
Storing incoming serial data to disk<br />
Sending disk contents out serial port<br />
Handshaking<br />
Protocol (Xmodem, Zmodem, etc.)<br />
There are several ways to test your work. One method is to perform a loop-back test by jumping pins 2 and 3 on your computer&#8217;s RS-232 connector. With the loop-back connection anything you type into the Memo area will be echoed back.</p>
<p>Here are some online references that you might find useful:</p>
<p>Serial Communications in Win32 . This is a comprehensive reference.<br />
www.ontrak.net . Excellent example of simple serial port access.<br />
www.temporaldoorway.com . Good example of threaded serial program with overlapped I/O.<br />
www.codeguru.com . Yet another example (more for VC++).<br />
Good luck.<br />
==============================================================================</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/10/19/serial-communication-with-borland-c-builder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IIS 5安全清单</title>
		<link>http://blog.axqd.net/2004/10/18/check-list-for-iis5/</link>
		<comments>http://blog.axqd.net/2004/10/18/check-list-for-iis5/#comments</comments>
		<pubDate>Mon, 18 Oct 2004 05:17:37 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[iis]]></category>
		<category><![CDATA[netunion]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=352</guid>
		<description><![CDATA[IIS的安全性首先要基于Windows系统的安全性，详细部分请见相关文档。对IIS的安全控制可从以下四个方面进行： * IP地址的域名安全限制（目录/文件安全性）：视需求而定，可暂时阻止DOS； * IIS身份验证安全限制（目录/文件安全性）： 匿名访问：帐号IUSR_HOSTNAME,不过期，不能更改口令，Guest组成员； 基本身份验证：服务器上的真实用户名/密码，明文传输； Digest身份验证：哈希散列值传输；（只使用Windows2k的域） 集成Windows验证：需要用相同用户名和密码登录； * IIS权限 * NTFS权限 一、 为虚拟目录设置适当的 ACL 虽然一般情况下，虚拟目录的ACL取决于应用程序的需要，但一些通常的规则依然适用； 1、脚本和动态内容 可读 可执行脚本 2、静态内容 可读 3、可执行程序 可读 可执行 4、类数据库内容 可读 可写 推荐为每一种文件类型创建新的目录，在这些目录上仔细设置 ACL，并允许 ACL 继承到文件。至少建站第一步就应该在ACL中删除虚拟目录和Web页面的Everyone组。 例如，目录结构可能如下所示： * myserverstatic (.html) * myserverinclude (.inc) * myserverscript (.asp) * myserverexecutable (.dll) * myserverimages (.gif, .jpeg) 此外，有两个目录需要特别注意： * ftproot (FTP server) * [...]]]></description>
			<content:encoded><![CDATA[<p>IIS的安全性首先要基于Windows系统的安全性，详细部分请见<a href="http://blog.axqd.net/2004/10/18/check-list-for-win-2k/">相关文档</a>。对IIS的安全控制可从以下四个方面进行：</p>
<p>* IP地址的域名安全限制（目录/文件安全性）：视需求而定，可暂时阻止DOS；<br />
* IIS身份验证安全限制（目录/文件安全性）：<br />
匿名访问：帐号IUSR_HOSTNAME,不过期，不能更改口令，Guest组成员；<br />
基本身份验证：服务器上的真实用户名/密码，明文传输；<br />
Digest身份验证：哈希散列值传输；（只使用Windows2k的域）<br />
集成Windows验证：需要用相同用户名和密码登录；<br />
* IIS权限<br />
* NTFS权限</p>
<p>一、 为虚拟目录设置适当的 ACL</p>
<p>虽然一般情况下，虚拟目录的ACL取决于应用程序的需要，但一些通常的规则依然适用；</p>
<p>1、脚本和动态内容<br />
可读<br />
可执行脚本<br />
2、静态内容<br />
可读<br />
3、可执行程序<br />
可读<br />
可执行<br />
4、类数据库内容<br />
可读<br />
可写</p>
<p>推荐为每一种文件类型创建新的目录，在这些目录上仔细设置 ACL，并允许 ACL 继承到文件。至少建站第一步就应该在ACL中删除虚拟目录和Web页面的Everyone组。</p>
<p>例如，目录结构可能如下所示：<br />
* myserverstatic (.html)<br />
* myserverinclude (.inc)<br />
* myserverscript (.asp)<br />
* myserverexecutable (.dll)<br />
* myserverimages (.gif, .jpeg)</p>
<p>此外，有两个目录需要特别注意：<br />
* ftproot (FTP server)<br />
* mailroot (SMTP server)</p>
<p>这两个目录上的 ACL 都是“Everyone（完全控制）”，应当根据您的功能设置更加严格的ACL，若不使用则不要安装。</p>
<p>对于仅开启IIS的主机，可以参考下列ACL设置（下面ACL采用的是极其严格的ACL，可能会对管理及SQL等的使用造成不便，应在此基础上逐项添加权限，才能做到权限最小化）：</p>
<p>1.对于所有硬盘分区：<br />
System 完全控制<br />
Administrator 完全控制<br />
允许继承<br />
2.Program FilesCommon Files<br />
Everyone 读取及运行 列出文件目录 读取<br />
允许继承<br />
3.webroot<br />
IUSR_HOSTNAME 读取及运行 列出文件目录 读取<br />
允许继承<br />
4.Winntsystem32下除Inetsrv，Centsrv以外的所有目录<br />
不允许继承<br />
5.Winnt下除Downloaded Program Files、Help、IIS Temporary Compressed Files、Offline Web Pages、system32、Tasks、Temp、Web以外的所有目录<br />
不允许继承<br />
6.Winnt<br />
Everyone 读取及运行 列出文件和目录 读取<br />
允许继承<br />
7.WinntTemp<br />
Everyone 修改<br />
允许继承</p>
<p>除上面提到的权限外，删除所有用户、组的权限。</p>
<p>二、 设置适当的 IIS 日志文件 ACL</p>
<p>请确保 IIS 生成的日志文件 (%systemroot%system32LogFiles) 上的 ACL 是：<br />
Administrators（完全控制）<br />
System（完全控制）<br />
Everyone (RWC)</p>
<p>三、 启用日志记录</p>
<p>通过下列步骤使用 W3C 扩展日志记录格式：</p>
<p>1. 站点|属性|网站|启用日志<br />
2. 活动日志格式|W3C 扩展日志文件格式|属性|扩展属性：<br />
客户端 IP 地址<br />
用户名<br />
方法<br />
URI 资源<br />
Win32 状态<br />
用户代理<br />
服务器 IP 地址（如果多网卡）<br />
服务器端口</p>
<p>当您检查日志时，请注意错误5，即被拒绝的访问。</p>
<p><code>[小知识]<br />
</code> <code>如何察看错误代码所代表的意义？net helpmsg</code></p>
<p>四、 验证可执行内容的可信度</p>
<p>用 DumpBin 工具来查看可执行内容是否调用了某些 API。许多 Win32 开发工具都含有 DumpBin(tdump,dumpbin…)。</p>
<p>五、 在 IIS 服务器上更新根目录的 CA 证书</p>
<p>该过程包括两个步骤：</p>
<p>第一步：添加所有信任的新根目录证书颁发机构 (CA) 证书；<br />
第二步：删除所有不信任的根目录 CA 证书；</p>
<p>请注意如果您不知道发布根目录证书的公司名称，那么就不应当信任他们！</p>
<p>注意： 不要删除 Microsoft 或 VeriSign 根目录。操作系统会大量使用它们。</p>
<p>六、 禁用或删除所有示例应用程序</p>
<p>例如Internet Information Server 5 中的示例文件：</p>
<p>IIS 示例 IISSamples c:inetpubiissamples<br />
IIS 文档 IISHelp c:winnthelpiishelp<br />
数据访问 MSADC c:program filescommon filessystemmsadc</p>
<p>七、 禁用或删除不需要的COM 组件</p>
<p>考虑禁用“文件系统对象”组件（FSO），但需要注意的是这样也会删除 Dictionary 对象。通常禁用COM组件的发式是直接卸载其链接文件（撤消注册），具体步骤是：regsvr32 *** /u；</p>
<p>例如：<br />
下列命令将禁用“文件系统对象”：regsvr32 scrrun.dll /u</p>
<p>八、 删除 IISADMPWD 虚拟目录</p>
<p>该目录允许您重新设置 Windows NT 和 Windows 2000 密码。这主要是为 Intranet 方案设计的，并且不作为 IIS 5 的一部分来安装，但是在 IIS 4 服务器升级到 IIS 5 时将不会被删除。如果您不使用 Intranet 或者您将服务器连接到网站上，则应当将其删除。</p>
<p>有关此功能的详细信息，请参考Microsoft Knowledge Base文章Q184619。</p>
<p>九、 删除不使用的脚本映射</p>
<p>当 IIS 接收到针对其中某一类型文件的请求时，该调用由 DLL 进行处理。如果您不会用到其中某些扩展名或功能，请进行删除，方法如下：网站|属性|主目录|配置，然后删除下列引用：</p>
<p>* 基于网站的密码重置 .htr<br />
* Internet 数据库连接器（所有 IIS 5 网站应当使用 ADO 或相似技术） .idc<br />
* 采用SSI技术的服务器端包含程序 .stm, .shtm 和 .shtml<br />
* Internet 打印 .printer<br />
* 索引服务器 .htw, .ida , .idq</p>
<p>注意： 关于“Internet 打印”可以通过组策略和 Internet 服务管理器来配置。如果组策略设置和 Internet 管理器设置有冲突，那么组策略设置优先。默认组策略既不启用也不禁用“Internet 打印”。请选择“计算机配置”|“管理模板”|“打印”|“基于 Web 的打印”来禁用它。</p>
<p>十、 禁用父路径</p>
<p>父路径允许您在调用诸如 MapPath 等功能时使用“..”。默认状态下，该选项是启用的，您应当禁用它：网站|属性|主目录|配置|选项|启用父路径；</p>
<p>十一、   在“Content-Location”中禁用 IP 地址</p>
<p>“Content-Location”首部会暴露通常隐藏在网络地址转换 (NAT) 防火墙或代理服务器后的内部 IP 地址。如下设置后可以使服务器返回URL而不是IP地址：</p>
<p>将UseHostName添加到Metabase中的W3SVC键上；</p>
<p>例如: Set IISSchemaObject = GetObject（“IIS://Axqd/Schema/w3svc”）&#8230;</p>
<p>更简单的方法是使用IIS5.0提供的默认情况下安装在InetpubAdminscripts下面的ADSUTIL程序<br />
（IIS 4.0在winntsystem32inetsrvadminsamples）：</p>
<p>Adsutil set w3svc/UseHostName True</p>
<p>然后必须重启Web服务器。</p>
<p>有关禁用该选项的详细信息，请参阅知识库文章Q218180。IIS6.0目前没有提供这个问题的解决方案；</p>
<p>最后，关于针对DOS攻击的压力测试可以采用Microsoft Web Application Stress Tool；</p>
<p>关于IIS安全方面的工具，特别推荐IISLockDown以及URLSCAN（可从IISLockDown中分离出来)；</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/10/18/check-list-for-iis5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows 2000安全清单</title>
		<link>http://blog.axqd.net/2004/10/18/check-list-for-win-2k/</link>
		<comments>http://blog.axqd.net/2004/10/18/check-list-for-win-2k/#comments</comments>
		<pubDate>Mon, 18 Oct 2004 04:56:53 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[microsoft]]></category>
		<category><![CDATA[netunion]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=351</guid>
		<description><![CDATA[1.物理安全 确保每次本机登录服务器后的SignOut过程；设置BIOS密码且修改引导次序禁止从软盘或光盘引导系统； 2.停掉Guest 账号 把guest账号停用掉，最好给guest 账号加一个极其复杂的密码； 3．限制不必要的用户数量 经常检查系统的账号，删除已经不再使用的账号，并注意检查相应账号的权限设置； 应注意检查各个账号的实际权限，而不只是系统用户账号界面或者cmd命令显示出来的权限，严防账号克隆； 4．创建2个管理员所使用的账号 创建一个一般权限账号用来检查日志等一些日常事物，另一个拥有Administrators 权限的账号只在需要的时候使用；届时可让管理员使用 “ RunAS ” 命令来执行一些需要特权才能进行的一些工作，以方便管理； 5．把系统administrator账号改名 把Administrator账号改名，不要使用Admin之类的名字，尽量把它伪装成普通用户，例如：guestone ； 6．创建一个陷阱账号 创建一个名为” Administrator ”的本地账号，把它的权限设置成最低，并且加上一个极其复杂的密码，更进一步的可以在其的login scripts上面做点手脚，达到HoneyPot的效果； 7．把共享文件的权限从“ everyone ”组改成“ 授权用户 ” 任何时候都不要把共享文件的存取权限设置成“ everyone ”组，包括打印共享； 如果没有必要，请关闭默认共享(见附录)； 机器重新启动后，这些共享又会重新开启的，如果想要自动关闭，请使用WSH脚本或者BAT脚本； 也可以直接更改注册表，如下： Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserverparameters] "AutoShareServer"=dword:00000000 "AutoSharewks"=dword:00000000 REM 禁止建立空连接(限制对公用的本地安全权限 (LSA) 信息的访问) [HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLSA] "RestrictAnonymous"=dword:1 8．使用安全密码 包括对密码长度和密码复杂度的相应要求； 9．设置屏幕保护密码 不要使用OpenGL和一些复杂的屏幕保护程序，浪费系统资源，黑屏就可以了； 10． 使用NTFS格式分区 [...]]]></description>
			<content:encoded><![CDATA[<p>1.物理安全<br />
确保每次本机登录服务器后的SignOut过程；设置BIOS密码且修改引导次序禁止从软盘或光盘引导系统；</p>
<p>2.停掉Guest 账号<br />
把guest账号停用掉，最好给guest 账号加一个极其复杂的密码；</p>
<p>3．限制不必要的用户数量<br />
经常检查系统的账号，删除已经不再使用的账号，并注意检查相应账号的权限设置；<br />
应注意检查各个账号的实际权限，而不只是系统用户账号界面或者cmd命令显示出来的权限，严防账号克隆；</p>
<p>4．创建2个管理员所使用的账号<br />
创建一个一般权限账号用来检查日志等一些日常事物，另一个拥有Administrators 权限的账号只在需要的时候使用；届时可让管理员使用 “ RunAS ” 命令来执行一些需要特权才能进行的一些工作，以方便管理；</p>
<p>5．把系统administrator账号改名<br />
把Administrator账号改名，不要使用Admin之类的名字，尽量把它伪装成普通用户，例如：guestone ；</p>
<p>6．创建一个陷阱账号<br />
创建一个名为” Administrator ”的本地账号，把它的权限设置成最低，并且加上一个极其复杂的密码，更进一步的可以在其的login scripts上面做点手脚，达到HoneyPot的效果；</p>
<p>7．把共享文件的权限从“ everyone ”组改成“ 授权用户 ”<br />
任何时候都不要把共享文件的存取权限设置成“ everyone ”组，包括打印共享；<br />
如果没有必要，请关闭默认共享(见附录)；<br />
机器重新启动后，这些共享又会重新开启的，如果想要自动关闭，请使用WSH脚本或者BAT脚本；<br />
也可以直接更改注册表，如下：<br />
<code>Windows Registry Editor Version 5.00<br />
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserverparameters]<br />
"AutoShareServer"=dword:00000000<br />
"AutoSharewks"=dword:00000000</code><br />
REM 禁止建立空连接(限制对公用的本地安全权限 (LSA) 信息的访问)<br />
<code>[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLSA]<br />
"RestrictAnonymous"=dword:1</code></p>
<p>8．使用安全密码<br />
包括对密码长度和密码复杂度的相应要求；</p>
<p>9．设置屏幕保护密码<br />
不要使用OpenGL和一些复杂的屏幕保护程序，浪费系统资源，黑屏就可以了；</p>
<p>10． 使用NTFS格式分区<br />
把服务器的所有分区都改成NTFS格式；<br />
首先，性能上有较大提升；（簇小于4K条件不同：FAT &lt;256M FAT32 &lt;32G NTFS NIL）<br />
其次，2000以前身份验证协议只有NTLM（NT Lan Manager），NTFS为2000用户提供了更多样的选择&#8212;Kerberos v5协议以及附加身份验证工具Crypto API、Secure Sockets Layer（SSL）、公共密钥加密；</p>
<p>NTFS基本安全性数据结构：<br />
（1）SID(安全标识符)：唯一的标识用户和组；使用一次，即使删除也不会分发给其他用户；<br />
（2）ACE(访问控制项目)：定义了SID怎样才能与安全对象交互，允许或拒绝；可帮忙传递其他参数；<br />
（3）ACL（访问控制列表）：数组，包含0-多个ACE；<br />
（4）DACL（自选访问控制列表）：权限；<br />
（5）SACL（系统访问控制列表）：审核；<br />
（6）SECURITY_DESCRIPTOR（安全描述）：如与对象相关的DACL，SACL等等；</p>
<p>多条ACE冲突原则：<br />
（1）组之间的许可可累加；<br />
（2）文件许可优先于目录许可；<br />
（3）拒绝优先于许可；</p>
<p>账户权力：详见本地安全设置-&gt;用户权利指派</p>
<p>由于NTFS与FAT相比，支持更多的数据流，所以请注意时常检查数据流信息，防止木马伪装；（可采用stream.exe或者lads.exe工具）</p>
<p>11．运行防毒软件<br />
经常升级病毒库；<br />
微软关于防治病毒的建议请参见:</p>
<p>http://www.microsoft.com/windowsxp/downloads/updates/sp2/antivirus/default.mspx</p>
<p>12．保障备份盘的安全<br />
备份完资料后，把备份盘放在安全的地方；不要把资料备份在同一台服务器上，至少不要备份在同一个驱动器下；<br />
Windows的密码文件（SAM）也有备份，不要忽略备份文件的安全性；</p>
<p>13．利用win2000的安全配置工具来配置策略<br />
请参见控制台（MMC）和组策略（GPEDIT.MSC）的帮助文档</p>
<p>14．关闭不必要的服务<br />
留意服务器上面开启的所有服务，定期检查他们以及他们的默认启动方式；下面是C2级别安装的默认服务，仅供参考：</p>
<p>* Computer Browser service TCP/IP NetBIOS Helper<br />
* Microsoft DNS server Spooler<br />
* NTLM SSP Server<br />
* RPC Locator WINS<br />
* RPC service Workstation<br />
* Netlogon Event log</p>
<p>对于仅运行IIS主机而言，情况如下：<br />
必要服务：<br />
* DNS Client<br />
* Event Log<br />
* License Logging Services<br />
* Windows NTLM Security Support Provider<br />
* Remote Procedure Call(RPC) Services<br />
* Windows NT Server or Windows NT Workstation<br />
* IIS Admin Service<br />
* MSDTC<br />
* World Wide Web Publishing Service<br />
* Protected Storage<br />
* COM+ Event System<br />
* Network Connections<br />
* Windows Management Instrumentation Driver Extensions<br />
* Windows Management Instrumentation</p>
<p>一般需禁用服务：<br />
* Remote Registry Service<br />
* Server<br />
* Schedule<br />
* FTP Publishing Service<br />
* Telnet<br />
* Terminal Service<br />
* Telephony<br />
* Alerter<br />
* ClipBook Server<br />
* Computer Browser<br />
* DHCP Client<br />
* Directory Replicator<br />
* License Logging Service<br />
* Messenger<br />
* Netlogon<br />
* Network DDE<br />
* Network DDE DSDM<br />
* Network Monitor<br />
* Remote Access Server<br />
* Remote Procedure Call(RPC) locator<br />
* Spooler<br />
* TCP/IP Netbios Helper<br />
* Telephone Service</p>
<p>还有一些服务，如：SNMP Service，UPS等，应根据具体情况，如果不能确定可以选择手动，这样系统在需要的时候会自己启动这些服务；</p>
<p>此外，应该时常注意进程列表，特别注意名称与正常进程相近或者有迷惑性名称的进程；</p>
<p>15．关闭不必要的端口<br />
用端口扫描器扫描系统所开放的端口，确定开放了哪些端口；%system%driversetcservices 文件中有知名端口和服务的对照表可供参考；</p>
<p>关闭某端口具体方法为：<br />
网上邻居-&gt;属性-&gt;本地连接-&gt;属性-&gt;internet 协议(tcp/ip)-&gt;属性-&gt;高级-&gt;选项-&gt;tcp/ip筛选-&gt;属性 打开tcp/ip筛选，添加需要的tcp,udp协议即可；</p>
<p>可以利用fport等第三方工具列出端口与进程的对应表，然后直接杀掉进程；对于不能关掉的进程则采用防火墙屏蔽相应端口；</p>
<p>16．打开审核策略<br />
策略 设置<br />
审核系统登陆事件 成功，失败<br />
审核账号管理 成功，失败<br />
审核登陆事件 成功，失败<br />
审核对象访问 成功<br />
审核策略更改 成功，失败<br />
审核特权使用 成功，失败<br />
审核系统事件 成功，失败</p>
<p>17．开启密码密码策略<br />
策略 设置<br />
密码复杂性要求 启用<br />
密码长度最小值 6位<br />
强制密码历史 5 次<br />
强制密码历史 42 天</p>
<p>18．开启账号策略<br />
策略 设置<br />
复位账号锁定计数器 20分钟<br />
账号锁定时间 20分钟<br />
账号锁定阈值 3次</p>
<p>对于IIS主机，请不要开启此策略，否则可能锁定IUSR_HOSTNAME帐号，导致IIS不能访问，目前微软还没有提供解决方案；</p>
<p>注：<br />
关于策略的统一设置，可以使用统一的安全模板。<br />
模板配置下载地址：http://download.microsoft.com/download/win2000srv/SCM/1.0/NT5/EN-US/hisecweb.exe</p>
<p>值得注意的是对于Windows终端服务的审核未包含连接的IP地址的记录，故可采用登录脚本进行记录（例如：netstat –n –p tcp | find “:3389”；记住登录脚本的最后要start Explorer，因为默认的登录脚本就是Explorer）</p>
<p>19．设定安全记录的访问权限<br />
应该设置成只有Administrator和必要的系统账号才有权访问；</p>
<p>20．把敏感文件存放在另外的文件服务器中<br />
考虑是否有必要把一些重要的用户数据(文件，数据表，项目文件等)存放在另外一个安全的服务器中，并且经常备份它们；</p>
<p>21.不让系统显示上次登陆的用户名<br />
具体做法是：<br />
<code>HKLMSoftwareMicrosoftWindows NTCurrentVersionWinlogonDontDisplayLastUserName</code><br />
把 REG_SZ 的键值改成 1；<br />
或者使用本地安全设置-&gt;安全选项；</p>
<p>22．到微软网站下载最新的补丁程序<br />
经常访问微软和一些安全站点，下载最新的service pack和漏洞补丁；<br />
另注：除非确保有安全的SUS Server否则请不要使用Windows Update进行更新，而采用手工方式；<br />
具体网址：http://support.microsoft.com/support/contact/default.asp<br />
最简单的方式是订阅Microsoft 安全通知服务：</p>
<p>http://www.microsoft.com/technet/security/bulletin/notify.mspx</p>
<p>23．关闭 DirectDraw<br />
此为C2级安全标准对视频卡和内存的要求；<br />
具体做法：<br />
<code>HKLMSYSTEMCurrentControlSetControlGraphicsDriversDCI</code><br />
将Timeout(REG_DWORD)设置为 0 即可；</p>
<p>24．禁止dump file的产生<br />
打开 控制面板&gt;系统属性&gt;高级&gt;启动和故障恢复 把 写入调试信息 改成无；要用的时候，可以再重新打开它；<br />
另外，还需关闭华生医生（DrWaston&#8212;drwtsn32）产生的日志文件(故障转储文件)；</p>
<p>25．使用文件加密系统EFS<br />
注意要给文件夹也使用EFS, 而不仅仅是针对单个文件； 有关EFS的具体信息可以查看</p>
<p>http://www.microsoft.com/windows2000/techinfo/howitworks/security/encrypt.asp</p>
<p>请一定保管好证书，若遗失，恢复过程会极其繁琐（安装证书颁发机构然后创建附加数据恢复代理），而且还不一定能够修复（例如：WIN2K PRO）</p>
<p>26．关注temp、%windir%repair文件夹<br />
注意随时关注temp文件夹，在进行危险操作后记得删除temp文件夹相应内容；<br />
%windir%repair下面的备份文件存在很大危险；</p>
<p>27．锁住注册表<br />
详细信息请参考：</p>
<p>http://support.microsoft.com/support/kb/articles/Q153/1/83.asp</p>
<p>28．关机时清除掉页面文件<br />
编辑注册表<br />
<code>HKLMSYSTEMCurrentControlSetControlSession ManagerMemory Management</code><br />
把ClearPageFileAtShutdown的键值设置成1；</p>
<p>29．考虑使用IPSec<br />
有关IPSec的详细信息可以参考：</p>
<p>http://www.microsoft.com/china/technet/security/ipsecloc.asp</p>
<p>IPSec简化版为TCP/IP筛；</p>
<p>30、迁移以下程序<br />
迁移下列程序到一个单独的目录，限定该目录ACL为Admin（完全控制）<br />
<code>xcopy.exe wscript.exe cscript.exe net.exe ipconfig.exe ftp.exe arp.exe edlin.exe rcp.exe ping.exe route.exe at.exe posix.exe rsh.exe cmd.exe qbasic.exe syskey.exe secfixup.exe nslookup.exe runonce.exe tracert.exe nbtstat.exe regedt32.exe regedit.exe finger.exe telnet.exe netstat.exe rexec.exe atsvc.exe cacls.exe edit.com debug.exe command.com cmd.exe</code></p>
<p>31、关闭子系统<br />
Windows2000内核支持五个子系统：OS/2、POSIX、Win32、MS-DOS VDM、Win16 VDM，大多数用户不需要OS/2和POSIX子系统，删除如下子键：<br />
<code>[HKEY_LOCAL_MACHINESoftwareMicrosoftOS/2 Subsystem for NT]<br />
[HKEY_LOCAL_MACHINESystemCurrentControlSetControlSession ManagerEnvironmentOs2LibPath]<br />
[HKEY_LOCAL_MACHINESystemCurrentControlSetContrlSession ManagerSubSystemsOptional]<br />
[HKEY_LOCAL_MACHINESystemCurrentControlSetContrlSession ManagerSubSystemsPosix]<br />
[HKEY_LOCAL_MACHINESystemCurrentControlSetContrlSession ManagerSubSystemsOs2]</code><br />
再删除目录%SystemRoot%System32OS2</p>
<p>32、经常察看日志<br />
* 安全日志文件 %systemroot%system32configSecEvent.EVT<br />
* 系统日志文件 %systemroot%system32configSysEvent.EVT<br />
* 应用程序日志文件 %systemroot%system32configAppEvent.EVT</p>
<p>定位、设置日志文件：<br />
<code>[HKEY_LOCAL_MACHINESystemCurrentControlSetServicesEventlog]</code><br />
注意修改maxsize子键，如果超出大小，会报错并且不会再记录，默认大小512K。</p>
<p>下面给出脚本设置日志最大25MB，并且允许日志自行覆盖15天前的日志：<br />
<code>strComputer = “.”<br />
Set objWMIService = GetObject(“winmgmts:” &amp; “{impersonationLevel=impersonate,(Security)}!” &amp; strComputer &amp; “rootcimv2”) ‘获得VMI对象<br />
Set colLogFiles = objWMIService.ExecQuery(“Select * from Win32_NTEventLogFile”)   ‘获得LogFiles<br />
‘-------------------------<br />
For each objLogfile in colLogFiles<br />
strLogFileName = objLogfile.Name<br />
Set wmiSWbemObject = GetObject(“winmgmts:{impersonationLevel=Impersonate}!.rootcimv2:” &amp; “Win32_NTEventlogFile.Name=’” &amp; strLogFileName &amp; “’”)<br />
wmiSWbemObject.MaxFileSize = 2500000000<br />
wmiSWbemObject.OverwriteOutdated = 15  ‘未找到<br />
wmiSWbemObject.Put<br />
Next<br />
‘----------------------------</code></p>
<p>最简单的察看日志的方式是使用事件察看器；</p>
<p>最后有三点需要注意：<br />
1、安全方面“管理永远大于技术，态度永远大于能力”；<br />
2、安全与易用性永远是一对矛盾，需要在其间权衡利弊；<br />
3、安全界有一个著名的理论，即所谓的“木桶原理”，请杜绝麻痹大意，不拘小节。</p>
<p>对于安全配置的检测，推举使用：<br />
Microsoft 基准安全分析器 (MBSA)<br />
并将 MBSA 添加到每周维护计划中，并按照计划中的任何安全建议操作。</p>
<p><strong>附录：</strong><br />
默认共享目录路径和功能：</p>
<p>[C$ D$ E$]<br />
每个分区的根目录；Win2000 Pro版中，只有Administrator和Backup Operators组成员才可连接，Win2000 Server版本Server Operatros组也可以连接到这些共享目录；</p>
<p>[ADMIN$ %SYSTEMROOT%]<br />
远程管理用的共享目录；它的路径永远都指向Win2000的安装路径，比如 c:winnt；</p>
<p>[FAX$]<br />
在Win2000 Server中，FAX$在fax客户端发传真的时候会到；</p>
<p>[IPC$ 空连接]<br />
IPC$共享提供了登录到系统的能力；</p>
<p>[NetLogon]<br />
这个共享在Windows 2000 服务器的Net Login 服务在处理登陆域请求时用到；</p>
<p>[PRINT$ %SYSTEMROOT%SYSTEM32SPOOLDRIVERS]<br />
用户远程管理打印机；</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2004/10/18/check-list-for-win-2k/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

