2006年11月23日

这年头很多女演员为了上戏,都和导演睡觉。娱乐圈“性丑闻”似乎也早就不是新鲜事,而张钰事件更是将这种“潜规则”展现在大众面前。金钱与肉体的交换,名与利的追逐,在这个圈子里真的那样赤裸裸吗?繁华热闹的“艺术”背后,到底藏了多少不可见人的肮脏呢…...[

见怪不怪!

黄健翔辞职相当与地震了。这两天各种消息很多,可真正原因是啥?为了让朋友看清来龙去脉,笔者费好大劲搜索以下东西,慢慢看吧,呵呵。从黄健翔写给领导的解释文字里看,这封信是S某执笔。刊登如下,同时也找到黄健翔逐一回驳的原始文字。以下文字谢绝一切媒体转载,否则将追究转载者责任并文责自负。谢谢合作。
 

关于黄健翔同志的情况说明及意见

 

J主任并有关领导:

体育频道评论员黄健翔同志近期内,违反台播音员主持人相关管理规定,频繁参加各类社会活动。按照台里及频道的相关规定,台里的主持人在参加与台里无关的社会活动之前必须向相关部门申报,得到批准后方可参加,而黄健翔同志则未能执行台里的社会活动报批程序,在一定范围内造成了不良影响。现将黄健翔同志近期内未经批准参加的社会活动呈报如下:

1、        2006年8月开始,参加《时尚》杂志“时尚先生”的评选活动并出席相关仪式。

2、        2006年10月,与TOM网站合作,组织“黄健翔进校园系列活动”,并于10月18日在清华大学进行了演讲。据统计,这是TOM网与黄健翔合作以来的第六期走进高校演讲活动。此项活动现仍在持续。

3、        2006年10月29日,出席第15届金鸡百花电影节并担任主持人。

4、        据《北京电视报》报道,本周四,即2006年11月2日,黄健翔还将参加由郭德刚担纲的德云社十周年庆典活动。报道中还称:届时,黄健翔将与足球记者董路合说一段相声。

 

黄健翔同志在参加上述活动的时候未和台里、频道以及播音组内的任何负责人通报,严重违反了台内的相关规定。不仅如此,为了参加上述活动,黄健翔同志以自己有事为由,要求安排值班的编辑将自己负责的节目取消由他人代替,导致2006年10月28日(周六)及29日(周日)夜间原本应由黄健翔同志负责解说的两场2006-2007赛季德国足球甲级联赛的直播,也由段暄同志临时代替。

黄健翔同志在2006年世界杯期间犯下了严重错误,世界杯之后,在台里、频道和其他相关领导的批评、教育和帮助下做出了深刻检查。因此,本着惩前毖后、治病救人的方针,台里、频道和相关部门给予了黄健翔改正错误、在原来的岗位上继续工作的机会。但是,现在看来,当时黄健翔同志的检查虽然深刻,仍然只是停留在了书面上,并未在思想上引起足够的重视。在黄健翔同志的内心深处,对于自己职位和责任的定位仍然不够清晰,因此,黄健翔同志才会在近期屡犯不止、明知故犯。另外,自体育中心改制成立播音组以来,播音组为强化管理,制定了很多相关的条例和细则,并多次召开会议,讨论、贯彻和传达。黄健翔同志则多次以有事为由请假,所有组内召开的会议仅仅参加过一次。

鉴于上述情况,我们认为,黄健翔同志的种种行为是一种无组织、无纪律的表现,但是,黄健翔同志本人并没有认识到这一点,思想上还存在着潜在的不良情绪,随时有再次犯下更为严重错误的可能,这样发展下去,将为台里和频道带来不可预料的严重后果,同时也为组内强化制度、强化管理带来了很大的压力。黄健翔同志的行为给许多年轻人带来了负面的不良影响,不利于组内良好风气的形成,更不利于队伍的建设和对年轻人的正面引导。

经过台里和中心的多年培养,黄健翔同志在社会上已经具有了一定的知名度,他的一举一动将直接影响到频道声誉和中央电视台的对外形象。因此,更应该加强对于黄健翔同志的管理和教育和处理。

鉴于上述情况,我们提请相关领导按照台播音员、主持人管理办法,对黄健翔同志所犯错误进行严肃处理,以警本人并对整个队伍建设提供良好氛围。

以上是体育频道编辑部对于黄健翔同志近期行为的呈报和相关

处理意见。

妥否,请批示。

 

 

                                  体育频道XXX

                                 2006年10月30日

~~~~~~~~~~~~~~~~~~~~~~~~

近期准备做全国各个城市生活/工作/娱乐的工具条,收集每个城市的信息于一身, 方便各地网民使用,绝对绿色软件,不带任何流氓性质,感兴趣的敬请关注, ^_^

IE 秀服务

www.ieshow.net

 

2006年11月13日

方法论对软件开发而言意味着什么?我们如何看待软件开发中的方法论?方法论能够成为软件开发的救命稻草吗?在读过此文后,这些疑惑就会得到解答。

在第一篇文章中,我们来了解标题中的一些词的含义。

  • 方法学是什么?
  • 敏捷是什么?
  • 为什么讨论架构?

方法论

方法论的英文为Methodology,词典中的解释为"A series of related methods or techniques"我们可以把它定义为软件开发(针对软件开发)的一整套方法、过程、规则、实践、技术。关于方法论的出现的问题,我很赞同Alistair Cockburn的一句话,"方法论源于恐惧。"出于对项目的超期、成本失控等等因素的恐惧,项目经理们从以前的经验出发,制定出了一些控制、监测项目的方法、技巧。这就是方法论产生的原因。

Agile Software Development一书中,作者提到了方法论的十三个要素,基本能够函盖方法论的各个方面:

  • 角色(Roles
  • 个性(Personality
  • 技能(Skills
  • 团队(Teams
  • 技术(Techniques
  • 活动(Activities
  • 过程(Process
  • 工件(Work products
  • 里程碑(Milestones
  • 标准(Standards
  • 质量(Quality
  • 工具(Tools
  • 团队价值(Team Values

它们之间的关系可以用一幅图来表示:

1. 方法论的十三个要素

很多的方法论,都涉及了上面列举的十三要素中的部分要素,因此,我们可以把方法论看作是一个抽象的、无穷的超集,而现实中的方法论都是指超集的一个有限的子集而已。它们之间的关系就好像有理数和1到100之间的整数的关系一样。不论是XP,还是UI设计经验之类,都属于方法论的一个子集,只是这两个子集之间有大小的差别而已。我们还应该看到,讨论一个完备的方法论是没有意义的,因此这种方法论铁定不存在,就好像你视图穷举出所有的有理数一样荒唐。因此,我们关于一个通用的方法论的说法也是无意义的。好的方法论,比如说XP、水晶系列,它们都有一个适合的范围,因为它们了解一点,自己并不是一个无所不能的方法论。

在现实中,我们其实不断的在接触方法论。比如说,为了控制项目的进度,项目经理要求所有的开发人员每周递交一份详细的进度报告,这就是一种方法、一种技巧。如果把开发过程中的这些技巧系统的组织起来,就能够成为一种方法论。你可能会说,那一种方法论的产生也太容易了吧。不,这样产生的方法论并没有太大的实用价值,没有实用价值的方法论根本就没有存在的必要。因此,一个成功的方法论是要能够为多个的项目所接受,并且能够成功实现软件的交付的方法论。

我和我的同事在实践中做了一些试验,希望能够把一些好的方法论应用于开发团队。试验的结果很无奈,方法论实施的效果并不理想,一开始我们认为是方法本身的原因,到后来,我们发现事情并不是这么简单。在试验的过程中,开发人员一致认同方法论的优势所在,但是在实施过程中,鲜有坚持的下来的。在Agile Software Development中,我发现作者遇到了和我们一样的问题。

Alistair Cockburn在和大量的项目团队的访谈之后,写成了Agile Software Development一书。在访谈之前,他笃定自己将会发现高度精确的过程控制是成功的关键所在,结果他发现事实并非如此,他把他的发现归结为7条定律。而我在实际中的发现也包含在这七条定律中,总结起来就只有两点:沟通和反馈。

只要能够保证良好的沟通和即时的反馈,那么开发团队即使并没有采用先进的方法论,一样可以成功。相反,那些"高质量"的团队却往往由于缺乏这两个因素而导致失败(我们这里指的失败是用户拒绝使用最终的软件)。最有效,而成本也最低的沟通方法就是面对面(face to face)的沟通,而随着项目团队的变大,或是另外一些影响因素的加入(比如地理位置的隔绝),面对面的沟通越来越难实现,这导致沟通的的成本逐渐加大,质量也慢慢下降。但这并不是说非面对面的沟通不可,重要的是我们需要知道不同的沟通方式的成本和质量并不相同。XP方法尤为强调面对面的沟通,通过现场客户、站立会议、结对编程等方式来保证沟通的有效。在我的经验中,一个开发团队其实是需要多种沟通方式的结合的。完全的面对面的沟通对某些团队来说是很难实现的,那么问题的关键就在于你如何应用沟通的方式来达到你希望的效果。在前不久结束的欧莱雅创业计划大赛上,有一支团队特别引人注目,他们彼此间素未谋面,仅仅凭借Internet和电话完成了高效的合作。他们虽然没有使用面对面的沟通方式,但是仍然达成了既定的目标。软件开发也是一样的,面对面的沟通是非常有必要的,但其它的沟通方式也是需要的。

再看反馈,不论是控制进度,还是保证客户的满意度,这些活动都需要管理成本。软件开发中的管理成本的一个通性就是伴随有中间产出物(intermediate delivery)。比如说我们的需求规约、分析文档、设计文档、测试计划,这些都属于中间产出物。中间产出物的增加将会带来效率下降的问题,因为开发人员的时间都花在了完成中间产出物的工作上,花在给软件新功能上的时间就减少了。而中间产出物的主要目的是两个,一个是为了保证软件如客户所愿,例如需求规约;另一个是为了作为团队中的其他成员工作的输入,例如开发计划、测试计划等。因此,我们也可以针对这两点来商讨对策,一种是采用迭代的思想,提高软件发布的频率,以保证客户的需求被确实的满足,另一种就是缩小团队的沟通范围,保证成员能够从其他人那里得到新的思路,而不是撰写规范的内部文档(内部文档指那些仅为内部开发人员之间的沟通所需要的文档)。

因此,一个软件项目的成功和你采用的开发方法论并没有直接的关系。

重量
我们根据把拥有大量artifact(RUP官方翻译为工件,意思是软件开发过程中的中间产物,如需求规约、设计模型等)和复杂控制的软件开发方法称为重型(Heavy Weight)方法,相对的,我们称artifact较少的方法为轻型(Light Weight)方法。在传统的观念中,我们认为重型方法要比轻型安全许多。因为我们之所以想出重型方法,就是由于在中大型的项目中,项目经理往往远离代码,他无法有效的了解目前的工程的进度、质量、成本等因素。为了克服未知的恐惧感,项目经理制定了大量的中间管理方法,希望能够控制整个项目,最典型的莫过于要求开发人员频繁的递交各种表示项目目前状态的报告。

Planning XP一书中有一段讨论轻重型方法论的精辟论述,它把重型方法论归结为一种防御性的姿态(defensive posture),而把轻型方法论归结为一种渴望成功(Plan to win)的心态。如果你是采用了防御性姿态,那么你的工作就集中在防止和跟踪错误上,大量的工作流程的制定,是为了保证项目不犯错误,而不是项目成功。而这种方法也不可谓不好,但前提是如果整个团队能够满足前面所提到的两个条件的话,项目也肯定会成功,但是重型方法论的一个弊端就在于,大家都在防止错误,都在惧怕错误,因此人和人之间的关系是很微妙的,要达到充分的沟通也是很难的。最终,连对人的评价也变成是以避免错误的多寡作为考评的依据,而不是成就。我们在做试验的时候,一位项目经理开玩笑说,"方法论源自项目经理的恐惧,这没错。但最糟糕的是整个团队只有项目经理一个人恐惧,如果能够做到人人的恐惧,那大家也就没有什么好恐惧的了。"这句话提醒了我们,如果一个团队的精神就是力求成功,那么这支团队的心态就和其它的团队不同了,尤其是对待错误的心态上。根本就没有必要花费大量的精力来预防错误,错误犯了就犯了,即时改正就可以了。这其实就是渴望成功的心态。

方法论的艺术
管理,被称为科学和艺术的融合体,而管理的艺术性部分很大程度的体现为人的管理上。我说,方法学,一样是科学和艺术的融合体。这是有依据的,其实方法论和管理学是近亲关系,管理学中有一门分支是项目管理,而在软件组织中,项目管理是非常重要的,方法学就是一种针对软件开发的一种特定的项目管理(或是项目管理的一个子集)。

重型方法最大的一个问题就在于他不清楚或忽略了艺术这个层次,忽视了人的因素,把人做为一个计量单位,一种资源,一种线性元素。而人的要素在软件开发中是非常重要的,软件开发实际上是一种知识、智力的转移过程,最终形成的产品是一种知识产品,它的成本取决于开发者的知识价值,因此,人是最重要的因素。而人这个要素是很难衡量的,每个人都有不同的个性、想法、经验、经历,这么多复杂的因素加在一起,就导致了人的不可预见性。因此,我们强调管人的艺术。

最简单的例子是,在重型方法中,我们的基本假设是对人的不信任。项目经理要控制项目。但不信任就会产生很多的问题,比如士气不高,计划赶不上变化,创新能力低下,跳槽率升高等等。人都是希望被尊重的,技术人员更看重这一点,而很多公司也口口声声说自己多么多么以人为本,可是采用的却是以不信任人为前提的开发方法,言行不一。我们说敏捷方法的出发点是相互信任,做到这一点是很难的,但是一旦做到了,那这个团队就是非常具有竞争力的。因此,这就产生了一个问题,在没有做到完全的相互信任之前,我们到底相不相信他人呢,这就是我提到的艺术性的问题,什么时候你要相信人?什么时候你不相信人,这些都是需要权衡的问题,也都是表现你艺术性的问题。

1 背景
1.1 作者URL
http://spaces.msn.com/members/sharklee/?partqs=cat%3D%25e8%25ae%25a1%25e7%25ae%2597%25e6%259c%25ba%25e4%25b8%258e+Internet&_c11_blogpart_blogpart=blogview&_c=blogpart

2 gsoap文档翻译计划
2.1 gsoap文档翻译计划(序)
 
前一阵子需要在unix c平台下创建一个webservice应用。头痛之余,上网查询相关资料,偶然发现了gsoap开发包。于是乎立即下载试用了一下,效果很好。在它的帮助下,我很快完成了webservice应用的设计开发工作。

今天,心里突然升起一个念头:为何不把整个gsoap的帮助文档翻译一下呢?一来可以方便与其他同仁的交流;二来也可以更好的理解gsoap的原理与思想。只是此项工程工作浩繁,须怀有革命的大无畏精神尚可完成也。

如今唯先写一序,实则有督促之意耳。

2.2 gsoap文档翻译计划(1、介绍)
 
1.介绍
 gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关的类库。与之相反,gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。gSOAP的编译器能够自动的将用户定义的本地化的C或C++数据类型转变为符合XML语法的数据结构,反之亦然。这样,只用一组简单的API就将用户从SOAP细节实现工作中解脱了出来,可以专注与应用程序逻辑的实现工作了。gSOAP编译器可以集成C/C++和Fortran代码(通过一个Fortran到C的接口),嵌入式系统,其他SOAP程序提供的实时软件的资源和信息;可以跨越多个操作系统,语言环境以及在防火墙后的不同组织。
 gSOAP使编写web服务的工作最小化了。gSOAP编译器生成SOAP的代码来序列化或反序列化C/C++的数据结构。gSOAP包含一个WSDL生成器,用它来为你的web服务生成web服务的解释。gSOAP的解释器及导入器可以使用户不需要分析web服务的细节就可以实现一个客户端或服务端程序。
 下面是gSOAP的一些特点:
 ×gSOAP编译器可以根据用户定义的C和C++数据结构自动生成符合SOAP的实例化代码。
 ×gSOAP支持WSDL 1.1, SOAP 1.1, SOAP 1.2, SOAP RPC 编码方式以及 literal/document 方式.
 ×gSOAP是少数完全支持SOAP1.1 RPC编码功能的工具包,包括多维数组及动态类型。比如,一个包含一个基类参数的远程方法可以接收客户端传来的子类实例。子类实例通过动态绑定技术来保持一致性。
 ×gSOAP 支持 MIME (SwA) 和 DIME 附件包。
 ×gSOAP是唯一支持DIME附件传输的工具包。它允许你在保证XML可用性的同时能够以最快的方式(流方式)传递近乎无大小限制的二进制数据。
 ×gSOAP 支持 SOAP-over-UDP。
 ×gSOAP 支持 IPv4 and IPv6.
 ×gSOAP 支持 Zlib deflate and gzip compression (for HTTP, TCP/IP, and XML file storage)。
 ×gSOAP 支持 SSL (HTTPS)。
 ×gSOAP 支持 HTTP/1.0, HTTP/1.1 保持连接, 分块传输及基本验证。
 ×gSOAP 支持 SOAP 单向消息。
 ×gSOAP 包含一个 WSDL 生成器,便于web服务的发布。
 ×gSOAP 包含一个WSDL解析器 (将WSDL转换为gSOAP头文件),可以自动化用户客户端及服务端的开发。
 ×生成可以单独运行的web服务及客户端程序。
 ×因为只需要很少内存空间,所以可以运行在类似Palm OS, Symbian, Pocket PC的小型设备中。
 ×适用于以C或C++开发的web服务中。
 ×跨平台:Windows, Unix, Linux, Mac OS X, Pocket PC, Palm OS, Symbian等。
 ×支持序列化程序中的本地化C/C++数据结构。
 ×可以使用输入和输出缓冲区来提高效率,但是不用完全消息缓冲来确定HTTP消息的长度。取而代之的是一个三相序列化方法。这样,像64位编码的图像就可以在小内存设备(如PDA)中以DIME附件或其他方式传输。
 ×支持C++单继承,动态绑定,重载,指针结构(列表、树、图、循环图,定长数组,动态数组,枚举,64位2进制编码及16进制编码)。
 ×不需要重写现有的C/C++应用。但是,不能用unions,指针和空指针来作为远程方法调用参数的数据结构中元素。
 ×三相编组:1)分析指针,引用,循环数据结构;2)确定HTTP消息长度;3)将数据序列化位SOAP1.1编码方式或用户定义的数据编码方式。
 ×双相编组:1)SOAP解释及编码;2)分解“forward”指针(例如:分解SOAP中的href属性)。
 ×完整可定制的SOAP错误处理机制。
 ×可定制的SOAP消息头处理机制,可以用来保持状态信息

2.3 gsoap文档翻译计划(2、符号规定)
 
懒得翻译了,因为也不能再现出原来的版式。后面章节中分别注明吧,

2.4 gsoap文档翻译计划(3)
 
3. gSoap2.5版与gSOAP 2.4版(或以前版本)的不同
 按照WS-I Basic Profile 1.0a的要求,gSOAP2.5及以上版本默认使用SOAP RPC文字。这不需要去关心,因为WSDL解析器wsdl2h在你提供一个WSDL文档时,会自动注意这些不同点。增加了一个soapcpp2编译器的编译选项 -e ,用来保持与gSOAP2.4及以前版本的兼容性。

2.5 gsoap文档翻译计划(4)
 
4  gSoap2.2版与gSOAP 2.1版(或以前版本)的不同
 如果你是从2.1版升级到2.2或以后版本,请注意这些变化。
 为了能够分离传输、内容编码、映射中的接收/发送设置,改变了运行时选项及标志。这些标志分布再四个类中:传输(IO),内容编码(ENC),XML编组(XML)及C/C++数据映射。不再提倡使用旧标志soap_disable_X及soap_enable_X(其中,X表示选项名)。具体内容请参见9.12节。

2.6 gsoap文档翻译计划(5)
 
5. gSoap2.x版与gSOAP 1.x版的不同
 如果你是从1.x版升级到2.x版,请注意下面的内容。
 gSOAP2.0及之后的版本是在1.x版基础上重写的。gSOAP2.0之后的版本是线程安全的,但之前版本不是。gSOAP2.x版本中的主要文件已经重新命名,以便与1.x版区分。

gSOAP 1.X  gSOAP 2.X 
soapcpp  soapcpp2 
soapcpp.exe  soapcpp2.exe 
stdsoap.h  stdsoap2.h 
stdsoap.c  stdsoap2.c 
stdsoap.cpp  stdsoap2.cpp 
 
 从1.x版升级到2.x版并不需要进行大量的代码重写工作。所有2.x版相关的函数都定义在stdsoap2.c[pp]文件中,这个文件是由gSOAP编译器自动生成的。所以,用1.x版开发的服务端或客户端代码需要进行修改以适应2.x版中函数的变化:在2.x版中,所有的gSOAP函数都增加了一个参数用来保存一个gSOAP运行环境实例。这个参数包括了文件描述,表,缓冲,标志位等,它在所有gSOAP函数中都是第一个参数。
 gSOAP运行环境实例是一个struct soap类型的变量。当客户端程序访问远程方法前或当服务端程序能够接收一个请求前,必须先将这个运行环境变量初始化。在2.x版中新增了3个函数来负责这些事情:
 函数                        解释
 soap_init(struct soap *soap)         初始化环境变量(只需执行一次)
 struct soap *soap_new()            定义并初始化环境变量并返回一个该变量的指针
 struct soap *soap_copy(struct soap *soap)   定义一个环境变量并从已有的环境变量中拷贝环境信息
 
  环境变量定义好后就可以重复使用而不必再次初始化了。只有当线程独占访问时,我们才需要一个新的环境变量。例如,下面的代码分配了一个用于多个远程方法的环境变量:
 int main()
{
   struct soap soap;
   …
   soap_init(&soap); // 初始化环境变量
   …
   soap_call_ns__method1(&soap, …); // 调用一个远程方法
   …
   soap_call_ns__method2(&soap, …); // 调用另一个远程方法
   …
   soap_end(&soap); // 清除环境变量
   …
}
 我们也可以像下面这样定义环境变量:
 int main()
{
   struct soap *soap;
   …
   soap = soap_new(); // 定义并初始化环境变量
   if (!soap) // 如果不能定义,退出
   …
   soap_call_ns__method1(soap, …); // 调用远程函数
   …
   soap_call_ns__method2(soap, …); // 调用另一个远程函数
   …
   soap_end(soap); // 清除环境变量
   …
   free(soap); // 释放环境变量空间
}
 
 服务端代码在调用soap_serve函数前,需要定义相关环境变量:

int main()
{
   struct soap soap;
   soap_init(&soap);
   soap_serve(&soap);

 或者像下面这样:

int main()
{
   soap_serve(soap_new());

 soap_serve函数用来处理一个或多个(当允许HTTP keep-alive时,参见18.11节中的SOAP_IO_KEEPALIVE标志)请求。
 一个web服务可以用多线程技术来处理请求:
int main()
{
   struct soap soap1, soap2;
   pthread_t tid;
   …
   soap_init(&soap1);
   if (soap_bind(&soap1, host, port, backlog) < 0) exit(1);
   if (soap_accept(&soap1) < 0) exit(1);
   pthread_create(&tid, NULL, (void*(*)(void*))soap_serve, (void*)&soap1);
   …
   soap_init(&soap2);
   soap_call_ns__method(&soap2, …); // 调用远程方法
   …
   soap_end(&soap2);
   …
   pthread_join(tid, NULL); // 等待线程结束
   soap_end(&soap1); // 释放环境变量

 在上面的例子中,需要两个环境变量信息。而在1.x版本中,由于静态分配环境变量,多线程技术是不被允许的(只有一个线程可以用这个环境变量调用远程方法或处理请求信息)。
 8.2.4节将给出一个具体的多线程服务实例,它为每个SOAP请求分配一个独立线程进行处理。
2.7 gsoap文档翻译计划(6)
 
gSOAP 使用下面的软件包验证了其可用性: Apache 2.2 Apache Axis ASP.NET Cape Connect Delphi easySOAP++ eSOAP Frontier GLUE Iona XMLBus kSOAP MS SOAP Phalanx SIM SOAP::Lite SOAP4R Spray SQLData Wasp Adv. Wasp C++ White Mesa xSOAP ZSI 4S4C

2.8 gsoap文档翻译计划(7)
 
7  准备工作

 要开始用gSOAP创建一个web服务应用, 你需要:

 一个C/C++编译器.
 拥有根据操作系统平台创建的可执行的gSOAP的stdsoap2(windows下为stdsoap2.exe)编译器。
 拥有根据操作系统平台创建的可执行的gSOAP的wsdl2h(windows下为wsdl2h.exe)WSDL解析器。
 需要’stdsoap2.c’或’stdsoap2.cpp’及’stdsoap2.h’文件来实现你的SOAP功能。你可以创建一个dll或动态库以便简化连接。
 如果你要支持SSL(HTTPS)及压缩的话,可以安装OpenSSL及Zlib库。
 gSOAP是独立开发包,不需要任何第三方的软件支持(除非你要用到OpenSSL及Zlib)。
 与平台无关的gSOAP版本需要你下面的工具编译’soapcpp2′及’wsdl2h’文件:
 一个C++编译器(用来编译’wsdl2h’WSDL解析器)。
 Bison 或 Yacc
 Flex 或 Lex
 推荐使用Bison及Flex。
 在软件包samples目录下有大量的开发实例。可以用’make’来编译这些例子。这些例子包含了gSOAP中的各个方面。其中,最简单的例子是 one-liners(samples/oneliners)。

2.9 gsoap文档翻译计划(8.1.1)
 
8  快速指南
 本指南旨在让你快速开始你的gSOAP开发之旅。阅读本节的内容,需要你对SOAP 1.1协议及C/C++语法有大体的了解。虽然使用gSOAP编译器可以直接用C/C++开始编写web服务及客户端程序而不需要了解SOAP协议的细节,但是由于我们在本节中使用了大量的实例来说明gSOAP与其他SOAP实现的连接及通讯,所以了解一些SOAP及WSDL协议也是必需的。
 
8.1 如何使用gSOAP编译环境来编译SOAP客户端程序
 通常,一个SOAP客户端应用的实现需要为每个客户端需要调用的远程方法提供一个存根例程(stub routine)。存根例程主要负责编码参数信息;将包含参数信息的调用请求发送给制定的SOAP服务;等待返回结果;将结果中的参数信息编码。客户端程序调用访问远程方法的存根例程就像调用本地方法一样。用C/C++手工别写一个存根例程是个十分痛苦的差使,尤其当远程方法的参数中包含特定的数据结构(如:记录、数组、图等)时。幸运的是,gSOAP包中的’wsdl2h’WSDL解析器和’soapcpp2’存根及架构编译器能够将web服务客户端及服务端的开发工作自动化。
 ’soapcpp2’存根及架构编译器是可以生成构建C++ SOAP客户端所需的C++源码的预编译器。该预编译器的输入参数是一个标准的C/C++头文件。这个头文件可以由WSDL解析器根据相关的WSDL文档自动生成。
 参见下面的命令:
 $ wsdl2h -o quote.h http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl
 上面的命令根据制定URL提供的WSDL文档生成一个C++语法结构的头文件。
 如果需要生成一个纯C的头文件,需要一下命令:
 $ wsdl2h -c -o quote.h http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl
 更多关于WSDL解析器及其选项的细节信息,请参见8.2.10节。
 执行上述命令后,quote.h文件就生成了。其中包含开发客户端或服务端程序的存根例程定义。SOAP服务远程方法以函数声明的方式在这个头文件中被定义。C/C++源代码的存根例程将通过预编译器自动实现。同时,每个远程方法的程序框架也被自动生成了,它可以用来建立SOAP服务端程序应用。
 SOAP服务的输入输出参数可以是简单的数据类型或复杂的数据结构,可以由WSDL解析器自动生成或手工定义。预编译器将自动生成序列化/反序列化这些数据的代码,以便存根例程可以将这些数据以XML的方式编码或解码。

8.1.1  例子
 XMethods Delayed Stock Quote 服务提供一个getQuote方法(由’wsdl2h’WSDL解析器生成的quote.h定义)。这个方法根据提供的股票名称返回相应的股票价格。下面是这个方法的WSDL文档信息:

Endpoint URL:  http://services.xmethods.net:80/soap 
SOAP action:  "" (2 quotes) 
Remote method namespace:  urn:xmethods-delayed-quotes 
Remote method name:  getQuote 
   Input parameter:  symbol of type xsd:string 
   Output parameter:  Result of type xsd:float 
 
 下面是由WSDL解析器生成的getQuote.h头文件(实际的文件内容与’wsdl2h’版本及生成选项有关):
//gsoap ns1 service name: net_DOTxmethods_DOTservices_DOTstockquote_DOTStockQuoteBinding
//gsoap ns1 service type: net_DOTxmethods_DOTservices_DOTstockquote_DOTStockQuotePortType
//gsoap ns1 service port: http://66.28.98.121:9090/soap
//gsoap ns1 service namespace: urn:xmethods-delayed-quotes
//gsoap ns1 service documentation: Definitions generated by the gSOAP WSDL parser 1.0
// Service net.xmethods.services.stockquote.StockQuoteService : net.xmethods.services.stockquote.StockQuote web service

//gsoap ns1 service method-style: getQuote rpc
//gsoap ns1 service method-encoding: getQuote http://schemas.xmlsoap.org/soap/encoding/
//gsoap ns1 service method-action: getQuote urn:xmethods-delayed-quotes#getQuote
int ns1__getQuote(char *symbol, float &Result);

 这个头文件用C/C++代码为gSOAP预编译器指定了web服务的细节。远程方法被定义为函数ns1__getQuote,同时指定了客户端调用web服务所需的所有细节信息。
 getQuote远程方法需要一个名为symbol的字符串作为输入参数,同时需要一个名为Result的浮点数作为输出参数。预编译器生成的远程方法调用函数中,最后一个参数必须是输出参数,该参数以引用方式传递或定义为指针类型。除此之外的所有参数都是输入参数,这些参数必须以传值方式传递。函数返回一个整型值,其值说明web服务调用成功或出现的错误。具体的错误代码信息参见10.2节。
 函数名中命名空间前缀ns1__的细节信息将在8.1.2节中讨论。简单的说,命名空间前缀与函数名之间用两个下划线分割。比如,ns1__getQuote中,ns1为命名空间前缀,getQuote是函数名称。(函数名中单个下划线将在XML中解释为破折号-,因为在XML中破折号比下划线更常用,细节请参见10.3节)
 用下面命令执行预编译器:
 
soapcpp2 getQuote.h 

 预编译器根据getQuote.h中定义的信息来生成存根例程的代码框架。这个存根例程可以在客户端程序中随处调用。存根例程被声明为下面的样子:

int soap_call_ns1__getQuote(struct soap *soap, char *URL, char *action, char *symbol, float &Result); 

 存根例程保存在soapClient.cpp文件中;soapC.cpp文件包含了序列化、反序列化数据的函数。你可以用 -c编译选项来生成纯C的代码。
 注意,soap_call_ns1__getQuote在ns1__getQuote的参数基础上又增加了三个参数:soap必须是指向一个gSOAP运行环境的合法指针;URL是web服务的URL;action指明了web服务需要的SOAP action。XMethods Delayed Stock Quote服务的URL是http://66.28.98.121:9090/soap,action是"" (2 quotes)。你可以动态的改变URL及action。如果上述两个变量定义为NULL,则会使用头文件中定义的信息。
 下面的例子调用远程方法获取IBM的股票信息:

#include "soapH.h" // 包含生成的存根例程定义
#include "net_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBinding.nsmap" // 包含命名空间表
int main()
{
   struct soap soap; // gSOAP运行环境
   float quote;
   soap_init(&soap); // 初始化运行环境(只执行一次)
   if (soap_call_ns1__getQuote(&soap, NULL, NULL, "IBM", &quote) == SOAP_OK)
      std::cout << "Current IBM Stock Quote = " << quote << std::endl;
   else // an error occurred
      soap_print_fault(&soap, stderr); // 在stderr中显示错误信息
   soap_destroy(&soap); // 删除类实例(仅用于C++中)
   soap_end(&soap); // 清除运行环境变量
   soap_done(&soap); // 卸载运行环境变量
   return 0;

 调用成功后,存根例程返回SOAP_OK同时quote变量保存着股票信息;如果调用失败则产生一个错误,同时通过soap_print_fault函数显示错误信息。
 gSOAP编译器同时为C++客户端程序生成了一个代理类。

#include "soapnet_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBindingProxy.h" // 获得代理
#include "net_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBinding.nsmap" // 包含命名空间表
int main()
{
   net q; // "net" 是这个服务代理类的短名称
   float r;
   if (q.ns1__getQuote("IBM", r) == SOAP_OK)
      std::cout << r << std::endl;
   else
      soap_print_fault(q.soap, stderr);
   return 0;

 代理类的构造函数定义并初始化了一个gSOAP环境变量实例。所有的HTTP及SOAP/XML处理被隐藏在后台处理。你可以改变WSDL解析器生成的头文件中web服务的名称。web服务的名字是由WSDL内容中萃取的,并不总是短名称格式的。你可以随意更改这个条目

//gsoap ns1 service name: net_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBinding 

来使用一个更合适的名字。这个名字将决定代理类文件及XML命名空间表文件的名字。
 下面的函数可以用来建立一个gSOAP运行环境(struct soap):
soap_init(struct soap *soap)  初始化运行环境变量(只需要执行一次)
soap_init1(struct soap *soap, soap_mode iomode)  初始化运行环境变量同时设置in/out模式
soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)  初始化运行环境变量同时分别设置in/out模式
struct soap *soap_new()  定义、初始化运行环境并返回一个执行运行环境的指针
struct soap *soap_new1(soap_mode iomode)  定义、初始化运行环境并返回一个执行运行环境的指针并设置in/out模式
struct soap *soap_new2(soap_mode imode, soap_mode omode)  定义、初始化运行环境并返回一个执行运行环境的指针并分别设置in/out模式
struct soap *soap_copy(struct soap *soap)  定义一个新的环境变量并将现有环境信息赋值给新的变量
soap_done(struct soap *soap)  重置、关闭连接,清除环境变量
 
 环境变量可以在程序中任意次数的使用。每个新的线程就需要一个新的环境变量实例。
 当例子中的客户端程序执行时,SOAP请求通过soap_call_ns1__getQuote函数来调用,它生成下面的SOAP RPC请求信息:
POST /soap HTTP/1.1
Host: services.xmethods.net
Content-Type: text/xml
Content-Length: 529
SOAPAction: ""

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:ns1="urn:xmethods-delayed-quotes"
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getQuote>
<symbol>IBM</symbol>
</ns1:getQuote>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> 

 XMethods Delayed Stock Quote 服务返回如下的信息:
HTTP/1.1 200 OK
Date: Sat, 25 Aug 2001 19:28:59 GMT
Content-Type: text/xml
Server: Electric/1.0
Connection: Keep-Alive
Content-Length: 491

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
   soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/?
<soap:Body>
<n:getQuoteResponse xmlns:n="urn:xmethods-delayed-quotes?
<Result xsi:type="xsd:float?41.81</Result>
</n:getQuoteResponse>
</soap:Body>
</soap:Envelope>

 服务返回的信息通过存根例程来解析,并保存在soap_call_ns1__getQuote函数的quote参数中。
 客户端程序可以在任意时间多次调用远程方法。请看下面的例子:


struct soap soap;
float quotes[3]; char *myportfolio[] = {"IBM", "MSDN"};
soap_init(&soap); // need to initialize only once
for (int i = 0; i < 3; i++)
   if (soap_call_ns1__getQuote(&soap, "http://services.xmethods.net:80/soap", "", myportfolio[i], &quotes[i]) != SOAP_OK)
      break;
if (soap.error) // an error occurred
   soap_print_fault(&soap, stderr);
soap_end(&soap); // clean up all deserialized data
… 

 这个客户端程序通过调用ns1__getQuote存根例程来为数组中的每个股票代码获得信息。
 上面的例子给我们示范了使用gSOAP创建一个SOAP客户端时多么容易的事情啊。
2.10 gSoap文档翻译计划(8.1.2~8.1.3)
 
8.1.2 关于命名空间
 函数ns1__getQuote(上节提到的)中,使用了ns1__作为远程方法的命名空间。使用命名空间是为了防止远程方法名冲突,比方多个服务中使用同一个远程方法名的情况。
 命名空间前缀及命名空间名称同时也被用来验证SOAP信息的内容有效性。存根例程通过命名空间表中的信息来验证服务返回信息。命名空间表在运行时被取出用于解析命名空间绑定,反序列化数据结构,解码并验证服务返回信息。命名空间表不应该包含在gSOAP预编译器所需输入的头文件中。在18.2节中将会对命名空间表做详细介绍。
 Delayed Stock Quote服务客户端的命名空间表如下:

struct Namespace namespaces[] =
{   // {"命名前缀", "空间名称"}
   {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"}, // 必须是第一行
   {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"}, // 必须是第二行
   {"xsi", "http://www.w3.org/2001/XMLSchema-instance"}, // 必须是第三行
   {"xsd", "http://www.w3.org/2001/XMLSchema"}, // 2001 XML 大纲
   {"ns1", "urn:xmethods-delayed-quotes"}, // 通过服务描述获取
   {NULL, NULL} // 结束
};

 第一行命名空间是SOAP1.1协议默认命名空间。事实上,命名空间表就是用来让程序员可以规定SOAP编码方式,能够用包含命名空间的命名空间前缀来满足指定SOAP服务的命名空间需求的。举例来说,使用前面命名空间表中定义的命名空间前缀ns1,存根例程就可以对getQuote方法的请求进行编码。这个过程由gSOAP预编译器通过在getQuote.h文件中定义的包含前缀ns1的ns1__getQuote函数自动完成。通常,如果要在远程方法名,结构名,类名,字段名等结构或类中使用命名空间前缀,就必须在命名空间表中进行定义。
 命名空间表将会被存根例程封装,并按下面的形式输出:


<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:ns1="urn:xmethods-delayed-quotes"
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
… 

 这个命名空间绑定将被SOAP服务用来验证SOAP请求。

8.1.3 例子
 使用命名空间前缀可以解决在不同的服务中使用相同名称的远程方法的问题,看下面的例子:

// Contents of file "getQuote.h":
int ns1__getQuote(char *symbol, float &Result);
int ns2__getQuote(char *ticker, char *&quote); 

 这个例子允许客户端程序使用不同的命名空间以便连接到不同的服务程序执行其中的远程方法。
 命名空间前缀也可以用在类声明中使用,在XML大纲中区分同名但不同命名空间的SOAP值。例如:

class e__Address // an electronic address
{
   char *email;
   char *url;
};
class s__Address // a street address
{
   char *street;
   int number;
   char *city;
}; 

 在生成的序列化函数中,使用e__Address的一个实例来表示e命名空间前缀的一个地址元素类型。

<e:Address xsi:type="e:Address">
<email xsi:type="string">me@home</email>
<url xsi:type="string">www.me.com</url>
</e:Address> 

 用s__Address的一个实例来表示s命名空间前缀的一个地址元素类型。

<s:Address xsi:type="s:Address">
<street xsi:type="string">Technology Drive</street>
<number xsi:type="int">5</number>
<city xsi:type="string">Softcity</city>
</s:Address> 

 客户端程序的命名空间表必须有e和s的数据类型定义:

struct Namespace namespaces[] =
{ …
   {"e", "http://www.me.com/schemas/electronic-address"},
   {"s", "http://www.me.com/schemas/street-address"},
… 

 命名空间表必须作为客户端程序的一部分,使客户端程序在运行时可以对数据进行序列化及反序列化。
2.11 gsoap翻译计划(8.1.4~8.1.6)
 
8.1.4 如何建立客户端程序代理类
 用于C++客户端程序的代理类信息是由gSOAP预编译器自动创建的。为了说明代理类的生成过程,我们在getQuote.h头文件中加入一些信息,以便gSOAP预编译器可以生成代理类。这些信息就类似于WSDL解析器自动生成的头文件中就已经包含的信息。

//"getQuote.h"的内容:
//gsoap ns1 service name: Quote
//gsoap ns1 service location: http://services.xmethods.net/soap
//gsoap ns1 service namespace: urn:xmethods-delayed-quotes
//gsoap ns1 service style: rpc
//gsoap ns1 service encoding: encoded
//gsoap ns1 service method-action: getQuote ""
int ns1__getQuote(char *symbol, float &Result); 

 前三行指令用于定义代理类的名称,服务地址,命名空间。第四行、第五行指令定义了使用SOAP RPC编码方式。最后一行定义了可选的SOAPAction。当需要SOAPAction时,这行信息将提供给每个远程方法。使用soapcpp2对该头文件进行编译后,将会产生soapQuoteProxy.h文件。它包含下面的内容:

#include "soapH.h"
class Quote
{ public:
   struct soap *soap;
   const char *endpoint;
   Quote() { soap = soap_new(); endpoint = "http://services.xmethods.net/soap"; };
   ~Quote() { if (soap) { soap_destroy(soap); soap_end(soap); soap_done(soap); free((void*)soap); }};
   int getQuote(char *symbol, float &Result) { return soap ? soap_call_ns1__getQuote(soap, endpoint, "", symbol, Result) : SOAP_EOM; };
}; 

 为了能够在运行时刻对gSOAP环境变量及命名空间进行定制,上述两个变量被定义程全局变量。
 生成的代理类可以同命名空间表一起包含在客户端程序中,请看下面的例子:

#include "soapQuoteProxy.h" // 获得代理类
#include "Quote.nsmap" // 获得命名空间绑定
int main()
{
   Quote q;
   float r;
   if (q.ns1__getQuote("IBM", r) == SOAP_OK)
      std::cout << r << std::endl;
   else
      soap_print_fault(q.soap, stderr);
   return 0;

 Quote构造函数定义并初始化了一个gSOAP运行环境实例。所有的HTTP及SOAP/XML进程都被隐藏在后台自动执行。
 如果你需要多个命名空间表或要联合多个客户端,你可以在执行soapcpp2时添加参数-n及-p来生成命名空间表以防止冲突。详细信息请看9.1及18.33节。同时,你可以使用C++代码命名空间来创建一个命名空间限制的代理类,详细信息请看18.32节。

8.1.5  XSD 类型编码
 许多SOAP服务需要在SOAP负载中使用XML编码。在gSOAP预编译器中使用的默认编码为SOAP RPC编码。然而,使用XSD类型编码可以改善互操作性。XSD类型在头文件中用typedef定义。举个例子,下面的定义将C/C++类型转换为XSD类型:

// Contents of header file:

typedef char *xsd__string; // encode xsd__string value as the xsd:string schema type
typedef char *xsd__anyURI; // encode xsd__anyURI value as the xsd:anyURI schema type
typedef float xsd__float; // encode xsd__float value as the xsd:float schema type
typedef long xsd__int; // encode xsd__int value as the xsd:int schema type
typedef bool xsd__boolean; // encode xsd__boolean value as the xsd:boolean schema type
typedef unsigned long long xsd__positiveInteger; // encode xsd__positiveInteger value as the xsd:positiveInteger schema type
… 

 这些简单的声明告诉gSOAP预编译器当远程方法参数中使用上述定义的类型时,就把相关的C++类型转当作内建的XSD类型进行编码、解码。同时,使用typedef不需要使用内建C++类型的客户端或服务端程序更改现有代码(但只是当参数为简单的C++类型时,请参看11.2.2节来使用XSD类型表示组合的数据类型)。

8.1.6 例子
 
 重新考虑一席getQuote的例子。现在用XSD类型来重写代码:

// Contents of file "getQuote.h":
typedef char *xsd__string;
typedef float xsd__float;
int ns1__getQuote(xsd__string symbol, xsd__float &Result); 

 使用预编译器编译这个头文件,将会生成与原来相同的存根例程代码:

int soap_call_ns1__getQuote(struct soap *soap, char *URL, char *action, char *symbol, float &Result); 

 客户端程序不需要进行任何改动,即可使用XSD类型类编码、解码数据类型信息了。
 举个例子,当客户端程序调用代理时,代理方法用xsd:string类型产生一个SOAP请求:


<SOAP-ENV:Body>
<ns1:getQuote><symbol xsi:type="xsd:string">IBM</symbol>
</ns1:getQuote>
</SOAP-ENV:Body>
… 

服务端的返回码为:


<soap:Body>
<n:getQuoteResponse xmlns:n="urn:xmethods-delayed-quotes">
<Result xsi:type="xsd:float">41.81</Result>
</n:getQuoteResponse>
</soap:Body>
… 

 

 
Rundll32.exe是什么?顾名思意,“执行32位的DLL文件”。它的作用是执行DLL文件中的内部函数,这样在进程当中,只会有Rundll32.exe,而不会有DLL后门的进程,这样,就实现了进程上的隐藏。如果看到系统中有多个Rundll32.exe,不必惊慌,这证明用Rundll32.exe启动了多少个的DLL文件。当然,这些Rundll32.exe执行的DLL文件是什么,我们都可以从系统自动加载的地方找到。

现在,我来介绍一下Rundll32.exe这个文件,意思上边已经说过,功能就是以命令行的方式调用动态链接程序库。系统中还有一个Rundll.exe文件,他的意思是“执行16位的DLL文件”,这里要注意一下。在来看看Rundll32.exe使用的函数原型:
Void CALLBACK FunctionName (
HWND hwnd,
HINSTANCE hinst,
LPTSTR lpCmdLine,
Int nCmdShow
);

其命令行下的使用方法为:Rundll32.exe DLLname,Functionname [Arguments]
DLLname为需要执行的DLL文件名;Functionname为前边需要执行的DLL文件的具体引出函数;[Arguments]为引出函数的具体参数。

略谈Rundll32.exe的作用

常用Windows9x的朋友一定对Rundll32.exe和Rundll.exe这两个档案不会陌生吧,不过,由於这两个程式的功能原先只限於在微软内部使用,因而真正知道如何使用它们的朋友想必不多。那么好,如果你还不清楚的话,那么就让我来告诉你吧。

首先,请你做个小实验(请事先保存好你正在执行的程式的结果,否则…):点击“开始-程式-Ms-Dos方式”,进入Dos视窗,然後键入rundll32.exe user.exe,restartwindows,再按下回车键,这时你将看到,机器被重启了!怎么样,是不是很有趣?

当然,Rundll的功能绝不仅仅是重启你的机器。其实,Rundll者,顾名思义,执行Dll也,它的功能就是以命令列的方式呼叫Windows的动态链结库,Rundll32.exe与Rundll.exe的区别就在於前者是呼叫32位的链结库,而後者是运用於16位的链结库,它们的命令格式是: RUNDLL.EXE ,,

这里要注意三点:1.Dll档案名中不能含有空格,比如该档案位於c:\ProgramFiles\目录,你要把这个路径改成c:\Progra~1\;2.Dll档案名与Dll入口点间的逗号不能少,否则程式将出错并且不会给出任何资讯!3.这是最重要的一点:Rundll不能用来呼叫含返回值参数的Dll,例如Win32API中的GetUserName(),GetTextFace()等。在Visual Basic中,提供了一条执行外部程式的指令Shell,格式为:Shell “命令列”

如果能配合Rundll32.exe用好Shell指令,会使您的VB程式拥有用其他方法难以甚至无法实现的效果:仍以重启为例,传统的方法需要你在VB工程中先建立一个模组,然後写入WinAPI的声明,最後才能在程式中呼叫。而现在只需一句: Shell “rundll32.exe user.exe,restartwindows”就搞定了!是不是方便多了?

实际上,Rundll32.exe在呼叫各种Windows控制面板和系统选项方面有著独特的优势。下面,我就将本人在因特网上收集的有关Rundll的指令列举如下(很有用的,能省去你很多呼叫Windows API的时间!!),供大家在程式设计中引用:
命令列: rundll32.exe shell32.dll,Control_RunDLL
功能: 显示控制面板
命令列: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,1
功能: 显示“控制面板-辅助选项-键盘”选项视窗
命令列: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,2
功能: 显示“控制面板-辅助选项-声音”选项视窗
命令列: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,3
功能: 显示“控制面板-辅助选项-显示”选项视窗
命令列: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,4
功能: 显示“控制面板-辅助选项-滑鼠”选项视窗
命令列: rundll32.exe shell32.dll,Control_RunDLL access.cpl,,5
功能: 显示“控制面板-辅助选项-传统”选项视窗
命令列: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl @1
功能: 执行“控制面板-添加新硬体”向导。
命令列: rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL AddPrinter
功能: 执行“控制面板-添加新印表机”向导。
命令列: rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,1
功能: 显示 “控制面板-添加/删除程式-安装/卸载” 面板。
命令列: rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,2
功能: 显示 “控制面板-添加/删除程式-安装Windows” 面板。
命令列: rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,3
功能: 显示 “控制面板-添加/删除程式-启动盘” 面板。
命令列: rundll32.exe syncui.dll,Briefcase_Create
功能: 在桌面上建立一个新的“我的公文包”。
命令列: rundll32.exe diskcopy.dll,DiskCopyRunDll
功能: 显示复制软碟视窗
命令列: rundll32.exe apwiz.cpl,NewLinkHere %1
功能: 显示“建立快捷方式”的对话框,所建立的快捷方式的位置由%1参数决定。
命令列: rundll32.exe shell32.dll,Control_RunDLL timedate.cpl,,0
功能: 显示“日期与时间”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL timedate.cpl,,1
功能: 显示“时区”选项视窗。
命令列: rundll32.exe rnaui.dll,RnaDial [某个拨号连接的名称]
功能: 显示某个拨号连接的拨号视窗。如果已经拨号连接,则显示目前的连接状态的视窗。
命令列: rundll32.exe rnaui.dll,RnaWizard
功能: 显示“新建拨号连接”向导的视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0
功能: 显示“显示属性-背景”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,1
功能: 显示“显示属性-萤屏保护”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,2
功能: 显示“显示属性-外观”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3
功能: 显示显示“显示属性-属性”选项视窗。
命令列: rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL FontsFolder
功能: 显示Windows的“字体”档案夹。
命令列: rundll32.exe shell32.dll,Control_RunDLL main.cpl @3
功能: 同样是显示Windows的“字体”档案夹。
命令列: rundll32.exe shell32.dll,SHformatDrive
功能: 显示格式化软碟对话框。
命令列: rundll32.exe shell32.dll,Control_RunDLL joy.cpl,,0
功能: 显示“控制面板-游戏控制器-一般”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL joy.cpl,,1
功能: 显示“控制面板-游戏控制器-进阶”选项视窗。
命令列: rundll32.exe mshtml.dll,PrintHTML (HTML文档)
功能: 列印HTML文档。
命令列: rundll32.exe shell32.dll,Control_RunDLL mlcfg32.cpl
功能: 显示Microsoft Exchange一般选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL main.cpl @0
功能: 显示“控制面板-滑鼠” 选项 。
命令列: rundll32.exe shell32.dll,Control_RunDLL main.cpl @1
功能: 显示 “控制面板-键盘属性-速度”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL main.cpl @1,,1
功能: 显示 “控制面板-键盘属性-语言”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL main.cpl @2
功能: 显示Windows“印表机”档案夹。
命令列: rundll32.exe shell32.dll,Control_RunDLL main.cpl @3
功能: 显示Windows“字体”档案夹。
命令列: rundll32.exe shell32.dll,Control_RunDLL main.cpl @4
功能: 显示“控制面板-输入法属性-输入法”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL modem.cpl,,add
功能: 执行“添加新调制解调器”向导。
命令列: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0
功能: 显示“控制面板-多媒体属性-音频”属性页。
命令列: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,1
功能: 显示“控制面板-多媒体属性-视频”属性页。
命令列: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,2
功能: 显示“控制面板-多媒体属性-MIDI”属性页。
命令列: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,3
功能: 显示“控制面板-多媒体属性-CD音乐”属性页。
命令列: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,4
功能: 显示“控制面板-多媒体属性-设备”属性页。
命令列: rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl @1
功能: 显示“控制面板-声音”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL netcpl.cpl
功能: 显示“控制面板-网路”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL odbccp32.cpl
功能: 显示ODBC32资料管理选项视窗。
命令列: rundll32.exe shell32.dll,OpenAs_RunDLL {drive:\path\filename}

功能: 显示指定档案(drive:\path\filename)的“打开方式”对话框。
命令列: rundll32.exe shell32.dll,Control_RunDLL password.cpl
功能: 显示“控制面板-密码”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL powercfg.cpl
功能: 显示“控制面板-电源管理属性”选项视窗。
命令列: rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL PrintersFolder
功能: 显示Windows“印表机”档案夹。(同rundll32.exe shell32.dll,Control_RunDLL main.cpl @2)
命令列: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,0
功能: 显示“控制面板-区域设置属性-区域设置”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,1
功能: 显示“控制面板-区域设置属性-数字”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,2
功能: 显示“控制面板-区域设置属性-货币”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,3
功能: 显示“控制面板-区域设置属性-时间”选项视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,4
功能: 显示“控制面板-区域设置属性-日期”选项视窗。
命令列: rundll32.exe desk.cpl,InstallScreenSaver [萤屏保护档案名]
功能: 将指定的萤屏保护档案设置为Windows的屏保,并显示萤屏保护属性视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,0
功能: 显示“控制面板-系统属性-传统”属性视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,1
功能: 显示“控制面板-系统属性-设备管理器”属性视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,2
功能: 显示“控制面板-系统属性-硬体配置档案”属性视窗。
命令列: rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,3
功能: 显示“控制面板-系统属性-性能”属性视窗。
命令列: rundll32.exe user.exe,restartwindows
功能: 强行关闭所有程式并重启机器。
命令列: rundll32.exe user.exe,exitwindows
功能: 强行关闭所有程式并关机。
命令列: rundll32.exe shell32.dll,Control_RunDLL telephon.cpl
功能: 显示“拨号属性”选项视窗
命令列: rundll32.exe shell32.dll,Control_RunDLL themes.cpl
功能: 显示“桌面主旨”选项面板
当然,不止是VisualBasic,象Delphi.VisualC++等其他程式设计语言也可以通过呼叫外部命令的方法来使用Rundll的这些功能,具体方法这里就不再详细叙述了。灵活的使用Rundll,一定会使你的程式设计轻轻松松,达到事半功倍的效果!

 

2006年11月11日

IE秀网站www.ieshow.net 免费提供了在线制作工具条,用户可以Diy自己制作自己想要的工具条,功能极其强大,真是随心所欲阿,痛快了得!

我自己做了一个用来方便上网的迷你好123工具条,呵呵,说白了就是收藏夹功能,附带了其他一些系统功能,现在上网方便多了。

还具有IE的收藏功能,可以方便的导出/导入,呵呵,牛吧!

下载地址:

http://www.ieshow.net/toolbar/online/toolbar/toolbar_info.aspx?programeName=ProSiteAll

 

 

–据悉,国内金融界从中国国情出发,已经开始共建金融权威认证中心(CA)。这项计划由银行卡信息交换总中心负责筹建,经金融信息化领导小组正式批准,今年3月已开始向国内外厂商发出招标通告。CA只是电子商务信息安全大系统中的一个环节,这里我们将向读者全面系统介绍网络安全中的一个重要概念及技术。

–随着Internet技术的发展,Intranet服务、电子商务、网络银行成为近年来的几大热点,国内也有越来越多的机构、企业涉足这些领域。这样,信息安全问题就提到日程上来。几年来,在Internet上涌现出了许多新的安全技术和安全规范,公开密钥基础设施(PKI:PublicKeyInfrastructure)即是其中一员。  

 PKI的基本组成

–PKI是一种遵循标准的密钥管理平台,它能够为所有网络应用透明地提供采用加密和数字签名等密码服务所必需的密钥和证书管理。PKI必须具有认证机关(CA)、证书库、密钥备份及恢复系统、证书作废处理系统、客户端证书处理系统等基本成分,构建PKI也将围绕着这五大系统来构建。

–1.认证机关

–CA是证书的签发机构,它是PKI的核心。众所周知,构建密码服务系统的核心内容是如何实现密钥管理,公钥体制涉及到一对密钥,即私钥和公钥,私钥只由持有者秘密掌握,无须在网上传送,而公钥是公开的,需要在网上传送,故公钥体制的密钥管理主要是公钥的管理问题,目前较好的解决方案是引进证书(certificate)机制。

–证书是公开密钥体制的一种密钥管理媒介。它是一种权威性的电子文档,形同网络计算环境中的一种身份证,用于证明某一主体(如人、服务器等)的身份以及其公开密钥的合法性。在使用公钥体制的网络环境中,必须向公钥的使用者证明公钥的真实合法性。因此,在公钥体制环境中,必须有一个可信的机构来对任何一个主体的公钥进行公证,证明主体的身份以及他与公钥的匹配关系。

CA正是这样的机构,它的职责归纳起来有:  

验证并标识证书申请者的身份;   

确保CA用于签名证书的非对称密钥的质量;  

确保整个签证过程的安全性,确保签名私钥的安全性;   

证书材料信息(包括公钥证书序列号、CA标识等)的管理;   

确定并检查证书的有效期限;  

确保证书主体标识的唯一性,防止重名;发布并维护作废证书表;  

对整个证书签发过程做日志记录;   

向申请人发通知。

–其中最为重要的是CA自己的一对密钥的管理,它必须确保其高度的机密性,防止他方伪造证书。CA的公钥在网上公开,整个网络系统必须保证完整性。

–证书的主要内容如右表所示。

–其中,CA的数字签名保证了证书(实质是持有者的公钥)的合法性和权威性。   

主体(用户)的公钥可有两种产生方式:用户自己生成密钥对,然后将公钥以安全的方式传送给CA,该过程必须保证用户公钥的可验证性和完整性;   

CA替用户生成密钥对,然后将其以安全的方式传送给用户,该过程必须确保密钥对的机密性、完整性和可验证性。该方式下由于用户的私钥为CA所知,故对CA的可信性有更高的要求。

–用户A可通过两种方式获取用户B的证书和公钥,一种是由B将证书随同发送的正文信息一起传送给A,另一种是所有的证书集中存放于一个证书库中,用户A可从该地点取得B的证书。

–CA的公钥可以存放在所有节点处,方便用户使用。  

 表证书的主要内容

–上表中的"用途"是一项重要的内容,它规定了该证书所公证的公钥的用途。公钥必须按规定的用途来使用。一般地,公钥有两大类用途:用于验证数字签名。消息接收者使用发送者的公钥对消息的数字签名进行验证。用于加密信息。消息发送者使用接收者的公钥加密用于加密消息的密钥,进行数据加密密钥的传递。

–相应地,系统中需要配置用于数字签名/验证的密钥对和用于数据加密/脱密的密钥对,这里分别称为签名密钥对和加密密钥对。这两对密钥对于密钥管理有不同的要求:   

签名密钥对

–签名密钥对由签名私钥和验证公钥组成。签名私钥具有日常生活中公章、私章的效力,为保证其唯一性,签名私钥绝对不能够作备份和存档,丢失后只需重新生成新的密钥对,原来的签名可以使用旧公钥的备份来验证。验证公钥需要存档,用于验证旧的数字签名。

–用作数字签名的这一对密钥一般可以有较长的生命期。  

加密密钥对

–加密密钥对由加密公钥和脱密私钥组成。

–为防止密钥丢失时丢失数据,脱密私钥应该进行备份,同时还可能需要进行存档,以便能在任何时候脱密历史密文数据。加密公钥无须备份和存档,加密公钥丢失时,只须重新产生密钥对。

–加密密钥对通常用于分发会话密钥,这种密钥应该频繁更换,故加密密钥对的生命周期较短。

–不难看出,这两对密钥的密钥管理要求存在互相冲突的地方,因此,系统必须针对不同的用途使用不同的密钥对,尽管有的公钥体制算法,如目前使用广泛的RSA,既可以用于加密、又可以用于签名,在使用中仍然必须为用户配置两对密钥、两张证书,其一用于数字签名,另一用于加密。

–2.证书库

–证书库是证书的集中存放地,它与网上"白页"类似,是网上的一种公共信息库,用户可以从此处获得其他用户的证书和公钥。

–构造证书库的最佳方法是采用支持LDAP协议的目录系统,用户或相关的应用通过LDAP来访问证书库。系统必须确保证书库的完整性,防止伪造、篡改证书。

–3.密钥备份及恢复系统—-如果用户丢失了用于脱密数据的密钥,则密文数据将无法被脱密,造成数据丢失。为避免这种情况的出现,PKI应该提供备份与恢复脱密密钥的机制。

–密钥的备份与恢复应该由可信的机构来完成,例如CA可以充当这一角色。值得强调的是,密钥备份与恢复只能针对脱密密钥,签名私钥不能够作备份。

–4.证书作废处理系统

–证书作废处理系统是PKI的一个重要组件。同日常生活中的各种证件一样,证书在CA为其签署的有效期以内也可能需要作废,例如,A公司的职员a辞职离开公司,这就需要终止a证书的生命期。为实现这一点,PKI必须提供作废证书的一系列机制。作废证书有如下三种策略:   

作废一个或多个主体的证书;   

作废由某一对密钥签发的所有证书;  

作废由某CA签发的所有证书。

–作废证书一般通过将证书列入作废证书表(CRL)来完成。通常,系统中由CA负责创建并维护一张及时更新的CRL,而由用户在验证证书时负责检查该证书是否在CRL之列。CRL一般存放在目录系统中。

–证书的作废处理必须在安全及可验证的情况下进行,系统还必须保证CRL的完整性。

–5.PKI应用接口系统

–PKI的价值在于使用户能够方便地使用加密、数字签名等安全服务,因此一个完整的PKI必须提供良好的应用接口系统,使得各种各样的应用能够以安全、一致、可信的方式与PKI交互,确保所建立起来的网络环境的可信性,同时降低管理维护成本。

–为了向应用系统屏蔽密钥管理的细节,PKI应用接口系统需要实现如下的功能:   

完成证书的验证工作,为所有应用以一致、可信的方式使用公钥证书提供支持;   

以安全、一致的方式与PKI的密钥备份与恢复系统交互,为应用提供统一的密钥备份与恢复支持;   

在所有应用系统中,确保用户的签名私钥始终只在用户本人的控制之下,阻止备份签名私钥的行为;  

根据安全策略自动为用户更换密钥,实现密钥更换的自动、透明与一致;   

为方便用户访问加密的历史数据,向应用提供历史密钥的安全管理服务;  

为所有应用访问统一的公用证书库提供支持;  

以可信、一致的方式与证书作废系统交互,向所有应用提供统一的证书作废处理服务;  

完成交叉证书(见后)的验证工作,为所用应用提供统一模式的交叉验证支持;

支持多种密钥存放介质,包括IC卡、PC卡、安全文件等。

–最后,PKI应用接口系统应该是跨平台的。  

PKI的功能

–归纳起来,PKI应该为应用提供如下的安全支持:   

证书与CA

–PKI应实现CA以及证书库、CRL等基本的证书管理功能。  

密钥备份及恢复证书、密钥对的自动更换

–证书、密钥都有一定的生命期限。当用户的私钥泄露时,必须更换密钥对;另外,随着计算机速度日益提高,密钥长度也必须相应地增长。因此,PKI应该提供完全自动(无须用户干预)的密钥更换以及新证书的分发工作。  

交叉签证

–每个CA只可能覆盖一定的作用范围,即CA的域,例如,不同的企业往往有各自的CA,它们颁发的证书都只在企业范围内有效。当隶属于不同CA的用户需要交换信息时,就需要引入交叉证书和交叉验证,这也是PKI必须完成的工作。  

加密密钥和签名密钥的分隔

–如前所述,加密和签名密钥的密钥管理需求是相互抵触的,因此PKI应该支持加密和签名密钥的分隔使用。  

 支持对数字签名的不可抵赖

–任何类型的电子商务都离不开数字签名,因此PKI必须支持数字签名的不可抵赖性,而数字签名的不可抵赖性依赖于签名私钥的唯一性和机密性,为确保这一点,PKI必须保证签名密钥与加密密钥的分隔使用。  

密钥历史的管理

–每次更新加密密钥后,相应的解密密钥都应该存档,以便将来恢复用旧密钥加密的数据。每次更新签名密钥后,旧的签名私钥应该妥善销毁,防止破坏其唯一性;相应的旧验证公钥应该进行存档,以便将来用于验证旧的签名。这些工作都应该是PKI自动完成的。  

PKI的性能要求

–作为网络环境的一种基础设施,PKI必须具有良好的性能,一般地,对PKI的性能有如下要求:

透明性和易用性

–这是对PKI的最基本要求,PKI必须尽可能地向上层应用屏蔽密码服务的实现细节,向用户屏蔽复杂的安全解决方案,使密码服务对用户而言简单易用,同时便于单位、企业完全控制其信息资源。  

可扩展性

–证书库和CRL必须具有良好的可扩展性。

互操作性

–不同企业、单位的PKI实现可能是不同的,这就提出了互操作性要求。要保证PKI的互操作性,必须将PKI建立在标准之上,这些标准包括加密标准、数字签名标准、HASH标准、密钥管理标准、证书格式、目录标准、文件信封格式、安全会话格式、安全应用程序接口规范等。  

 支持多应用 –PKI应该面向广泛的网络应用,提供文件传送安全、文件存储安全、电子邮件安全、电子表单安全、Web应用安全等保护。

支持多平台

–PKI应该支持目前广泛使用的操作系统平台,包括Windows、UNIX、MAC等
 

  1.了解上司的为人。

    如果你不了解上司的为人、喜好、个性,只顾挥汗如雨的埋头苦干,工作再怎么出色也是得不到上司的赏识和认同的。在工作中多多留意一下领导的言谈举止,品味一下他的为人,不但可以减少相处过程中不必要的摩擦,还可以促进相互之间的沟通,为自己的晋升扫清障碍。

    2.注意等级差别。

    由于家庭环境和社会影响,现在的年轻人很容易只把上司看为公司团队中与自己相同的一分子。特别是上司与自己年龄相仿,在工作交往中便更加无所顾忌。平时直呼其名,随便开玩笑,若有了什么不满也不分场合直抒胸臆。但是上司不是你的朋友,他在乎他的权威和地位,他需要别人的承认。如果你的上司还有上司,你如此“礼遇”他,他会很没面子。就算他是你的朋友,在公司也最好把你们的关系单纯为简单的上下级关系。

    3.永远不要在上司面前流泪。

    泪水容易给人这样一个信息:她是柔弱的,她的承受力太差了。如果你在上司面前流眼泪,原先打算提拔你的上司也可能会认为你不能胜任你的工作。

    4.忠诚。

    你可以能力有限,你可以处事不够圆滑,你可以有些诸如丢三拉四的小毛病,但你绝对不可以不忠诚。忠诚是上司对员工的第一要求。不要试图搞小动作,你的上司能有今天的位置说明他绝非等闲之辈,你智商再高,手段再高明,在他的经验阅历面前也不过是小儿科。

    5.及时完成工作。

    职员的天职就是工作。如果没有完成上司交给你的任务,不管有什么客观因素,别试图在心存不快的上司面前解释什么,没有做好本职工作,任何理由都不是理由,因为上司关心的只是事情的结果。工作没做好,你的解释只会让他更加反感。如果确实是上司的安排有问题,你可以事后委婉地提出,但千万不要把它作为拖延工作的理由。

    6.敏感上司的动机。

    上司的不同命令下达方法可能暗含不同的目的:吩咐,意即要求下属严格执行,不得另行提出建议及加上自己的判断;请托,给予下属若干自由裁量的空间,大方向不得更改;征询,欲使下属产生强烈的意愿和责任感,对他极为青睐;暗示,面对能力强的下属,有意培养对方的能力。所以,当你接受一个任务时,用点心,不要辜负领导的美意,错失良机。

    7.小处不可随便。

    注意自己的言谈举止和工作中的细节问题,越是随意的场合越要加以小心;当事人无心,旁观者有意。很多上司都信奉“见微知著”的四字箴言,认为这些生活中的旁枝末节将暴露一个人太多的秘密——潜意识的行为是很难伪装的。比如文案的摆放显示了你做事的条理性和缜密度,发言的音量说明了你的自信心如何,酒会上行为是否得体暴露了你的个人修养与自制力,等等。

    8.不要委曲求全。

    涉世之初,我们被告诫:“忍一时风平浪静,退一步海阔天空”,总想委曲求全,即使被领导冤枉骂得狗血淋头也固守沉默是金,大不了背地里痛哭一场。可委曲能求全吗?NO!一方面你的“大度”掩盖了公司内部真正存在的问题,另一方面会让上司误解你的能力甚至是人品,你的无言使他对自己的判断更加深信不疑:她理亏所以她无话可说。既然于公于私都无益,你还不如找机会解释清楚,比如写封信。

    9.要有团队精神。

    没有一个上司喜欢害群之马,因为是他所服务的团队给了他威严、权利和成就感。没有整个团队的成长,他的事业就失去了依托。不要只想着怎样讨上司喜欢,要和你的同事融洽相处,别搞个人主义,孤胆英雄只有在影视作品里才有人赏识,在现实生活中却让所有的人嫉恨。如果你不打算做个自由职业者,除了融入集体,别无选择。《女性月刊》嫣然

 

清平调词三首

李白

  云想衣裳花想容, 春风拂槛露华浓。
  若非群玉山头见, 会向瑶台月下逢。
  一枝红艳露凝香, 云雨巫山枉断肠。
  借问汉宫谁得似? 可怜飞燕倚新妆。
  名花倾国两相欢, 长得君王带笑看。
  解释春风无限恨, 沉香亭北倚阑干。

  这三首诗是李白在长安供奉翰林时所作。一日,玄宗和杨妃在宫中观牡丹花,因命李白写新乐章,李白奉诏而作。在三首诗中,把木芍药(牡丹)和杨妃交互在一起写,花即是人,人即是花,把人面花光浑融一片,同蒙唐玄宗的恩泽。从篇章结构上说,第一首从空间来写,把读者引入蟾宫阆苑;第二首从时间来写,把读者引入楚襄王的阳台,汉成帝的宫廷;第三首归到目前的现实,点明唐宫中的沉香亭北。诗笔不仅挥洒自如,而且相互钩带。“其一”中的春风,和“其三”中的春风,前后遥相呼应。

  第一首,一起七字:“云想衣裳花想容,”把杨妃的衣服,写成真如霓裳羽衣一般,簇拥着她那丰满的玉容。“想”字有正反两面的理解,可以说是见云而想到衣裳,见花而想到容貌,也可以说把衣裳想象为云,把容貌想象为花,这样交互参差,七字之中就给人以花团锦簇之感。接下去“春风拂槛露华浓”,进一步以“露华浓”来点染花容,美丽的牡丹花在晶莹的露水中显得更加艳冶,这就使上句更为酣满,同时也以风露暗喻君王的恩泽,使花容人面倍见精神。下面,诗人的想象忽又升腾到天堂西王母所居的群玉山、瑶台。“若非”、“会向”,诗人故作选择,意实肯定:这样超绝人寰的花容,恐怕只有在上天仙境才能见到!玉山、瑶台、月色,一色素淡的字眼,映衬花容人面,使人自然联想到白玉般的人儿,又象一朵温馨的白牡丹花。与此同时,诗人又不露痕迹,把杨妃比作天女下凡,真是精妙至极。

  第二首,起句“一枝红艳露凝香”,不但写色,而且写香;不但写天然的美,而且写含露的美,比上首的“露华浓”更进一层。“云雨巫山枉断肠”用楚襄王的故事,把上句的花,加以人化,指出楚王为神女而断肠,其实梦中的神女,那里及得到当前的花容人面!再算下来,汉成帝的皇后赵飞燕,可算得绝代美人了,可是赵飞燕还得倚仗新妆,那里及得眼前花容月貌般的杨妃,不须脂粉,便是天然绝色。这一首以压低神女和飞燕,来抬高杨妃,借古喻今,亦是尊题之法。相传赵飞燕体态轻盈,能站在宫人手托的水晶盘中歌舞,而杨妃则比较丰肥,固有“环肥燕瘦”之语(杨贵妃名玉环)。后人据此就编造事实,说杨妃极喜此三诗,时常吟哦,高力士因李白曾命之脱靴,认为大辱,就向杨妃进谗,说李白以飞燕之瘦,讥杨妃之肥,以飞燕之私通赤凤,讥杨妃之宫闱不检。李白诗中果有此意,首先就瞒不过博学能文的玄宗,而且杨妃也不是毫无文化修养的人。据原诗来看,很明显是抑古尊今,好事之徒,强加曲解,其实是不可通的。

  第三首从仙境古人返回到现实。起首二句“名花倾国两相欢,长得君王带笑看”,“倾国”美人,当然指杨妃,诗到此处才正面点出,并用“两相欢”把牡丹和“倾国”合为一提,“带笑看”三字再来一统,使牡丹、杨妃、玄宗三位一体,融合在一起了。由于第二句的“笑”,逗起了第三句的“解释春风无限恨”,春风两字即君王之代词,这一句,把牡丹美人动人的姿色写得情趣盎然,君王既带笑,当然无恨,恨都为之消释了。末句点明玄宗杨妃赏花地点──“沉香亭北”。花在阑外,人倚阑干,多么优雅风流。

  这三首诗,语语浓艳,字字流葩,而最突出的是将花与人浑融在一起写,如“云想衣裳花想容”,又似在写花光,又似在写人面。“一枝红艳露凝香”,也都是人、物交溶,言在此而意在彼。读这三首诗,如觉春风满纸,花光满眼,人面迷离,不待什么刻画,而自然使人觉得这是牡丹,这是美人玉色,而不是别的。无怪这三首诗当时就深为唐玄宗所赞赏。