<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[水土不服's blog - 程序设计]]></title>
<link>http://www.ruery.net/</link>
<description><![CDATA[3C小子]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog3 v2.8]]></copyright>
<webMaster><![CDATA[admin@ruery.com(ruery)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>水土不服&#39;s blog</title>
	<url>http://www.ruery.net/images/logos.gif</url>
	<link>http://www.ruery.net/</link>
	<description>水土不服&#39;s blog</description>
</image>

			<item>
			<link>http://www.ruery.net/article/Program/DelphiKB.htm</link>
			<title><![CDATA[Delphi 键盘码表]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Wed,04 Feb 2009 19:26:35 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=2678</guid>
		<description><![CDATA[VK_LBUTTON = 1;<br/>VK_RBUTTON = 2;<br/>VK_CANCEL = 3;<br/>VK_MBUTTON = 4; { NOT contiguous with L &amp; RBUTTON }<br/>VK_BACK = 8;<br/>VK_TAB = 9;<br/>VK_CLEAR = 12;<br/>VK_RETURN = 13;<br/>VK_SHIFT = $10;<br/>VK_CONTROL = 17;<br/>VK_MENU = 18;<br/>VK_PAUSE = 19;<br/>VK_CAPITAL = 20;<br/>VK_KANA = 21;<br/>VK_HANGUL = 21;<br/>VK_JUNJA = 23;<br/>VK_FINAL = 24;<br/>VK_HANJA = 25;<br/>VK_KANJI = 25;<br/>VK_CONVERT = 28;<br/>VK_NONCONVERT = 29;<br/>VK_ACCEPT = 30;<br/>VK_MODECHANGE = 31;<br/>VK_ESCAPE = 27;<br/>VK_SPACE = $20;<br/>VK_PRIOR = 33;<br/>VK_NEXT = 34;<br/>VK_END = 35;<br/>VK_HOME = 36;<br/>VK_LEFT = 37;<br/>VK_UP = 38;<br/>VK_RIGHT = 39;<br/>VK_DOWN = 40;<br/>VK_Sel&#101;ct = 41;<br/>VK_PRINT = 42;<br/>VK_EXECUTE = 43;<br/>VK_SNAPSHOT = 44;<br/>VK_Ins&#101;rt = 45;<br/>VK_Del&#101;te = 46;<br/>VK_HELP = 47;<br/>{ VK_0 thru VK_9 are the same as ASCII &#39;&#39;0&#39;&#39; thru &#39;&#39;9&#39;&#39; ($30 - $39) }<br/>{ VK_A thru VK_Z are the same as ASCII &#39;&#39;A&#39;&#39; thru &#39;&#39;Z&#39;&#39; ($41 - $5A) }<br/>VK_LWIN = 91;<br/>VK_RWIN = 92;<br/>VK_APPS = 93;<br/>VK_NUMPAD0 = 96;<br/>VK_NUMPAD1 = 97;<br/>VK_NUMPAD2 = 98;<br/>VK_NUMPAD3 = 99;<br/>VK_NUMPAD4 = 100;<br/>VK_NUMPAD5 = 101;<br/>VK_NUMPAD6 = 102;<br/>VK_NUMPAD7 = 103;<br/>VK_NUMPAD8 = 104; VK_NUMPAD9 = 105;<br/>VK_MULTIPLY = 106;<br/>VK_ADD = 107;<br/>VK_SEPARATOR = 108;<br/>VK_SUBTRACT = 109;<br/>VK_DECIMAL = 110;<br/>VK_DIVIDE = 111;<br/>VK_F1 = 112;<br/>VK_F2 = 113;<br/>VK_F3 = 114;<br/>VK_F4 = 115;<br/>VK_F5 = 116;<br/>VK_F6 = 117;<br/>VK_F7 = 118;<br/>VK_F8 = 119;<br/>VK_F9 = 120;<br/>VK_F10 = 121;<br/>VK_F11 = 122;<br/>VK_F12 = 123;<br/>VK_F13 = 124;<br/>VK_F14 = 125;<br/>VK_F15 = 126;<br/>VK_F16 = 127;<br/>VK_F17 = 128;<br/>VK_F18 = 129;<br/>VK_F19 = 130;<br/>VK_F20 = 131;<br/>VK_F21 = 132;<br/>VK_F22 = 133;<br/>VK_F23 = 134;<br/>VK_F24 = 135;<br/>VK_NUMLOCK = 144;<br/>VK_SCROLL = 145;<br/>{ VK_L &amp; VK_R - left and right Alt, Ctrl and Shift virtual keys.<br/>Used only as parameters to GetAsyncKeyState() and GetKeyState().<br/>No other API&nbsp;&nbsp; o&#114; message will distinguish left and right keys in this way. }<br/>VK_LSHIFT = 160;<br/>VK_RSHIFT = 161;<br/>VK_LCONTROL = 162;<br/>VK_RCONTROL = 163;<br/>VK_LMENU = 164;<br/>VK_RMENU = 165;<br/>VK_PROCESSKEY = 229;<br/>VK_ATTN = 246;<br/>VK_CRSEL = 247;<br/>VK_EXSEL = 248;<br/>VK_EREOF = 249;<br/>VK_PLAY = 250;<br/>VK_ZOOM = 251;<br/>VK_NONAME = 252;<br/>VK_PA1 = 253;<br/>VK_OEM_CLEAR = 254;　]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/2009.htm</link>
			<title><![CDATA[利用GetPrivateProfileString读取配置文件(.ini)]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Sun,06 Apr 2008 16:05:12 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=2009</guid>
		<description><![CDATA[配置文件中经常用到ini文件，在VC中其函数分别为：<br/><br/>写入.ini文件：bool WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTR lpFileName);<br/><br/>读取.ini文件：DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName,LPCTSTR lpDefaut,LPSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName);<br/><br/>读取整形值：UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,INT nDefault,LPCTSTR lpFileName);<br/><br/>其中个参数的意思：<br/><br/>LPCTSTR lpAppName ------- INI文件中的一个字段名<br/><br/>LPCTSTR lpKeyName -------- lpAppName 下的一个键名，也就是里面具体的变量名<br/><br/>LPCTSTR lpString ---------是键值，也就是变量的值， 必须为LPCTSTR或CString类型<br/><br/>LPCTSTR lpFileName --------完整的INI文件路径名<br/><br/>LPCTSTR lpDefaut ----------如果没有其前两个参数值，则将此值赋给变量<br/><br/>LPSTR lpReturnedString --------接收INI文件中的值的CString对象，即接收缓冲区<br/><br/>DWORD nSize ------接收缓冲区的大小<br/><br/>例子：<br/><br/>CString StrName,Strtemp;<br/><br/>int nAge;<br/><br/>StrName = &#34;jacky&#34;;<br/><br/>nAge = 13;<br/><br/>WritePrivateProfileString(&#34;Student&#34;,&#34;Name&#34;,StrName,&#34;c:\\setting.ini&#34;);<br/><br/>结果：（INI文件中显示如下：）<br/><br/>[Student]<br/><br/>Name=jacky<br/><br/>读取：<br/><br/>CString SName;<br/><br/>GetPrivateProfileString(&#34;Student&#34;,&#34;Name&#34;,&#34;DefaultName&#34;,SName.GetBuffer(MAX_LENGTH),MAX_LENGTH,&#34;c:\\setting.ini&#34;);<br/><br/>结果：SName = &#34;jacky&#34;；这里需要注意点就是用完GetBuffer函数后一定要释放(用SName.ReleaseBuffer()函数)，不然后面再用到SName的其他子函数就会失灵。<br/><br/>读整数比较简单，如下<br/><br/>int Result = GetPrivateProfileInt(&#34;Student&#34;,&#34;nAge&#34;,0,&#34;c:\\setting.ini&#34;)返回值即为所读取的结果！<br/><br/>在GetPrivateProfileString最后一个参数是配置文件路径的参数，此路径只能是绝对路径，不能是相对路径，但现在我需要是我的exe文件能和我的配置文件在一起。因此我使用了GetCurrentDirectory函数。<br/><br/>原代码如下：<br/><br/>CString server_ip;<br/>CString des=&#34;&#34;;<br/>::GetCurrentDirectory(MAX_PATHLENGTH,des.GetBuffer(MAX_PATHLENGTH));<br/>des.ReleaseBuffer();<br/>des+=&#34;\\config.ini&#34;;<br/>GetPrivateProfileString(&#34;PhoneDemo&#34;,&#34;Server_IP&#34;,&#34;&#34;,server_ip.GetBufferSetLength(15),15,des);<br/>server_ip.ReleaseBuffer();<br/><br/>注意：在这里使用CString变量时，在使用完GetBuffer后，紧接着一定要使用ReleaseBuffer()函数，才可以进行其他的诸如字符串+操作 ]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/2000.htm</link>
			<title><![CDATA[DELPHI中完成端口(IOCP)的简单分析]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Wed,19 Mar 2008 12:48:17 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=2000</guid>
		<description><![CDATA[我发现在网上用VC来实现完成端口（IOCP）的代码很多，但是使用DELPHI来实现的就比较少了。对IOCP讲的清楚的就更少了。在这里我把自己编写DELPHI下的IOCP写出来，希望对刚学完成端口的朋友有个帮助。<br/><br/>首先我们来了解一些在使用IOCP的时候需要使用的一些结构！<br/><br/>（1）：单IO数据结构<br/><br/>&nbsp;&nbsp; LPVOID = Pointer;<br/>&nbsp;&nbsp; LPPER_IO_OPERATION_DATA = ^ PER_IO_OPERATION_DATA ;<br/>&nbsp;&nbsp; PER_IO_OPERATION_DATA = packed record<br/>&nbsp;&nbsp;&nbsp;&nbsp; Overlapped: OVERLAPPED;<br/>&nbsp;&nbsp;&nbsp;&nbsp; DataBuf: TWSABUF;<br/>&nbsp;&nbsp;&nbsp;&nbsp; Buffer: array [0..1024] of CHAR;<br/>&nbsp;&nbsp;&nbsp;&nbsp; BytesSEND: DWORD;<br/>&nbsp;&nbsp;&nbsp;&nbsp; BytesRECV: DWORD;<br/>&nbsp;&nbsp; end;<br/><br/>上面的结构中Overlapped: OVERLAPPED;和DataBuf: TWSABUF;是固定的结构类型。Buffer: array [0..1024] of CHAR;是用来保存接受数据的缓存。BytesSEND: DWORD;用来标志发送数据的长度。BytesRECV: DWORD;用来标志接受数据的长度。因为完成端口的工作者线程可以接受到来自客户端的数据，同时还可以接受到自己发送给客户端的数据，所以我们使用BytesSEND，BytesRECV变量来说是用来区分这次的数据是来自客户端的数据还是自己发送出去的数据。详细的使用方法，我会在下面详细说明。<br/><br/>（2）：“单句柄数据结构”<br/><br/>&nbsp;&nbsp; LPPER_HANDLE_DATA = ^ PER_HANDLE_DATA;<br/>&nbsp;&nbsp; PER_HANDLE_DATA = packed record<br/>&nbsp;&nbsp;&nbsp;&nbsp; Socket: TSocket;<br/>&nbsp;&nbsp; end;<br/><br/>下来我从编写一个完成端口的为例说明。<br/><br/>if WSAStartUp($202, wsData) &lt;&gt; 0 then<br/>begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;WSACleanup();<br/>end;<br/><br/>加载SOCKET。我使用的是2.2版为了后面方便加入心跳。<br/><br/>CompletionPort:=Cr&#101;ateIOCompletionPort(INVALID_HANDLE_VALUE,0,0,0);<br/><br/>创建一个完成端口。<br/>GetSystemInfo(LocalSI);<br/>for I:=0 to LocalSI.dwNumberOfProcessors * 2 -1 do<br/>begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;hThread := Cr&#101;ateThread(nil, 0, @ServerWorkerThread, Pointer(CompletionPort),0, ThreadID);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (hThread = 0) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exit;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hThread);<br/>end;<br/><br/>根据CPU的数量创建CPU*2数量的工作者线程。<br/>Listensc:=WSASocket(AF_INET,SOCK_STREAM,0,Nil,0,WSA_FLAG_OVERLAPPED);<br/>if Listensc=SOCKET_ERROR then<br/>begin<br/>&nbsp;&nbsp;&nbsp;&nbsp; closesocket(Listensc);<br/>&nbsp;&nbsp;&nbsp;&nbsp; WSACleanup();<br/>end;<br/>sto.sin_family:=AF_INET;<br/>sto.sin_port:=htons(5500);<br/>sto.sin_addr.s_addr:=htonl(INADDR_ANY);<br/>if bind(Listensc,sto,sizeof(sto))=SOCKET_ERROR then<br/>begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;closesocket(Listensc);<br/>end;<br/>listen(Listensc,20);<br/><br/>创建一个套接字，将此套接字和一个端口绑定并监听此端口。<br/><br/>while (TRUE) do<br/>begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;Acceptsc:= WSAAccept(Listensc, nil, nil, nil, 0);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;当客户端有连接请求的时候，WSAAccept函数会新创建一个套接字Acceptsc。这个套接字就是和客户端通信的时候使用的套接字。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;if (Acceptsc= SOCKET_ERROR) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closesocket(Listensc);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;判断Acceptsc套接字创建是否成功，如果不成功则退出。<br/>&nbsp;&nbsp;&nbsp;&nbsp;PerHandleData := LPPER_HANDLE_DATA (GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA)));<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (PerHandleData = nil) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;PerHandleData.Socket := Acceptsc;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;创建一个“单句柄数据结构”将Acceptsc套接字绑定。<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (Cr&#101;ateIoCompletionPort(Acceptsc, CompletionPort, DWORD(PerHandleData), 0) = 0) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;将套接字、完成端口和“单句柄数据结构”三者绑定在一起。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;PerIoData := LPPER_IO_OPERATION_DATA(GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA)));<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (PerIoData = nil) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;ZeroMemory(@PerIoData.Overlapped, sizeof(OVERLAPPED));<br/>&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.BytesSEND := 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.BytesRECV := 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.DataBuf.len := 1024;<br/>&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.DataBuf.buf := @PerIoData.Buffer;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Flags := 0;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;创建一个“单IO数据结构”其中将PerIoData.BytesSEND 和PerIoData.BytesRECV 均设置成0。说明此“单IO数据结构”是用来接受的。<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (WSARecv(Acceptsc, @(PerIoData.DataBuf), 1, @RecvBytes, @Flags,@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (WSAGetLastError() &lt;&gt; ERROR_IO_PENDING) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br/>&nbsp;&nbsp;&nbsp;&nbsp;end;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;用此“单IO数据结构”来接受Acceptsc套接字的数据。<br/><br/>end;<br/><br/>创建IOCP的工作已经完成，下一次我将写IOCP的工作者线程的处理方法，谢谢！<br/><br/><br/><br/><br/>今天我写一下关于DELPHI编写完成端口（IOCP）的工作者线程中的东西。希望各位能提出批评意见。<br/>上次我写了关于常见IOCP的代码，对于IOCP来说，接受到客户端发送过来和自己发送出去的数据都是从工作者线程中得到。代码和解释如下：<br/>function ServerWorkerThread(CompletionPortID:Pointer):Integer;stdcall;<br/>begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;CompletionPort:=THANDLE(CompletionPortID);<br/>&nbsp;&nbsp;&nbsp;&nbsp;//得到创建线程是传递过来的IOCP<br/>&nbsp;&nbsp;&nbsp;&nbsp;while(TRUE) do<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //工作者线程会停止到GetQueuedCompletionStatus函数处，直到接受到数据为止<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当客户端连接断开或者客户端调用closesocket函数的时候,函数GetQueuedCompletionStatus会返回错误。如果我们加入心跳后，在这里就可以来判断套接字是否依然在连接。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if PerHandleData&lt;&gt;nil then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closesocket(PerHandleData.Socket);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GlobalFree(DWORD(PerHandleData));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if PerIoData&lt;&gt;nil then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GlobalFree(DWORD(PerIoData));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (BytesTransferred = 0) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//当客户端调用shutdown函数来从容断开的时候，我们可以在这里进行处理。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if PerHandleData&lt;&gt;nil then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TempSc:=PerHandleData.Socket;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shutdown(PerHandleData.Socket,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closesocket(PerHandleData.Socket);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GlobalFree(DWORD(PerHandleData));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if PerIoData&lt;&gt;nil then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GlobalFree(DWORD(PerIoData));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //在上一篇中我们说到IOCP可以接受来自客户端的数据和自己发送出去的数据，两种数据的区别在于我们定义的结构成员BytesRECV和BytesSEND的值。所以下面我们来判断数据的来自方向。因为我们发送出去数据的时候我们设置了结构成员BytesSEND。所以如果BytesRECV=0同时BytesSEND=0那么此数据就是我们接受到的客户端数据。（这种区分方法不是唯一的，个人可以有自己的定义方法。只要可以区分开数据来源就可以。）<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (PerIoData.BytesRECV = 0) and (PerIoData.BytesSEND = 0) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.BytesRECV := BytesTransferred;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.BytesSEND := 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.BytesSEND := BytesTransferred;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PerIoData.BytesRECV := 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当是接受来自客户端的数据是，我们进行数据的处理。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (PerIoData.BytesRECV &gt; PerIoData.BytesSEND) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PerIoData.DataBuf.buf := PerIoData.Buffer + PerIoData.BytesSEND;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PerIoData.DataBuf.len := PerIoData.BytesRECV - PerIoData.BytesSEND;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这时变量PerIoData.Buffer就是接受到的客户端数据。数据的长度是PerIoData.DataBuf.len 你可以对数据进行相关的处理了。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //.......<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当我们将数据处理完毕以后，应该将此套接字设置为结束状态，同时初始化和它绑定在一起的数据结构。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PerIoData.BytesRECV := 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Flags := 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PerIoData.DataBuf.len := DATA_BUFSIZE;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ZeroMemory(@PerIoData.Buffer,sizeof(@PerIoData.Buffer));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PerIoData.DataBuf.buf := @PerIoData.Buffer;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (WSARecv(PerHandleData.Socket, @(PerIoData.DataBuf), 1, @RecvBytes, @Flags,@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (WSAGetLastError() &lt;&gt; ERROR_IO_PENDING) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if PerHandleData&lt;&gt;nil then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TempSc:=PerHandleData.Socket;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closesocket(PerHandleData.Socket);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GlobalFree(DWORD(PerHandleData));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if PerIoData&lt;&gt;nil then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GlobalFree(DWORD(PerIoData));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当我们判断出来接受的数据是我们发送出去的数据的时候，在这里我们清空我们申请的内存空间<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GlobalFree(DWORD(PerIoData));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end;<br/><br/>end;<br/>到此，工作者线程已经处理完成。接受数据已经没有问题了。下一篇中我将会写出，如何时候IOCP来发送数据代码。今天的代码中应该对PerIoData.BytesRECV &gt; PerIoData.BytesSEND单另解说一下。其实如果按照上面的例子去编写工作者线程，会觉得编写出来的代码会很不稳定，接受到的数据总是有错位的现象。原因是TCP协议中有数据分片的概念，这个以后我会将我处理这个的代码分享给大家。 ]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/1947.htm</link>
			<title><![CDATA[vbs搜索代理]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Mon,01 Oct 2007 03:43:03 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=1947</guid>
		<description><![CDATA[&#39;1、输入url目标网页地址，返回值getHTTPPage是目标网页的html代码<br/>function getHTTPPage(url)<br/>dim Http<br/>set Http=Cr&#101;ateObject(&#34;MSXML2.XMLHTTP&#34;)<br/>Http.open &#34;GET&#34;,url,false<br/>Http.send()<br/>if Http.readystate&lt;&gt;4 then <br/>exit function<br/>end if<br/>getHTTPPage=bytesToBSTR(Http.responseBody,&#34;GB2312&#34;)<br/>set http=nothing<br/>if err.number&lt;&gt;0 then err.Clear <br/>end function<br/><br/>&#39;2、转换乱玛，直接用xmlhttp调用有中文字符的网页得到的将是乱玛，可以通过adodb.stream组件进行转换<br/>Function BytesToBstr(body,Cset)<br/>dim objstream<br/>set objstream =Cr&#101;ateObject(&#34;adodb.stream&#34;)<br/>objstream.Type = 1<br/>objstream.Mode = 3<br/>objstream.Open<br/>objstream.Write body<br/>objstream.Position = 0<br/>objstream.Type = 2<br/>objstream.Charset = Cset<br/>BytesToBstr = objstream.ReadText <br/>objstream.Close<br/>set objstream = nothing<br/>End Function<br/><br/>&#39;下面试着调用<a href="http://www.proxycn.com/html_proxy/30fastproxy-1.html" target="_blank" rel="external">http://www.proxycn.com/html_proxy/30fastproxy-1.html</a>的html内容<br/>Dim Url,Html,Temp<br/>Url=&#34;<a href="http://www.proxycn.com/html_proxy/30fastproxy-1.html" target="_blank" rel="external">http://www.proxycn.com/html_proxy/30fastproxy-1.html</a>&#34;<br/>Html = getHTTPPage(Url)<br/>Call getinfo(html)<br/><br/>Sub Getinfo(S)<br/>Dim pl(),m,St<br/>St=&#34;&lt;/TD&gt;&lt;TD class=&#34; &amp; &#34;&#34;&#34;list&#34;&#34;&#34; &amp; &#34;&gt;&#34;<br/>Do <br/>&nbsp;&nbsp; m = m + 1<br/>&nbsp;&nbsp; n = P + Len(St)<br/>&nbsp;&nbsp; P = InStr(n,S,St)<br/>&nbsp;&nbsp; ReDim Preserve pl(m-1)<br/>&nbsp;&nbsp; pl(m-1) = P<br/>loop While P &lt;&gt; 0<br/><br/>For o = 0 to m-1<br/>&nbsp;&nbsp; If o+1 &lt; m-1 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;T_S=Mid(S,pl(o)+Len(St),pl(o+1)-pl(o)-Len(St))<br/>&nbsp;&nbsp;&nbsp;&nbsp;If Len(T_S) &lt; 30 Then <br/>&nbsp;&nbsp;&nbsp;&nbsp; t=t+1<br/>&nbsp;&nbsp;&nbsp;&nbsp; Sel&#101;ct Case t<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = temp &amp; &#34;端口 : &#34; &amp; T_S &amp; vbcrlf<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = temp &amp; &#34;类型 : &#34; &amp; T_S &amp; vbcrlf<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 3<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = temp &amp; &#34;地址 : &#34; &amp; T_S &amp; vbcrlf<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 4<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = temp &amp; &#34;时间 : &#34; &amp; Now &amp; vbcrlf<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 5<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t=0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Str_Sip = &#34;whois.php?whois=&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Str_Eip = &#34;target=_blank&gt;whois&lt;/TD&gt;&lt;/TR&gt;&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n1 = P_Sip + Len(Str_Sip)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P_Sip = InStr(n1,S,Str_Sip)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n2 = P_Eip + Len(Str_Eip)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P_Eip = InStr(n2,S,Str_Eip) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ip=Mid(S,P_Sip+Len(Str_Sip),P_Eip-P_Sip-Len(Str_Sip))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If PingIp(Ip) = 1 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp = temp &amp; &#34;IP&nbsp;&nbsp;&nbsp;&nbsp;: &#34; &amp; Ip &amp; vbcrlf<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MsgBox (temp,vbyesno,&#34;是否继续? &#34; )=vbno Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WScript.quit<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = &#34;&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End Sel&#101;ct<br/>&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>&nbsp;&nbsp; Else<br/>&nbsp;&nbsp;&nbsp;&nbsp;MsgBox &#34;&nbsp;&nbsp;&nbsp;&nbsp; 没有了&#34;,vbokonly,&#34;提示&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;WSCript.quit<br/>&nbsp;&nbsp; End If<br/>Next<br/>End Sub<br/><br/>Function PingIp(host)<br/>On Error Resume Next<br/>strComputer = &#34;.&#34;<br/>strTarget = host<br/>Set objWMIService = GetObject(&#34;winmgmts:&#34; _<br/>&nbsp;&nbsp; &amp; &#34;{impersonationLevel=impersonate}!\\&#34; &amp; strComputer &amp; &#34;\root\cimv2&#34;)<br/>Set colPings = objWMIService.ExecQuery _<br/>&nbsp;&nbsp; (&#34;Sel&#101;ct * From Win32_PingStatus wh&#101;re Address = &#39;&#34; &amp; strTarget &amp; &#34;&#39;&#34;)<br/>If Err = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;Err.Clear<br/>&nbsp;&nbsp;&nbsp;&nbsp;For Each objPing in colPings<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If Err = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Err.Clear<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If objPing.StatusCode = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PingIp = 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = temp &amp; &#34;速度 : &#34; &amp; objPing.ResponseTime &amp; &#34; 毫秒&#34; &amp; vbcrlf<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MsgBox&nbsp;&nbsp; strTarget &amp; &#34; responded to ping.&#34; &amp; vbcrlf &amp;_<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&#34;Responding Address: &#34; &amp; objPing.ProtocolAddress &amp; vbcrlf &amp;_<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&#34;Responding Name: &#34; &amp; objPing.ProtocolAddressResolved &amp; vbcrlf &amp;_<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&#34;Bytes Sent: &#34; &amp; objPing.BufferSize &amp; vbcrlf &amp;_<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&#34;Time: &#34; &amp; objPing.ResponseTime &amp; &#34; ms&#34; &amp; vbcrlf &amp;_<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&#34;TTL: &#34; &amp; objPing.ResponseTimeToLive &amp; &#34; seconds&#34; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PingIp = 0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MsgBox strTarget &amp; &#34; did not respond to ping.&#34; &amp;_<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&#34;Status Code: &#34; &amp; objPing.StatusCode<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Err.Clear<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PingIP = 0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MsgBox &#34;Unable to call Win32_PingStatus on &#34; &amp; strComputer &amp; &#34;.&#34;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>&nbsp;&nbsp;&nbsp;&nbsp;Next<br/>Else<br/>&nbsp;&nbsp;&nbsp;&nbsp;Err.Clear<br/>&nbsp;&nbsp;&nbsp;&nbsp;PingIp = 0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;MsgBox &#34;Unable to call Win32_PingStatus on &#34; &amp; strComputer &amp; &#34;.&#34;<br/>End If<br/>End Function]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/1908.htm</link>
			<title><![CDATA[Ring3 下隐藏进程]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Thu,20 Sep 2007 11:35:53 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=1908</guid>
		<description><![CDATA[library nthide;<br/><br/>uses<br/>Windows,<br/>ImageHlp,<br/>TlHelp32;<br/><br/>type SYSTEM_INFORMATION_CLASS = (<br/>SystemBasicInformation,<br/>SystemProcessorInformation,<br/>SystemPerformanceInformation,<br/>SystemTimeOfDayInformation,<br/>SystemNotImplemented1,<br/>SystemProcessesAndThreadsInformation,<br/>SystemCallCounts,<br/>SystemConfigurationInformation,<br/>SystemProcessorTimes,<br/>SystemGlobalFlag,<br/>SystemNotImplemented2,<br/>SystemModuleInformation,<br/>SystemLockInformation,<br/>SystemNotImplemented3,<br/>SystemNotImplemented4,<br/>SystemNotImplemented5,<br/>SystemHandleInformation,<br/>SystemObjectInformation,<br/>SystemPagefileInformation,<br/>SystemInstructionEmulationCounts,<br/>SystemInvalidInfoClass1,<br/>SystemCacheInformation,<br/>SystemPoolTagInformation,<br/>SystemProcessorStatistics,<br/>SystemDpcInformation,<br/>SystemNotImplemented6,<br/>SystemLoadImage,<br/>SystemUnloadImage,<br/>SystemTimeAdjustment,<br/>SystemNotImplemented7,<br/>SystemNotImplemented8,<br/>SystemNotImplemented9,<br/>SystemCrashDumpInformation,<br/>SystemExceptionInformation,<br/>SystemCrashDumpStateInformation,<br/>SystemKernelDebuggerInformation,<br/>SystemContextSwitchInformation,<br/>SystemRegistryQuotaInformation,<br/>SystemLoadAndCallImage,<br/>SystemPrioritySeparation,<br/>SystemNotImplemented10,<br/>SystemNotImplemented11,<br/>SystemInvalidInfoClass2,<br/>SystemInvalidInfoClass3,<br/>SystemTimeZoneInformation,<br/>SystemLookasideInformation,<br/>SystemSetTimeSlipEvent,<br/>SystemCr&#101;ateSession,<br/>SystemDel&#101;teSession,<br/>SystemInvalidInfoClass4,<br/>SystemRangeStartInformation,<br/>SystemVerifierInformation,<br/>SystemAddVerifier,<br/>SystemSessionProcessesInformation<br/>);<br/><br/>_IMAGE_IMPORT_DESCRIPTOR = packed record<br/>case integer of<br/>0:(Characteristics: DWORD);<br/>1:(OriginalFirstThunk:DWORD; TimeDateStamp:DWORD; ForwarderChain: DWORD; Name: DWORD; FirstThunk: DWORD);<br/>end;<br/>IMAGE_IMPORT_DESCRIPTOR=_IMAGE_IMPORT_DESCRIPTOR;<br/>PIMAGE_IMPORT_DESCRIPTOR=^IMAGE_IMPORT_DESCRIPTOR;<br/><br/>PFARPROC=^FARPROC;<br/><br/>procedure ReplaceIATEntryInOneMod(pszCallerModName: Pchar; pfnCurrent: FarProc; pfnNew: FARPROC; hmodCaller: hModule);<br/>var<br/>ulSize: ULONG;<br/>pImportDesc: PIMAGE_IMPORT_DESCRIPTOR;<br/>pszModName: PChar;<br/>pThunk: PDWORD; ppfn:PFARPROC;<br/>ffound: LongBool;<br/>written: DWORD;<br/>begin<br/>pImportDesc:= ImageDirectoryEntryToData(Pointer(hmodCaller), TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, ulSize);<br/>if pImportDesc = nil then<br/>exit;<br/>while pImportDesc.Name &lt;&gt; 0 do begin<br/>pszModName := PChar(hmodCaller + pImportDesc.Name);<br/>if (lstrcmpiA(pszModName, pszCallerModName) = 0) then<br/>break;<br/>Inc(pImportDesc);<br/>end;<br/>if (pImportDesc.Name = 0) then<br/>exit;<br/>pThunk := PDWORD(hmodCaller + pImportDesc.FirstThunk);<br/>while pThunk^ &lt;&gt; 0 do begin<br/>ppfn := PFARPROC(pThunk);<br/>fFound := (ppfn^ = pfnCurrent);<br/>if (fFound) then begin<br/>VirtualProtectEx(GetCurrentProcess,ppfn,4,PAGE_EXECUTE_READWRITE,written);<br/>WriteProcessMemory(GetCurrentProcess, ppfn, @pfnNew, sizeof(pfnNew), Written);<br/>exit;<br/>end;<br/>Inc(pThunk);<br/>end;<br/>end;<br/><br/>var<br/>addr_NtQuerySystemInformation: Pointer;<br/>mypid: DWORD;<br/>fname: PCHAR;<br/>mapaddr: PDWORD;<br/>hideOnlyTaskMan: PBOOL;<br/><br/>function myNtQuerySystemInfo(SystemInformationClass: SYSTEM_INFORMATION_CLASS; SystemInformation: Pointer;<br/>SystemInformationLength:ULONG; ReturnLength:PULONG):LongInt; stdcall;<br/>label onceagain, getnextpidstruct, quit, fillzero;<br/>asm<br/>push ReturnLength<br/>push SystemInformationLength<br/>push SystemInformation<br/>push dword ptr SystemInformationClass<br/>call dword ptr [addr_NtQuerySystemInformation]<br/>o&#114; eax,eax<br/>jl quit<br/>cmp SystemInformationClass, SystemProcessesAndThreadsInformation<br/>jne quit<br/><br/>onceagain:<br/>mov esi, SystemInformation<br/><br/>getnextpidstruct:<br/>mov ebx, esi<br/>cmp dword ptr [esi],0<br/>je quit<br/>add esi, [esi]<br/>mov ecx, [esi+44h]<br/>cmp ecx, mypid<br/>jne getnextpidstruct<br/>mov edx, [esi]<br/>test edx, edx<br/>je fillzero<br/>add [ebx], edx<br/>jmp onceagain<br/><br/>fillzero:<br/>and [ebx], edx<br/>jmp onceagain<br/><br/>quit:<br/>mov Result, eax<br/>end;<br/><br/>procedure InterceptFunctions;<br/>var<br/>hSnapShot: THandle;<br/>me32: MODULEENTRY32;<br/>begin<br/>addr_NtQuerySystemInformation:=GetProcAddress(getModuleHandle(&#39;ntdll.dll&#39;),&#39;NtQuerySystemInformation&#39;);<br/>hSnapShot:=Cr&#101;ateToolHelp32SnapShot(TH32CS_SNAPMODULE,GetCurrentProcessId);<br/>if hSnapshot=INVALID_HANDLE_VALUE then<br/>exit;<br/>try<br/>ZeroMemory(@me32,sizeof(MODULEENTRY32));<br/>me32.dwSize:=sizeof(MODULEENTRY32);<br/>Module32First(hSnapShot,me32);<br/>repeat<br/>ReplaceIATEntryInOneMod(&#39;ntdll.dll&#39;,addr_NtQuerySystemInformation,@MyNtQuerySystemInfo,me32.hModule);<br/>until not Module32Next(hSnapShot,me32);<br/>finally<br/>CloseHandle(hSnapShot);<br/>end;<br/>end;<br/><br/>procedure UninterceptFunctions;<br/>var<br/>hSnapShot: THandle;<br/>me32: MODULEENTRY32;<br/>begin<br/>addr_NtQuerySystemInformation:=GetProcAddress(getModuleHandle(&#39;ntdll.dll&#39;),&#39;NtQuerySystemInformation&#39;);<br/>hSnapShot:=Cr&#101;ateToolHelp32SnapShot(TH32CS_SNAPMODULE,GetCurrentProcessId);<br/>if hSnapshot=INVALID_HANDLE_VALUE then exit;<br/>try<br/>ZeroMemory(@me32,sizeof(MODULEENTRY32));<br/>me32.dwSize:=sizeof(MODULEENTRY32);<br/>Module32First(hSnapShot,me32);<br/>repeat<br/>ReplaceIATEntryInOneMod(&#39;ntdll.dll&#39;,@MyNtQuerySystemInfo,addr_NtQuerySystemInformation,me32.hModule);<br/>until not Module32Next(hSnapShot,me32);<br/>finally<br/>CloseHandle(hSnapShot);<br/>end;<br/>end;<br/><br/>var HookHandle: THandle;<br/><br/>function CbtProc(code: integer; wparam: integer; lparam: integer):Integer; stdcall;<br/>begin<br/>Result:=0;<br/>end;<br/><br/>procedure InstallHook; stdcall;<br/>begin<br/>HookHandle := SetWindowsHookEx(WH_CBT, @CbtProc, HInstance, 0);<br/>end;<br/><br/>var hFirstMapHandle:THandle;<br/><br/>procedure HideProcess(pid:DWORD); stdcall;<br/>var<br/>addrMap: PDWORD;<br/>ptr2: PBOOL;<br/>begin<br/>mypid:=0;<br/>hFirstMapHandle:=Cr&#101;ateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,8,&#39;NtHideFileMapping&#39;);<br/>if hFirstMapHandle=0 then<br/>exit;<br/>addrMap:=MapViewOfFile(hFirstMapHandle,FILE_MAP_WRITE,0,0,8);<br/>if addrMap=nil then begin<br/>CloseHandle(hFirstMapHandle);<br/>exit;<br/>end;<br/>addrMap^:=pid;<br/>ptr2:=PBOOL(DWORD(addrMap)+4);<br/>ptr2^:= false;<br/>UnmapViewOfFile(addrMap);<br/>InstallHook;<br/>end;<br/><br/>exports<br/>HideProcess;<br/><br/>var<br/>hmap: THandle;<br/><br/>procedure LibraryProc(Reason: Integer);<br/>begin<br/>if Reason = DLL_PROCESS_DETACH then<br/>if mypid &gt; 0 then<br/>UninterceptFunctions()<br/>else<br/>CloseHandle(hFirstMapHandle);<br/>end;<br/><br/>function ExtractFileName(APath:string): string;<br/>var<br/>LI,LJ: Integer;<br/>begin<br/>if Length(APath)&lt;&gt;0 then begin<br/>LJ:=0;<br/>for LI:=Length(APath) downto 1 do<br/>if APath[LI]=&#39;\&#39; then begin<br/>LJ:=LI;<br/>Break;<br/>end;<br/>Result:=Copy(APath,LJ+1,MaxInt);<br/>end<br/>else<br/>Result := &#39;&#39;;<br/>end;<br/><br/>function AllocMem(Size: Cardinal): Pointer;<br/>begin<br/>GetMem(Result, Size);<br/>FillChar(Result^, Size, 0);<br/>end;<br/><br/>begin<br/>hmap:=OpenFileMapping(FILE_MAP_READ,false,&#39;NtHideFileMapping&#39;);<br/>if hmap=0 then<br/>exit;<br/>try<br/>mapaddr:=MapViewOfFile(hmap,FILE_MAP_READ,0,0,0);<br/>if mapaddr=nil then<br/>exit;<br/>mypid:=mapaddr^;<br/>hideOnlyTaskMan:=PBOOL(DWORD(mapaddr)+4);<br/>if hideOnlyTaskMan^ then begin<br/>fname:=allocMem(MAX_PATH+1);<br/>GetModuleFileName(GetModuleHandle(nil),fname,MAX_PATH+1);<br/>if not (ExtractFileName(fname)=&#39;taskmgr.exe&#39;) then<br/>exit;<br/>end;<br/>InterceptFunctions;<br/>finally<br/>UnmapViewOfFile(mapaddr);<br/>CloseHandle(Hmap);<br/>DLLProc:=@LibraryProc;<br/>end;<br/>end. ]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/1816.htm</link>
			<title><![CDATA[浅谈用SHAppBarMessage函数控制任务栏]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Sat,01 Sep 2007 11:10:56 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=1816</guid>
		<description><![CDATA[利用SHAppBarMessage函数我们可以完成对任务栏的控制，或是获取任务栏的相关信息。<br/><br/>当然了，Autoit本身并不提供该项函数，不过我们可以通过调用API实现，具体方法见下面的例子。<br/><br/>SHAppBarMessage函数的用法：<br/>SHAppBarMessage(消息名,APPBARDATA结构指针)<br/><br/>消息名对应着操作类型，比如ABM_GETSTATE代表着获取任务栏状态，ABM_SETSTATE代表设置任务栏状态等。而APPBARDATA结构指针则储存着任务栏的相关数据，其结构为：<br/>struct APP_BAR_DATA<br/>{<br/>int cbSize;<br/>IntPtr hWnd;<br/>int uCallbackMessage;<br/>int uEdge;<br/>RECT rc;<br/>IntPtr lParam;<br/>}<br/><br/>而RECT本身也包含着一个结构：<br/>struct RECT<br/>{<br/>int left;<br/>int top;<br/>int right;<br/>int bottom;<br/>}<br/><br/>在autoit里写就是：<br/>$pabd = DllStructCr&#101;ate(&#34;dword;int;uint;uint;int;int;int;int;int&#34;)<br/><br/>分别对应着cbSize、任务栏句柄、callback指针、边缘的位置、左、上、右、下、状态。<br/><br/>其中cbSize用DllStructGetSize处理就好了，任务栏句柄需要自己添加，别的就不用管了。<br/><br/>顺带一提，用ABM_NEW消息你可以把一个窗口变为任务栏，autoit里已经具备了实现条件，我会抽时间试一下。<br/><br/>理论完毕，剩下的东西就看看下面的例子吧：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.ruery.net/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">;SHAppBarMessage<br/>;Sends an appbar message to the system. <br/>;<br/>;Syntax<br/>;UINT_PTR SHAppBarMessage( DWORD dwMessage, PAPPBARDATA pData );<br/>;<br/>;MSDN<br/>;<a href="http://msdn2.microsoft.com/en-us/library/ms647647.aspx" target="_blank" rel="external">http://msdn2.microsoft.com/en-us/library/ms647647.aspx</a><br/>;<br/>;Author zHcH<br/>;For more information,please visit<br/>;<a href="http://hi.baidu.com/zhch_ao" target="_blank" rel="external">http://hi.baidu.com/zhch_ao</a><br/><br/>;------------------------定义一些将要使用的变量----------------------------<br/><br/>Global Const $ABM_ACTIVATE = 0x06<br/>Global Const $ABM_GETAUTOHIDEBAR = 0x07<br/>Global Const $ABM_GETSTATE = 0x04<br/>Global Const $ABM_SETSTATE = 0x0000000a<br/>Global Const $ABM_GETTASKBARPOS = 0x05<br/>Global Const $ABM_NEW = 0x00<br/>Global Const $ABM_QUERYPOS = 0x02<br/>Global Const $ABM_REMOVE = 0x01<br/>Global Const $ABM_SETAUTOHIDEBAR = 0x08<br/>Global Const $ABM_SETPOS = 0x03<br/>Global Const $ABM_WINDOWPOSCHANGED = 0x09<br/>;---<br/>Global Const $ABS_ALWAYSONTOP = 0x2<br/>Global Const $ABS_AUTOHIDE = 0x1<br/>;---<br/>Global Const $ABE_LEFT = 0<br/>Global Const $ABE_TOP = 1<br/>Global Const $ABE_RIGHT = 2<br/>Global Const $ABE_BOTTOM = 3<br/>;---<br/><br/>;--------------------------建立APPBARDATA结构的指针----------------------------<br/>;详细信息:<a href="http://msdn2.microsoft.com/en-us/library/ms538008.aspx" target="_blank" rel="external">http://msdn2.microsoft.com/en-us/library/ms538008.aspx</a><br/><br/>Global $pabd = DllStructCr&#101;ate(&#34;dword;int;uint;uint;int;int;int;int;int&#34;)<br/>DllStructSetData($pabd,1,DllStructGetSize($pabd)) ;cbSize<br/>DllStructSetData($pabd,2,ControlGetHandle(&#34;Start&#34;,&#34;&#34;,&#34;Shell_TrayWnd&#34;)) ;hWnd<br/><br/>;-------------------------定义SHAppBarMessage函数------------------------------<br/><br/>Func SHAppBarMessage($Message,ByRef $pabd)<br/>$lResult = DllCall(&#34;shell32.dll&#34;,&#34;int&#34;,&#34;SHAppBarMessage&#34;,&#34;int&#34;,$Message,&#34;ptr&#34;,DllStructGetPtr($pabd))<br/>If Not @error Then<br/>If $lResult[0] Then<br/>Return $lResult[0]<br/>EndIf<br/>EndIf<br/>SetError(1)<br/>Return False<br/>EndFunc<br/><br/>;----------------------------------例子开始----------------------------------<br/><br/>;---------------------ep1.控制任务栏的状态<br/>#cs<br/>DllStructSetData($pabd,9,BitOR($ABS_ALWAYSONTOP,$ABS_AUTOHIDE)) ;自动隐藏,且位于窗口前<br/>DllStructSetData($pabd,9,$ABS_AUTOHIDE) ;自动隐藏,且不位于窗口前<br/>DllStructSetData($pabd,9,$ABS_ALWAYSONTOP) ;不自动隐藏,且位于窗口前<br/><br/>SHAppBarMessage($ABM_SETSTATE,$pabd) ;发送ABM_SETSTATE消息应用修改<br/>#ce<br/><br/>;---------------------ep2.获取任务栏状态<br/>#cs<br/>$result = SHAppBarMessage($ABM_GETSTATE,$pabd)<br/>If BitAND($result,$ABS_ALWAYSONTOP) = $ABS_ALWAYSONTOP Then ConsoleWrite(&#34;ALWAYSONTOP&#34; &amp; @LF)<br/>If BitAND($result,$ABS_AUTOHIDE) = $ABS_AUTOHIDE Then ConsoleWrite(&#34;AUTOHIDE&#34; &amp; @LF)<br/>#ce<br/><br/>;---------------------ep3.任务栏的位置<br/>#cs<br/>$result = SHAppBarMessage($ABM_GETTASKBARPOS,$pabd)<br/>If $result Then<br/>ConsoleWrite(&#34;Left : &#34; &amp; DllStructGetData($pabd,5) &amp; @LF)<br/>ConsoleWrite(&#34;Top : &#34; &amp; DllStructGetData($pabd,6) &amp; @LF)<br/>ConsoleWrite(&#34;Right : &#34; &amp; DllStructGetData($pabd,7) &amp; @LF)<br/>ConsoleWrite(&#34;Bottom: &#34; &amp; DllStructGetData($pabd,8) &amp; @LF)<br/>EndIf<br/><br/>Switch DllStructGetData($pabd,4)<br/>Case 0<br/>ConsoleWrite(&#34;ABE_LEFT&#34; &amp; @LF)<br/>Case 1<br/>ConsoleWrite(&#34;ABE_TOP&#34; &amp; @LF)<br/>Case 2<br/>ConsoleWrite(&#34;ABE_RIGHT&#34; &amp; @LF)<br/>Case 3<br/>ConsoleWrite(&#34;ABE_BOTTOM&#34; &amp; @LF)<br/>EndSwitch<br/>#ce<br/><br/>;----------------------------------例子结束--------------------------------------</div></div><br/><br/>提示:你可以将此段代码保存为SHAppBarMessage.au3，并放入include文件夹中。此后再要调用该函数只需在脚本头加上 #include &lt;SHAppBarMessage.au3&gt; 。<br/><br/>——END——]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/1784.htm</link>
			<title><![CDATA[取得windows注册序列号]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Sat,25 Aug 2007 13:00:11 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=1784</guid>
		<description><![CDATA[来源:teN.potgnayiaH.wwW vbs小铺<br/><br/>&#39;&nbsp;&nbsp; ##############################################################<br/>&#39;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; # VBScript to find the DigitalProductID for your&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; # Microsoft windows Installation and decode it to&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; # retrieve your windows Product Key&nbsp;&nbsp;&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; # -----------------------------------------------&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; #&nbsp;&nbsp; Cr&#101;ated by:&nbsp;&nbsp; Parabellum&nbsp;&nbsp;&nbsp;&nbsp;#<br/>&#39;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br/>&#39;&nbsp;&nbsp; ##############################################################<br/>&#39;<br/>&#39; &lt;--------------- Open Registry Key and populate binary data into an array --------------------------&gt;<br/>&#39;<br/>const HKEY_LOCAL_MACHINE = &amp;H80000002 <br/>strKeyPath = &#34;SOFTWARE\Microsoft\Windows NT\CurrentVersion&#34;<br/>strValueName = &#34;DigitalProductId&#34;<br/>strComputer = &#34;.&#34;<br/>dim iValues()<br/>Set o&#114;eg=GetObject(&#34;winmgmts:{impersonationLevel=impersonate}!\\&#34; &amp; _ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strComputer &amp; &#34;\root\default:StdRegProv&#34;)<br/>o&#114;eg.GetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,iValues<br/>Dim arrDPID<br/>arrDPID = Array()<br/>For i = 52 to 66<br/>ReDim Preserve arrDPID( UBound(arrDPID) + 1 )<br/>arrDPID( UBound(arrDPID) ) = iValues(i)<br/>Next<br/>&#39; &lt;--------------- Cr&#101;ate an array to hold the valid characters for a microsoft Product Key --------------------------&gt;<br/>Dim arrChars<br/>arrChars = Array(&#34;B&#34;,&#34;C&#34;,&#34;D&#34;,&#34;F&#34;,&#34;G&#34;,&#34;H&#34;,&#34;J&#34;,&#34;K&#34;,&#34;M&#34;,&#34;P&#34;,&#34;Q&#34;,&#34;R&#34;,&#34;T&#34;,&#34;V&#34;,&#34;W&#34;,&#34;X&#34;,&#34;Y&#34;,&#34;2&#34;,&#34;3&#34;,&#34;4&#34;,&#34;6&#34;,&#34;7&#34;,&#34;8&#34;,&#34;9&#34;)<br/><br/>&#39; &lt;--------------- The clever bit !!! (Decrypt the base24 encoded binary data)--------------------------&gt;<br/>For i = 24 To 0 Step -1<br/>k = 0<br/>For j = 14 To 0 Step -1<br/>k = k * 256 Xor arrDPID(j)<br/>arrDPID(j) = Int(k / 24)<br/>k = k Mod 24<br/>Next<br/>strProductKey = arrChars(k) &amp; strProductKey<br/>&#39; &lt;------- add the &#34;-&#34; between the groups of 5 Char --------&gt;<br/>If i Mod 5 = 0 And i &lt;&gt; 0 Then strProductKey = &#34;-&#34; &amp; strProductKey<br/>Next<br/>strFinalKey = strProductKey<br/>&#39;<br/>&#39; &lt;---------- This part of the script displays operating system Information and the license Key ---------&gt;<br/>&#39;<br/>strComputer = &#34;.&#34;<br/>Set objWMIService = GetObject(&#34;winmgmts:&#34; _<br/>&nbsp;&nbsp; &amp; &#34;{impersonationLevel=impersonate}!\\&#34; &amp; strComputer &amp; &#34;\root\cimv2&#34;)<br/>Set colOperatingSystems = objWMIService.ExecQuery _<br/>&nbsp;&nbsp; (&#34;Sel&#101;ct * from Win32_OperatingSystem&#34;)<br/>For Each objOperatingSystem in colOperatingSystems<br/>&nbsp;&nbsp; strOS&nbsp;&nbsp;&nbsp;&nbsp;= objOperatingSystem.Caption<br/>&nbsp;&nbsp; strBuild&nbsp;&nbsp;&nbsp;&nbsp;= objOperatingSystem.BuildNumber<br/>&nbsp;&nbsp; strSerial&nbsp;&nbsp;&nbsp;&nbsp;= objOperatingSystem.SerialNumber<br/>&nbsp;&nbsp; strRegistered&nbsp;&nbsp; = objOperatingSystem.RegisteredUser<br/>Next<br/>Set wshShell=Cr&#101;ateObject(&#34;wscript.shell&#34;)<br/>strPopupMsg = strOS &amp; vbNewLine &amp; vbNewLine<br/>strPopupMsg = strPopupMsg &amp; &#34;Build Number:&nbsp;&nbsp; &#34; &amp; strBuild &amp; vbNewLine<br/>strPopupMsg = strPopupMsg &amp; &#34;PID:&nbsp;&nbsp; &#34; &amp; strSerial &amp; vbNewLine &amp; vbNewLine<br/>strPopupMsg = strPopupMsg &amp; &#34;Registered to:&nbsp;&nbsp; &#34; &amp; strRegistered &amp; vbNewLine &amp; vbNewLine &amp; vbNewLine<br/>strPopupMsg = strPopupMsg &amp; &#34;Your Windows Product Key is:&#34; &amp; vbNewLine &amp; vbNewLine &amp; strFinalKey<br/>strPopupTitle = &#34;Microsoft Windows License Information&#34;<br/>wshShell.Popup strPopupMsg,,strPopupTitle,vbCancelOnly+vbinformation<br/>WScript.Quit]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/1758.htm</link>
			<title><![CDATA[如何透過程式來控制 Windows (XP) 防火牆的開關]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Fri,17 Aug 2007 12:17:20 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=1758</guid>
		<description><![CDATA[Dim objFW As Object&nbsp;&nbsp; <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;Set objFW = Cr&#101;ateObject(&#34;HNetCfg.FwMgr&#34;).LocalPolicy.CurrentProfile<br/>&nbsp;&nbsp;&nbsp;&nbsp;With objFW<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.FirewallEnabled = True &#39; True 開啟 , False 關閉<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ExceptionsNotAllowed = True &#39; [ 不允許例外 ] 選項 , True 勾 , 反之則不勾<br/>&nbsp;&nbsp;&nbsp;&nbsp;End With<br/><br/><br/>或<br/><br/>procedure Set_WindowsXP_FireWall(Enable: boolean);<br/>// 需引用 winsvc, shellapi<br/>// Set_WindowsXP_FireWall(false); // 關閉 Windows Xp 防火牆<br/>//<br/>var<br/>&nbsp;&nbsp;SCM, hService: LongWord;<br/>&nbsp;&nbsp;sStatus: TServiceStatus;<br/>begin<br/>&nbsp;&nbsp;if Enable = false then<br/>&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;SCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);<br/>&nbsp;&nbsp;&nbsp;&nbsp;hService := OpenService(SCM, PChar(&#39;SharedAccess&#39;), SERVICE_ALL_ACCESS);<br/>&nbsp;&nbsp;&nbsp;&nbsp;ControlService(hService, SERVICE_CONTROL_STOP, sStatus);<br/>&nbsp;&nbsp;&nbsp;&nbsp;CloseServiceHandle(hService);<br/>&nbsp;&nbsp;end;<br/>end;<br/><br/>設定Port 的部份，不過還沒測試！不過我還是希望寫成簡單形式的函數庫呼叫方式，大家一起來測試吧！<br/><br/>出處：<a href="http://www-new.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_22122056.html" target="_blank" rel="external">http://www-new.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_22122056.html</a><br/>Example of both adding and removing a tcp port from the globaly open ports list (in Windows XP firewall)<br/><br/>Regards,<br/>Russell<br/><br/>// Include ActiveX and ComObj in uses clause (also Variants for D6 and up)<br/><br/>const<br/>&nbsp;&nbsp;NET_FW_PROFILE_DOMAIN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;0;<br/>&nbsp;&nbsp;NET_FW_PROFILE_STANDARD&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;1;<br/><br/>const<br/>&nbsp;&nbsp;NET_FW_IP_PROTOCOL_TCP&nbsp;&nbsp;&nbsp;&nbsp; = 6;<br/>&nbsp;&nbsp;NET_FW_IP_PROTOCOL_UDP&nbsp;&nbsp;&nbsp;&nbsp; = 17;<br/><br/>const<br/>&nbsp;&nbsp;NET_FW_SCOPE_ALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;0;<br/><br/>const<br/>&nbsp;&nbsp;NET_FW_IP_VERSION_ANY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;2;<br/><br/>implementation<br/>{$R *.DFM}<br/><br/>procedure TForm1.Button1Click(Sender: TObject);<br/>var&nbsp;&nbsp;ovMgr:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OleVariant;<br/>&nbsp;&nbsp;&nbsp;&nbsp; ovProfile:&nbsp;&nbsp;&nbsp;&nbsp; OleVariant;<br/>&nbsp;&nbsp;&nbsp;&nbsp; ovPort:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleVariant;<br/>begin<br/><br/>&nbsp;&nbsp;// Cr&#101;ate manager interface<br/>&nbsp;&nbsp;ovMgr:=Cr&#101;ateOleObject(&#39;HNetCfg.FwMgr&#39;);<br/><br/>&nbsp;&nbsp;// Resource protection<br/>&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp; // Get local profile interface<br/>&nbsp;&nbsp;&nbsp;&nbsp; ovProfile:=ovMgr.LocalPolicy.CurrentProfile;<br/>&nbsp;&nbsp;&nbsp;&nbsp; // Resource protection<br/>&nbsp;&nbsp;&nbsp;&nbsp; try<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Cr&#101;ate new port interface<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ovPort:=Cr&#101;ateOleObject(&#39;HNetCfg.FwOpenPort&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set port properties<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovPort.Port:=81;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovPort.Name:=&#39;Whatever&#39;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovPort.Scope:=NET_FW_SCOPE_ALL;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovPort.IpVersion:=NET_FW_IP_VERSION_ANY;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovPort.Protocol:=NET_FW_IP_PROTOCOL_TCP;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovPort.Enabled:=True;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Resource protection<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Add to globally open ports<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ovProfile.GloballyOpenPorts.Add(ovPort);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;////<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// .... do whatever ....<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;////<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Remove from globally open ports<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ovProfile.GloballyOpenPorts.Remove(81, NET_FW_IP_PROTOCOL_TCP);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Release interface<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovPort:=Unassigned;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br/>&nbsp;&nbsp;&nbsp;&nbsp; finally<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Release interface<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ovProfile:=Unassigned;<br/>&nbsp;&nbsp;&nbsp;&nbsp; end;<br/>&nbsp;&nbsp;finally<br/>&nbsp;&nbsp;&nbsp;&nbsp; // Release interface<br/>&nbsp;&nbsp;&nbsp;&nbsp; ovMgr:=Unassigned;<br/>&nbsp;&nbsp;end;<br/><br/>end;]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/1672.htm</link>
			<title><![CDATA[PHP入门教程]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Sun,05 Aug 2007 18:36:22 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=1672</guid>
		<description><![CDATA[１．PHP 是什么？<br/>PHP（&#34;PHP: Hypertext Preprocessor&#34;，超文本预处理器的字母缩写）是一种被广泛应用的开放源代码的多用途脚本语言，它可嵌入到 HTML中，尤其适合 web 开发。 <br/>以上是一个简单的回答，不过这是什么意思呢？请看如下例子： 例子 1-1. 一个介绍性的范例<br/>[table=98%,#e0e0e0] <br/>&lt;html&gt;<br/>&lt;head&gt;<br/>&lt;title&gt;Example&lt;/title&gt;<br/>&lt;/head&gt;<br/>&lt;body&gt;<br/><br/>&lt;?php<br/>echo &#34;Hi, I&#39;m a PHP scrīpt!&#34;;<br/>?&gt;<br/><br/>&lt;/body&gt;<br/>&lt;/html&gt; <br/>[/td][/tr][/table]<br/>请注意这个范例和其它用 C 或 Perl 语言写的脚本之间的区别――与用大量的命令来编写程序以输出 HTML 不同的是，我们用 PHP 编写了一个 HTML 脚本，其中嵌入了一些代码来做一些事情（例如，在本例中输出了一些文本）。PHP 代码被包含在特殊的起始符和结束符中，使得可以进出&#34;PHP 模式&#34;。 <br/>和客户端的 Javascrīpt 不同的是，PHP 代码是运行在服务端的。如果在服务器上建立了如上例类似的代码，则在运行该脚本后，客户端就能接收到其结果，但他们无法得知其背后的代码是如何运作的。甚至可以将 web 服务器设置成让 PHP 来处理所有的 HTML 文件，这么一来，用户就无法得知服务端到底做了什么。 <br/>使用 PHP 的一大好处是它对于初学者来说极其简单，同时也给专业的程序员提供了各种高级的特性。当看到 PHP 长长的特性列表时，请不要害怕。可以很快的入门，只需几个小时就可以自己写一些简单的脚本。 <br/>尽管 PHP 的开发是以服务端脚本为目的，但事实上其功能远不局限与此。<br/><br/><br/><br/>２．PHP 能做什么？<br/>PHP 能做任何事。PHP 主要是用于服务端的脚本程序，因此可以用 PHP 来完成任何其它的 CGI 程序能够完成的工作，例如收集表单数据，生成动态网页，或者发送／接收 Cookies。但 PHP 的功能远不局限于此。 <br/>PHP 脚本主要用于以下三个领域： <br/><br/><br/>服务端脚本。这是 PHP 最传统，也是最主要的目标领域。开展这项工作需要具备以下三点：PHP 解析器（CGI 或者服务器模块）、web 服务器和 web 浏览器。需要在运行 web 服务器时，安装并配置 PHP，然后，可以用 web 浏览器来访问 PHP 程序的输出，即浏览服务端的 PHP 页面。如果只是实验 PHP 编程，所有的这些都可以运行在自己家里的电脑中。命令行脚本。可以编写一段 PHP 脚本，并且不需要任何服务器或者浏览器来运行它。通过这种方式，仅仅只需要 PHP 解析器来执行。这种用法对于依赖 cron（Unix 或者 Linux 环境）或者 Task Scheduler（Windows 环境）的日常运行的脚本来说是理想的选择。这些脚本也可以用来处理简单的文本。 <br/>编写桌面应用程序。对于有着图形界面的桌面应用程序来说，PHP 或许不是一种最好的语言，但是如果用户非常精通 PHP，并且希望在客户端应用程序中使用 PHP 的一些高级特性，可以利用 PHP-GTK 来编写这些程序。用这种方法，还可以编写跨平台的应用程序。PHP-GTK 是 PHP 的一个扩展，在通常发布的 PHP 包中并不包含它。如果对 PHP-GTK 感兴趣，请访问其网站以获取更多信息。<br/><br/>PHP 能够用在所有的主流操作系统上，包括 Linux、Unix 的各种变种（包括 HP-UX、Solaris 和 OpenBSD）、Microsoft Windows、Mac OS X、RISC OS 等。今天，PHP已经支持了大多数的 web 服务器，包括 Apache、Microsoft Internet Information Server（IIS）、Personal web Server（PWS）、Netscape 以及 iPlant server、Oreilly Website Pro Server、Caudium、Xitami、OmniHTTPd 等。对于大多数的服务器，PHP 提供了一个模块；还有一些 PHP 支持 CGI 标准，使得 PHP 能够作为 CGI 处理器来工作。 <br/>综上所述，使用 PHP，可以自由地选择操作系统和 web 服务器。同时，还可以在开发时选择使用面对过程和面对对象，或者两者混和的方式来开发。尽管 PHP 4 不支持 OOP 所有的标准，但很多代码仓库和大型的应用程序（包括 PEAR 库）仅使用 OOP 代码来开发。PHP 5 弥补了 PHP 4 的这一弱点，引入了完全的对象模型。 <br/>使用 PHP，并不局限于输出 HTML。PHP 还能被用来动态输出图像、PDF 文件甚至 Flash 动画（使用 libswf 和 Ming）。还能够非常简便的输出文本，例如 XHTML 以及任何其它形式的 XML 文件。PHP 能够自动生成这些文件，在服务端开辟出一块动态内容的缓存，可以直接把它们打印出来，或者将它们存储到文件系统中。 <br/>PHP 最强大最显著的特性之一，是它支持很大范围的数据库。用户会发现利用 PHP 编写数据库支持的网页简单得难以置信。目前，PHP 支持如下数据库： <br/>Adabas D InterBase PostgreSQL <br/>dBase FrontBase SQLite <br/>Empress mSQL Solid <br/>FilePro（只读） Direct MS-SQL Sybase <br/>Hyperwave MySQL Velocis <br/>IBM DB2 ODBC Unix dbm <br/>Informix o&#114;acle（OCI7 和 OCI8） <br/>Ingres Ovrimos <br/><br/>同时还有一个 DBX 扩展库使得可以自由地使用该扩展库支持的任何数据库。另外，PHP 还支持 ODBC，即 Open Database Connection Standard（开放数据库连接标准），因此可以连接任何其它支持该世界标准的数据库。 <br/><br/>PHP 还支持利用诸如 LDAP、IMAP、SNMP、NNTP、POP3、HTTP、COM（Windows 环境）等不计其数的协议的服务。还可以开放原始网络端口，使得任何其它的协议能够协同工作。PHP 支持和所有 web 开发语言之间的 WDDX 复杂数据交换。关于相互连接，PHP 已经支持了对 Java 对象的即时连接，并且可以将他们自由的用作 PHP 对象。甚至可以用我们的 CORBA 扩展库来访问远程对象。 <br/>PHP 具有极其有效的文本处理特性，支持从 POSIX 扩展或者 Perl 正则表达式到 XML 文档解析。为了解析和访问 XML 文档，PHP 4 支持 SAX 和 DOM 标准，也可以使用 XSLT 扩展库来转换 XML 文档。PHP 5 基于强健的 libxm2 标准化了所有的 XML 扩展，并添加了 SimpleXML 和 XMLReader 支持，扩展了其在 XML 方面的功能。 <br/>如果将 PHP 用于电子商务领域，会发现其 Cybercash 支付、CyberMUT、VeriSign Payflow Pro 以及 MCVE 函数对于在线交易程序来说是非常有用的。 <br/>另外，还有很多其它有趣的扩展库。例如 mnoGoSearch 搜索引擎函数、IRC 网关函数、多种压缩工具（gzip、bz2）、日历转换、翻译…… <br/><br/><br/><br/>３．需要些什么？<br/>在本教程中，假设用户的服务器已经安装并运行了 PHP，所有以 .php 结尾的文件都将由 PHP 来处理。在大部分的服务器上，这是 PHP 的默认扩展名，不过，也请询问服务器管理员以确认。如果服务器支持 PHP，则不需要做任何事情。只用建立 .php 文件，并把它们放置到 web 目录中，服务器将神奇地自动解析这些文件。不用编译任何东西，也不用安装任何其它的工具，仅仅只需把这些使用了 PHP 的文件想象成简单的 HTML 文件，其中只不过多了一种新的标识符，在这里可以做各种各样的事情。大多数的 web 主机都提供 PHP 的支持，如果你的主机不支持，可以访问 PHP 相关链接来查找支持 PHP 的 web 主机。 <br/>假设用户希望在本地机器开发以节约宝贵的带宽。在这种情况下，需要安装一个诸如 Apache 的 web 服务器，当然还有 PHP。可能还希望安装一个数据库，例如 MySQL。 <br/><br/><br/><br/><br/>４．第一个 PHP 页面<br/>在 web 服务器根目录（DOCUMENT_ROOT）下建立一个文件名为 hello.php，然后完成如下内容： 例子 2-1. 第一个 PHP 脚本：hello.php<br/>[table=98%,#e0e0e0] <br/>&lt;html&gt;<br/>&lt;head&gt;<br/>&lt;title&gt;PHP 测试&lt;/title&gt;<br/>&lt;/head&gt;<br/>&lt;body&gt;<br/>&lt;?php echo &#39;&lt;p&gt;Hello World&lt;/p&gt;&#39;; ?&gt;<br/>&lt;/body&gt;<br/>&lt;/html&gt; <br/>在浏览器的地址栏里输入 web 服务器的 URL 访问这个文件，在结尾加上&#34;/hello.php&#34;。如果本地开发，那么这个 URL 一般是 <a href="http://localhost/hello.php" target="_blank" rel="external">http://localhost/hello.php</a> 或者 <a href="http://127.0.0.1/hello.php" target="_blank" rel="external">http://127.0.0.1/hello.php</a>，当然这取决于 web 服务器的设置。如果所有的设置都正确，那么这个文件将被 PHP 解析，浏览器中将会输出如下结果： <br/>[table=98%,#e0e0e0][tr][td]&lt;html&gt; &lt;head&gt; &lt;title&gt;PHP 测试&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;p&gt;Hello World&lt;/p&gt; &lt;/body&gt;&lt;/html&gt;[/td][/tr][/table]<br/>[/td][/tr][/table]该程序非常的简单，它仅仅只是利用了 PHP 的 echo() 语句显示了 Hello World。用户一定不会满足与此。请注意该文件无需被执行或以任何方式指定。服务器会找到该文件并提供给 PHP 进行解释，因为使用了&#34;.php&#34;的扩展名，服务器已被配置成自动传递有着&#34;.php&#34;扩展名的文件给 PHP。一个普通的 HTML 文件，加上了几个特别的标签，就可以做很多非常有趣的事情！ <br/>如果试过了这个例子，但是没有得到任何输出，或者浏览器弹出了下载框，或者浏览器以文本方式显示了源文件，可能的原因是服务器还没有支持 PHP，或者没有正确配置。如果本地开发，请阅读手册有关安装的章节以确保所有的设置都正确。还要确认通过浏览器访问的 URL 确实指向了服务器上的这个文件。如果只是从本地文件系统调用这个文件，它不会被 PHP 解析。如果问题仍然存在，请通过 PHP 在线支持中的各种方式获取帮助。 <br/>以上例子的目的是为了显示 PHP 特殊标识符的格式。在这个例子中，用 &lt;?php 来表示 PHP 标识符的起始，然后放入 PHP 语句并通过加上一个终止标识符 ?&gt; 来退出 PHP 模式。可以根据自己的需要在 HTML 文件中像这样开启或关闭 PHP 模式。<br/><br/>　　　关于文本编辑器: 有很多文本编辑器以及集成开发环境（IDE）可以被用来建立、编辑和管理 PHP 文件。这些工具中的一部分被列在 PHP 编辑器列表中。如果希望推荐其它的编辑器，请访问以上页面，并要求该页面的维护者将你推荐的编辑器加入到该列表中。使用支持语法高亮功能的编辑器会给开发带来很多帮助。 <br/><br/>关于文字处理器: 诸如 StarOffice Writer、Microsoft Word 和 Abiword 的文字处理器不适合用来编辑 PHP 程序。如果希望用以上这些工具的某一种来处理脚本，必须保证将结果存成了纯文本格式，否则 PHP 将无法读取并运行这些脚本。 <br/><br/><br/><br/>关于 Windows 记事本: 如果使用 Windows 记事本来编写 PHP 脚本，需要注意在保存文件时，文件的后缀名应该为 .php（记事本将自动在文件名后面加上 .txt 后缀，除非采取以下措施之一来避免这种情况）。当保存文件时，系统会让你指定文件的文件名，这时请将文件名加上引号（例如 &#34;hello.php&#34;）。或者，也可以点击&#34;保存&#34;对话框中的&#34;保存类型&#34;下拉菜单，并将设置改为&#34;所有文件&#34;。这样在输入文件名的时候就不用加引号了。 <br/><br/><br/>现在已经成功建立了一个简单的 PHP 脚本。还可以建立一个最著名的 PHP 脚本。调用函数phpinfo()，将会看到很多有关自己系统有用的信息，以及预定义变量、已经加载的 PHP 模块和配置信息。请花一些时间来查看这些重要的信息。 <br/><br/><br/><br/>５．实用的脚本<br/>现在来编写一些更实用的脚本，比如检查浏览页面的访问者在用什么浏览器。要达到这个目的，需要检查用户的 agent 字符串，它是浏览器发送的 HTTP 请求的一部分。该信息被存储在一个变量中。在 PHP 中，变量总是以一个美元符开头。我们现在感兴趣的变量是 $_SERVER[&#39;HTTP_USER_AGENT&#39;]。 <br/><br/><br/>注: $_SERVER 是一个特殊的 PHP 保留变量，它包含了 web 服务器提供的所有信息，被称为自动全局变量（或&#34;超全局变量&#34;）。这些特殊的变量是在 PHP 4.1.0 版本引入的。在这之前使用 $HTTP_*_VARS 数组，如 $HTTP_SERVER_VARS。尽管现在已经不用了，但它们在新版本中仍然存在要显示该变量，只需简单地进行如下操作： <br/><br/>例子 2-3. 打印一个变量（数组元素）<br/>[table=98%,#e0e0e0] <br/>&lt;?php echo $_SERVER[&#39;HTTP_USER_AGENT&#39;]; ?&gt; <br/>该脚本的输出可能是： <br/>[table=98%,#e0e0e0][tr][td]Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)[/td][/tr][/table]<br/>[/td][/tr][/table]PHP 有很多种不同类型的变量。在以上例子中我们打印了一个数组的单元。数组是一类非常有用的变量。 <br/>$_SERVER 只是 PHP 自动全局化的变量之一。可以查阅保留变量一节来查看这些变量的列表，或者也可以通过上节例子中phpinfo()函数的输出来查看。 <br/>可以在一个 PHP 标识中加入多个 PHP 语句，也可以建立一个代码块来做比简单的 echo 更多的事情。例如，如果需要识别 Internet Explorer，可以进行如下操作： 例子流程控制函数的使用<br/>[table=98%,#e0e0e0] <br/>&lt;?php<br/>if (strpos($_SERVER[&#39;HTTP_USER_AGENT&#39;], &#39;MSIE&#39;) !== FALSE) {<br/>echo &#39;正在使用 Internet Explorer。&lt;br /&gt;&#39;;<br/>}<br/>?&gt; <br/>该脚本的输出可能是： <br/>[table=98%,#e0e0e0][tr][td]正在使用 Internet Explorer。&lt;br /&gt;[/td][/tr][/table]<br/>[/td][/tr][/table]这里要介绍一些新的原理。上面用了一个if[/url] 语句。如果用户对 C 语言的基本语法比较熟悉，则应该对此很熟悉，否则，可能需要拿起任何一本 PHP 介绍性的书籍并阅读前面的两三个章节。可以在 <a href="http://www.php.net/books.php" target="_blank" rel="external">http://www.php.net/books.php</a> 找到有关 PHP 的书籍的列表。 <br/>需要介绍的第二个原理，是对strpos() 函数的调用strpos()是 PHP 的一个内置函数，其功能是在一个字符串中搜索另外一个字符串。例如我们现在需要在 $_SERVER[&#39;HTTP_USER_AGENT&#39;]（即所谓的 haystack）变量中寻找 &#39;MSIE&#39;。如果在这个 haystack 中该字符串（即所谓的 needle）被找到，则函数返回 needle 在 haystack 中相对开头的位置；如果没有，则返回 FALSE。如果该函数没有返回 FALSE，则 if 会将条件判断为 TRUE 并运行其花括号 {} 内的代码；否则，则不运行这些代码。可以自己尝试利用strtoupper()和strlen()来建立类似的脚本。在本手册中相关的页面也包含有范例。如果对如何使用函数不是很确定以下我们进一步显示如何进出 PHP 模式，甚至是在一个 PHP 代码块的中间： 例子 2-5. 混和 HTML 和 PHP 模式<br/>[table=98%,#e0e0e0] <br/>&lt;?php<br/>if (strpos($_SERVER[&#39;HTTP_USER_AGENT&#39;], &#39;MSIE&#39;) !== FALSE) {<br/>?&gt;<br/>&lt;h3&gt;strpos() 肯定没有返回假 (FALSE)&lt;/h3&gt;<br/>&lt;p&gt;正在使用 Internet Explorer&lt;/p&gt;<br/>&lt;?php<br/>} else {<br/>?&gt;<br/>&lt;h3&gt;strpos() 肯定返回假 (FALSE)&lt;/h3&gt;<br/>&lt;center&gt;&lt;b&gt;没有使用 Internet Explorer&lt;/b&gt;&lt;/center&gt;<br/>&lt;?php<br/>}<br/>?&gt; <br/>该脚本的输出可能是： <br/>[table=98%,#e0e0e0][tr][td]&lt;h3&gt;strpos() 肯定没有返回假 (FALSE)&lt;/h3&gt;&lt;p&gt;正在使用 Internet Explorer&lt;/p&gt;[/td][/tr][/table]<br/>[/td][/tr][/table]和以上我们用一个 PHP 的 echo 语句来输出不同的是，我们跳出了 PHP 模式来直接写 HTML 代码。这里很值得注意的一点是，对于这两种情况而言，脚本的逻辑效率是相同的。在判断了strpos()[/url] 函数的返回值是 TRUE 或是 FALSE，也就是判断了字符串 &#39;MSIE&#39; 是否被找到之后，最终只有一个 HTML 块被发送给浏览者]]></description>
		</item>
		
			<item>
			<link>http://www.ruery.net/article/Program/1664.htm</link>
			<title><![CDATA[利用xmlhttp分块上传文件]]></title>
			<author>admin@ruery.com(Ruery)</author>
			<category><![CDATA[程序设计]]></category>
			<pubDate>Sun,05 Aug 2007 03:13:05 +0800</pubDate>
			<guid>http://www.ruery.net/default.asp?id=1664</guid>
		<description><![CDATA[作者：tzboy　来自：蓝色理想 <br/><br/>编写思路:把本地文件在客户端通过base64编码以后发送目的地.<br/>测试过程中,上传文件过大,导致超时不成功.<br/>后来经过改善.把编码分段发送.测试20M成功<br/><br/>编写目的:在传统的解决方案里面,一次一次选取上传可以.但是在碰到把数据库里文件路径读出来,并把这些文件上传到一个地方的时候就比较麻烦.<br/>如果得到路径一个一个去找到用ftp当然也是可以的,但每次找这些文件我看都会比较费时。这里编写这个主要就是为了通过数据库里的文件路径取得文件.把文件一次批量上传到一个地方.<br/>其主要目的还是为了锻炼一下自己. <br/><br/>解决过程:起初试着用模拟键盘输入强行赋值给file控件用传统的方法上传。可是老碰到空值的情况，以至有很多文件没有发送出去。查阅一些资料,现在是把所有路径通过数据库取到然后写到一个js里。然后在前台用js读取这些路径,通过xmlhttp来发送文件。<br/>因为ie不太喜欢xmlHttp.总认为他有恶意行为.所以老谈出提示警告.所以操作的时候不能使用web路径.只能用物理路径去访问它.<br/>然后服务端有一文件来接收这些编码,并对其进行解码.所以我称之为&#34;c/s&#34;. ^_^<br/><br/>目前很多代码还在完善中.<br/>简单介绍一下:<br/><br/>aryFiles.push(&#34;c:\\aaa.zip&#34;) ;<br/>aryFiles.push(&#34;c:\\bbb.exe&#34;) ;<br/>这里为文件路径和文件.可为多个<br/>以后这个路径也可以通过file控件在客户端取到<br/><br/><a href="http://" target="_blank" rel="external">http://</a> www.xxx.com/xxx/xxx.asp<br/>这个是目的地,可以改为自己想要的地址.<br/><br/>ado_stream.LoadFromFile(server.mappath(&#34;.&#34;) &amp;&#34;/&#34;&amp; + str_filename) <br/>server.mappath(&#34;.&#34;) &amp;&#34;/&#34;&amp; + str_filename 这里是读取文件.<br/>server.mappath(&#34;.&#34;) &amp;&#34;/&#34;&amp; 路径和存放路径一致<br/><br/>ado_stream.SaveToFile server.mappath(&#34;.&#34;) &amp;&#34;/&#34;&amp; str_filename,2 <br/>server.mappath(&#34;.&#34;) &amp;&#34;/&#34;&amp; 这个为存放文件的路径. str_filename 为文件名<br/><br/><br/>这里读取和存放都是放在程序所放目录中.大家测试的时候也可以保持这样即可<br/><br/>把第一段代码放到本地(eg:c:\upload.htm)<br/><br/>把第二段代码放到服务器上,可以是本地服务器,可以是公网服务器.和上面的目的地保持一致<br/>(eg:<a href="http://www.xxx.com/upload.asp" target="_blank" rel="external">http://www.xxx.com/upload.asp</a> o&#114; <a href="http://" target="_blank" rel="external">http://</a> localhost/www/upload.asp)<br/><br/><br/>操作:找到第一段代码保存的地方。执行即可(eg:打开c盘执行upload.htm)<br/><br/>目前程序还在调试过程中,希望大家提出宝贵意见<br/>客户端代码<br/><br/>&lt;html&gt;<br/>&lt;head&gt;<br/>&lt;/head&gt;<br/>&lt;body&gt; &lt;input type=button onclick=&#34;BeginSendFiles();&#34;<br/>value=&#34;发送&#34; /&gt; &lt;input type=button onclick=&#34;JavaScript:<br/>Breaked=true;&#34; value=&#34;中断&#34; /&gt; &lt;div id=&#34;ddd&#34;<br/>width=300px&gt;&lt;/div&gt; &lt;br&gt;&lt;/br&gt; &lt;DIV<br/>id=div_message&gt;&lt;/DIV&gt;<br/>&lt;/body&gt;<br/>&lt;script language=VBScript&gt; Function bytes2BSTR(vIn) strReturn =<br/>&#34;&#34; For i = 1 To LenB(vIn) ThisCharCode = AscB(MidB(vIn,i,1)) If<br/>ThisCharCode &lt; &amp;H80 Then strReturn = strReturn &amp;<br/>Chr(ThisCharCode) Else NextCharCode = AscB(MidB(vIn,i+1,1)) strReturn =<br/>strReturn &amp; Chr(CLng(ThisCharCode) * &amp;H100 +<br/>CInt(NextCharCode)) i = i + 1 End If Next bytes2BSTR = strReturn End<br/>Function<br/>&lt;/script&gt;<br/>&lt;script language=javascript&gt; var xmlhttp ; var ado_stream ; var<br/>mFileName, mPartStart, mPartID, mPartEnd ; var SendCount ; var<br/>BlockSize ; var Breaked ; var aryFiles ; BlockSize = 1024*100<br/>;//每次发送字节数 Breaked = false ; aryFiles = new Array() ; // 开始发送文件<br/>function BeginSendFiles() { initAryFiles() ; SendFile(aryFiles.pop()) ;<br/>} // 构造待发送文件的数组 function initAryFiles() { aryFiles.push(&#34;c:\\aaa.zip&#34;)<br/>; aryFiles.push(&#34;c:\\bbb.exe&#34;) ; //c:\\aaa.zip c:\\bbb.exe本地文件<br/>aryFiles.reverse() ;//文件名 } function SendFile(vFullPath) { // 空文件则不执行上传<br/>if (!vFullPath) { return ; } Breaked = false ; div_message.innerHTML =<br/>&#34;&#34; ; ado_stream = new ActiveXObject(&#34;ADODB.Stream&#34;); // 读取文件的流<br/>ado_stream.Type = 1; ado_stream.Open();<br/>ado_stream.LoadFromFile(vFullPath); // 读取文件 ado_stream.position = 0 ;<br/>SendCount = Math.ceil(ado_stream.size/BlockSize) ; // 如果有余数则多发送一次 //<br/>alert(SendCount) ; var reg = /\b\w+.\w+$/gi mFileName =<br/>reg.exec(vFullPath) ; mPartStart = true ; mPartID = 1 ; mPartEnd =<br/>false ; SendData() ; } function SendData() { if (SendCount &gt; 0) {<br/>var dom = new ActiveXObject(&#34;msxml2.DOMDocument&#34;); // 发送的xml文件<br/>dom.async = false; dom.resolveExternals = false; // 构造xml文件头 var node =<br/>dom.cr&#101;ateProcessingInstruction(&#34;xml&#34;,&#34;version=&#39;1.0&#39;&#34;);<br/>dom.appendChild(node) ; node = null ; // 构造root节点 var root =<br/>dom.cr&#101;ateElement(&#34;root&#34;); dom.appendChild(root) ;<br/>dom.documentElement.setAttribute(&#34;xmlns:dt&#34;,<br/>&#34;urn:schemas-microsoft-com:datatypes&#34;); // 构造保存二进制数据的节点updata node =<br/>dom.cr&#101;ateElement(&#34;upData&#34;) ; node.dataType = &#34;bin.base64&#34; ; //<br/>bin。base64编码 var att = dom.cr&#101;ateAttribute(&#34;FileName&#34;) ; // 文件名属性<br/>att.value = mFileName ; node.setAttributeNode(att) ; att = null ; var<br/>att = dom.cr&#101;ateAttribute(&#34;PartStart&#34;) ; // 分段开始标记 att.value =<br/>mPartStart ; node.setAttributeNode(att) ; att = null ; var att =<br/>dom.cr&#101;ateAttribute(&#34;PartID&#34;) ; // 分段序号 att.value = mPartID ;<br/>node.setAttributeNode(att) ; att = null ; var att =<br/>dom.cr&#101;ateAttribute(&#34;PartEnd&#34;) ; // 分段结束标记 att.value = mPartEnd ;<br/>node.setAttributeNode(att) ; att = null ; root.appendChild(node) ;<br/>node.nodeTypedValue = ado_stream.Read(BlockSize); // 节点数据从stream读取，固定长度<br/>node = null ; SendCount -= 1 ; xmlhttp = new<br/>ActiveXObject(&#34;Microsoft.XMLHTTP&#34;);<br/>xmlhttp.open(&#34;POST&#34;,&#34;<a href="http://www.xxx.com/xxx/xxx.asp" target="_blank" rel="external">http://www.xxx.com/xxx/xxx.asp</a>&#34;, false);<br/>//<a href="http://www.xxx.com/xxx/xxx.asp" target="_blank" rel="external">http://www.xxx.com/xxx/xxx.asp</a> 为web路径上的文件 xmlhttp.onreadystatechange=<br/>CallBack ; xmlhttp.send(dom); mPartStart = false ; xmlhttp = null ; }<br/>else { ado_stream.Close(); ado_stream = null ; } } function CallBack()<br/>{ // 上传成功 if(xmlhttp.readystate == 4) { // 检查是否中断上传 if(Breaked) {<br/>return ; } if (SendCount &gt; 0) { mPartID += 1 ; //<br/>div_message.innerHTML += (&#34;&lt;br&gt;&#34; + xmlhttp.ResponseText) ; var p<br/>= Math.floor((mPartID/(Math.ceil(ado_stream.size/BlockSize) + 1)) *<br/>100) ; // 计算进度百分比 ShowBar(p) ; var t = setTimeout(&#34;SendData();&#34;, 1) ; }<br/>else { // 传送完文件 //div_message.innerHTML += mFileName +<br/>&#34;传送完毕！&lt;br&gt;&#34; ; // 继续传下一文件 ShowBar(0) ; var cFile = aryFiles.pop()<br/>; SendFile(cFile) ; } } } function ShowBar(per) { // 进度条 ddd.innerHTML<br/>= &#34;&lt;table width=&#39;200&#39; border=0 cellpadding=&#39;0&#39; cellspacing=&#39;0&#39;<br/>&gt;&lt;tr&gt;&lt;td bgcolor=&#39;#6699FF&#39;&gt;&lt;input type=button style=&#39;<br/>width:&#34; + per + &#34;% ; border:0px; background:#005599; color:#FFFFFF&#39;<br/>value=&#34; + per + &#34;%&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#34; ; }<br/>&lt;/script&gt;<br/>&lt;/html&gt;<br/><br/>服务端代码<br/><br/>&lt;%@ LANGUAGE=VBScript%&gt; <br/>&lt;% Option Explicit <br/>Response.Expires = 0&nbsp;&nbsp;<br/><br/>&#39; 定义变量和对象。 <br/>dim ado_stream <br/>dim xml_dom <br/>dim xml_data <br/>dim str_filename<br/>dim bol_PartStart<br/>dim int_PartID<br/>dim bol_PartEnd <br/><br/>&#39; 创建 Stream 对象 <br/>set ado_stream = Server.Cr&#101;ateObject(&#34;ADODB.Stream&#34;) <br/>&#39; 从Request对象创建 XMLDOM对象 <br/>set xml_dom = Server.Cr&#101;ateObject(&#34;MSXML2.DOMDocument&#34;) <br/>xml_dom.load(request) <br/>&#39; 读出包含二进制数据的节点 <br/>set xml_data = xml_dom.sel&#101;ctSingleNode(&#34;root/upData&#34;) <br/>str_filename = xml_data.getAttribute(&#34;FileName&#34;)<br/>bol_PartStart = CBool(xml_data.getAttribute(&#34;PartStart&#34;))<br/>int_PartID = CInt(xml_data.getAttribute(&#34;PartID&#34;))<br/>bol_PartEnd = CBool(xml_data.getAttribute(&#34;PartEnd&#34;))<br/><br/>&#39; 打开Stream对象，把数据存入其中&nbsp;&nbsp;<br/>ado_stream.Type = 1 &#39; 1=adTypeBinary&nbsp;&nbsp;<br/>ado_stream.open&nbsp;&nbsp;<br/>if not bol_PartStart then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ado_stream.LoadFromFile(server.mappath(&#34;.&#34;) &amp;&#34;/&#34;&amp; + str_filename)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39; 读取文件<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ado_stream.position = ado_stream.size <br/>end if<br/>ado_stream.Write xml_data.nodeTypedValue <br/>&#39; 文件存盘 <br/>ado_stream.SaveToFile server.mappath(&#34;.&#34;) &amp;&#34;/&#34;&amp; str_filename,2 <br/>&#39;保存文件 2=adSaveCr&#101;ateOverWrite&nbsp;&nbsp;<br/>ado_stream.close <br/><br/>&#39; 释放资源 <br/>set ado_stream = Nothing&nbsp;&nbsp;<br/>set xml_dom = Nothing <br/>&#39; 向浏览器返回信息 <br/>Response.Write &#34;Upload successful!&#34;&amp; str_filename &amp; int_PartID &amp; bol_PartStart<br/>%&gt; <br/><br/>另外：此文的目的并不是说这个程序能给朋友们解决什么问题，主要目的还是为了和大家交流一些心得：<br/>碰到问题-&gt;发现问题-&gt;解决问题.<br/>希望大家都不要成为一个标准的代码机器人。<br/>多学、多看、多思考、多实践。<br/>没有什么是不能解决的。 ]]></description>
		</item>
		
</channel>
</rss>
