人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS)中表现得尤为明显。笔者在工作实践中发现,不良的SQL往往来自于不恰当的索引设计、不充份的连接条件和不可优化的where子句。在对它们进行适当的优化后,其运行速度有了明显地提高!下面我将从这三个方面分别进行总结:
@2006-5-28 12:49:39
存储过程天天用,关于使用存储过程的sql语句的争论也一直在,个人觉得使用存储过程要好于用sql语句,整理了一些说明
@2006-5-28 12:51:50
- 单位换算 "12英里"、"12英里 in 海里"
- 货币折算 "213美元"、"213美元 in 澳元"
- 计算器 "sqrt(34*78)"
- 特定文件类型 "filetype:pdf 科学"
- 特定网站内容 "site:www.jflycn.net 科学"
- 链接 "link:www.jflycn.net"
- 定义 "define:科学"、"define:science"
- 电影 "movie: wo hu cang long"、"movie: li mu bai"、"movie: lee ang"、"movie: zhang zi yi"
- 翻译 "fy science"、"fy 科学"
- 天气 "tq 南通"
- 股票 "gp 综艺股份"、"gp zygf"、"gp 600770"
- 邮编 "yb 南通"、"yb 226300"
- 区号 "qh 南通"、"qh 0513"
- 手机归属地 "13862888888"
- 图像 images.google.com
- 新闻 news.google.com
- 新闻订阅 www.google.com/alerts
- 地图 maps.google.com
- 邮购 catalogs.google.com
- 购物 froogle.google.com
- 论坛 groups-beta.google.com
- 答疑 answers.google.com
- 本地信息 local.google.com
- 图书 print.google.com
- 学术 scholar.google.com
- 实验室 labs.google.com
@2006-6-13 15:34:18
到底哪一种最好呢?必须考虑序列化和反序列化的速度要快,占用内存小,并且不能有内存泄漏,容易使用。唉,难找啊。
我粗略看了下几种的ORM,请各位大侠不吝指教,小弟感激为盼。
国内:
Web Sharp: http://websharp.sf.net
License: BSD License, GNU Library or Lesser General Public License (LGPL)
.Net 版本: .Net Framework 2.0
入门文档写得不错,清晰,上手容易,同时也一下子就说清楚了WebSharp的意图以及覆盖范围。不过框架的层次就语焉不详了。
Websharp的目标,是开发一个开源的基于Microsoft.Net的轻量级的应用软件系统开发框架,包含以下内容:
* 一个轻量级的O/R Mapping框架
* 一个轻量级的AOP框架
* 一个轻量级的ServiceLocator,主要目的是为整合不同服务端技术的客户端编程。
Websharp ORM主要特点是使用Attribute作为描述映射的方法,简单明了,并且,对开发人员来说,只有PersistenceManager、Query、Transaction等极少数接口需要掌握,上手快,使用非常方便。只需要普通的类就可以进行O/R的转换,不需要从指定的类上派生。
遗憾:
无自动代码生成器,要手工写实体类。
Kanas.net: http://www.cnblogs.com/barton131420
License: GNU LESSER GENERAL PUBLIC LICENSE
.Net 版本:.Net Framework 1.1
优势:
它的设计思想也是使用Attribute作为描述映射的方法,同时多了一个 CodeGen IDE附加工具,使用XML格式文件作为输入,自动生成类的代码,不过VS2005下不能使用。并提供了基本NUnit一些测试【应该随便测试下运行效率】。
遗憾:
* CodeGen 工具没有提供源码,并且该工具必须在VS2003 IDE下使用,不爽。
* 帮助文档极不友好, Kanas.Framework 的基本描述,设计目标,覆盖范围都没有,帮助文件里类的说明用词晦涩难懂,还不如直接看源代码。上手难。
* 实体类必须从 BizObject 上派生(实际上它的BizObject也只是一个壳,所有的数据都是交由 DataCell 控制)
* 限制特定查询条件它似乎需要从 Constrant 类派生实现的,如 查询月日是否相同,都要定一个DayConstrant类,俺觉得这样太过于繁琐了。
NBear: http://Nbear.org
License: BSD.license
.Net 版本:.Net Framework 2.0
用到的第三方库: Castle Project
实体类必须定义成接口从 IEntity 派生,同样使用 Attribute。
提供NBear.Tools.EntityGen.exe 工具从数据库表和视图生成对应的实体类,目前只支持SqlServer和Access。
入门文档极多,上手并不太难,感觉该库的侧重点是Web结合方面,很是不错,正和我的需要,就是不知道速度
性能和内存占用如何。
可惜没有对自身框架做描述和解释的文章。文档大多以教程为主,说明如何用。
NBearV3 SDK.chm 无法看到内容,报告脚本出错,装的是IE7内核。似乎是从源代码自动生成的文档。
NBearV3TotoursCN.zip 只是教程,以及为啥取名未NBear【汗,这个谁关心啊,取名字嘛作者的权力】,关键是架构说明。依然只是简单提了一句,还是说的使用的是IEntry, 没发现什么变化:NBear的核心包括一个泛型、强类型的的数据持久化接口、一组接口式的Entity定义组件、高性能 XML/JSON序列化支持、服务工厂、分布式服务队列和Web组件。
国外
NHibernate for .NET
Release date: 03.11.2006
Requirements: .NET Framework 1.1 or 2.0
还未看,从java的Hibernate移植过来,如果没有利用CLR的特色,只是为了移植而移植,那就~~
DevExpress XPO
Lisence: 商用
还未看
http://www.howtoselectguides.com/dotnet/ormapping/ 这篇文章不错,告诉你如何选择ORM工具,以及列举出了国外常见的ORM工具【English】:
@2006-12-31 16:19:34
分词模块中主要是2大部分,首先是分词算法部分,然后就是词库部分。分词算法我们使用的是逆向最大匹配算法、语法效验、生词识别(基于上下文统计和语法效验)。这篇随笔主要说一下词库部分。
分词效率很大程度取决词库的设计,词库设计必须实现最大限度的查找匹配词。词库设计主要是2大部分,词数据部分和索引部分。
词数据部分:
我们将词按照长度不同分为不同的词类型,从长到短排列。在同一类型中按照词首字UTF-8内码从小到大排列。首字相同的词按照词频排列。
本文示例说明:{和|符号只是示例用,数据文件中不存在
示例:
{中华人们共和国|中华苏维埃政府}{数据文件|数据报表}
索引部分:索引部分包含统计数据和词索引,词索引是针对词首字的索引。索引记录的是首字的UTF-8内码和词偏移量。
总格式:系统版本号|拥有词量|拥有词类型量|各类型长度|各类型拥有词量|各类型拥有索引量|各类型词首字索引|索引开始地址|
各类型长度:类型长度|类型长度 (最短是2个字)
各类型拥有词量格式:拥有词量|...|拥有词量
各类型拥有索引量格式:索引量|...|索引量
各类型词首字索引格式:首字编码:第一个拥有该字偏移地址|n字编码:第1个拥有该字偏移地址} |...|长度类型n首字索引{首字编码:第一个拥有该字偏移地址|n字编码:第1个拥有该字偏移地址
在首字索引中,第一个拥有该字偏移地址相对地址,也是就是说该地址是所属词类型中的排列位数,需要通过转换才能得到实际地址。
使用类型说明:系统版本号是一个byte类型,词数量是int32类型,词类型长度数量是byte类型,n字词长度类型长度是byte类型,首字编码是3位byte 第一个拥有该字便宜地址是int32类型。
在具体使用该词库时,我们需要将整个索引部分解析到内存,解析后提供一个索引类,索引类包含版本号,拥有词类型量,每种词类型长度,每种词类型拥有词量,索引量,并换算出每种词类型第一个词在数据文件中的实际可读取偏移地址和第一个索引的实际偏移地址。换算出没类型索引的首字最大和最小UTF-8内码。
换算的办法是:感觉文件中记录的便宜量*数据类型所占用的位数。
比如:
前提条件:当前词库中拥有3个字长度和2个字长度的类型
2字长度词类型第一个词实际便宜量=3个字类型词量*3(3个字)*3(每个字UTF-8占用空间)+2*3
2字长度词类型第二个词实际便宜量=3个字类型词量*3(3个字)*3(每个字UTF-8占用空间)+2*3
通过这样处理后只有在加载的时候因为要换算一部分数据,数据略有影响,而在后去查询的时候由于索引数据载入到内存,并且基数数据换算完成了。那么速度就非常快。
同时在索引查询的时候可以通过比较最大和最小来加快索引,通过将索引不断的分为2部分,然后比较最大和最小,这样查找起来数据就非常快。查找索引数据后,可以直接将索引的偏移量转换成具体地址(类型首词实际地址+词偏移量*词类型长度*3),然后就可以逐步查找了。
这个格式的有点是查询速度很快,词库数量越大速度比纯文本词库就越快。但是添加和删除就很麻烦了。
有这方面经验的同志欢迎讨论哈。
源代码需要在分词系统测试完成后放出,不好意思了。
@2006-12-31 16:47:51
1.好像修改站点级的主题不太方便,web.config里的程序不好改。 Page.Theme的属性,每个页面都要写。有没有更好的办法能设置站点级的主题呢?继承Page麻烦,重写Page的Page_PreInit方法倒是可以,不过默认的直接是继承的System.Web.Page类啊。
@2007-1-5 10:43:36
看了一下visual web developer 中自带的个人站点,发现aspnet2.0里面的很多技术使用起来确实很优雅,比较典型的有 login控件和用户系统、MasterPage、主题和皮肤、SiteMap等等。这些特性,甚至不需要教程就可以很快上手。本文要介绍的是主题和皮肤的应用。 (一) 如何使用 1) 在你的应用里面添加 App_Themes 文件夹 2) 将主题相关的文件(包括.css,、.skin文件、其他资源文件包括图片、Flash等)组织到一个以主题名命名的文件夹中,将主题文件夹放于App_Themes目录。如果有多个主题,重复上述步骤。 Example : Css 文件(x.css)
@2007-1-5 10:44:36
主题是Microsoft ASP.NET 2.0 提供给开发人员的一项新增功能。 在 Asp.NET 2.0 出现以前, 给网站提供更换主题功能是一项繁重的工作,鉴于每切换一套主题,都需要在页面更改相应的图片、字体、网页样式等等细小的元素,因而在代码编写之余,更要求资源的规范管理。而往往在网站的编写初期,如果没有一定的经验,很难全面的考虑到资源文件的细致归类及放置问题。最终导致网站改版时,大量的迁移和更改,稍有不慎,还会引发文件丢失的问题。
@2007-1-5 10:46:49
1 foreach 和 for 的效率那个更高
这要看 所遍历的集合采用的数据结构,如果是顺序存储(比如数组),则for更快,如果采用链式存储,则采用foreach的效率更高
2 C# 访问修饰符的类型
五种而不是四种,不写任何修饰符的时候是private,而在java里面是package(不同于internal,internal表示同一个程序集,即使是两个名字空间)。
public>>internal protected>>internal<>protected>>private 共有五种
值得注意的是 internal protected 修饰符,表示可以在程序集内访问,也可以在派生类中访问。
3 ViewState和Session 那个更消耗服务器资源
通常情况下, Session 更消耗服务器内存资源,而ViewState因为涉及到编码和解码,所以比较消耗处理器资源;另外,在集群环境下,需要考虑Session的同步和复制带来的开销;如果Session保存于非Web进程,则需要考虑跨进程调用的开销;如果Session保存于数据库中,则要考虑数据访问的开销。
4 WebService vs Remoting
ASP.NET Web 服务基础结构通过将 SOAP 消息映射到方法调用,为 Web 服务提供了简单的 API。通过提供一种非常简单的编程模型(基于将 SOAP 消息交换映射到方法调用),它实现了此机制。ASP.NET Web 服务的客户端不需要了解用于创建它们的平台、对象模型或编程语言。而服务也不需要了解向它们发送消息的客户端。唯一的要求是:双方都要认可正在创建和使用的 SOAP 消息的格式,该格式是由使用 WSDL 和 XML 架构 (XSD) 表示的 Web 服务合约定义来定义的。
. NET Remoting 为分布式对象提供了一个基础结构。它使用既灵活又可扩展的管线向远程进程提供 .NET 的完全对象语义。ASP.NET Web 服务基于消息传递提供非常简单的编程模型,而 .NET Remoting 提供较为复杂的功能,包括支持通过值或引用传递对象、回调,以及多对象激活和生命周期管理策略等。要使用 .NET Remoting,客户端需要了解所有这些详细信息,简而言之,需要使用 .NET 建立客户端。.NET Remoting 管线还支持 SOAP 消息,但必须注意这并没有改变其对客户端的要求。如果 Remoting 端点提供 .NET 专用的对象语义,不管是否通过 SOAP,客户端必须理解它们。
5 WebService相关技术
SOAP:(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一个基于XML的协议,它包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。
WSDL:WSDL(Web Service Description Language)Web服务器描述语言是用XML文档来描述Web服务的标准,是Web服务的接口定义语言,由Ariba、Intel、IBM、MS等共同提出,通过WSDL,可描述Web服务的三个基本属性:
•服务做些什么——服务所提供的操作(方法)
•如何访问服务——和服务交互的数据格式以及必要协议
•服务位于何处——协议相关的地址,如URL
UDDI:(Universal Description, Discovery and Integration)统一描述、发现和集成协议,是为解决Web服务的发布和发现问题而制订的新一代基于Internet的电子商务技术标准。它包含一组基于Web的、分布式的Web服务信息注册中心的实现标准,以及一组使企业能将自己提供的Web服务注册到该中心的实现标准。UDDI利用SOAP消息来查找和注册Web服务。并为应用程序提供了一系列接口来访问注册中心。关于UDDI的详细内容可参考:http://www.uddi.org/
这三种技术互相都有联系,比如说 UDDI服务就是通过SOAP消息去发现Web服务。他们共同解决了 WebService 的发现、描述、访问的问题
6 override overload polymorphism(重写、重载、多态)
Override没有问题,关键是overload到底是否多态的一种实现方法?有人认为多态一定是迟绑定的,而overload并非迟绑定的,所以 overload跟多态没有关系;还有人说,多态的实现分override和overload两种形式,一种是类层次的,一种是方法层次的,或者说一种编译时多态,一种运行时多态;当然,也有人认为,overload根本不是面向对象独有的特性,在面向过程的语言中也同样存在。总之,对于这个问题,我比较倾向overload非多态实现的这种说法。
@2007-1-5 10:55:53
今天终于开始了EnterpriseLibrary的进程了,边看边学,在这里要感谢TerryLee前辈,看了你的文章得到了不少知识,让我更容易进入状态。由于刚刚接触到这个咚咚对他还有点陌生,无论是哪个项目配置文件肯定是我们研究的切入点,所以首先当然是要看看Enterprise Library对配置文件的一些做法。
@2007-1-5 11:06:05
我一直觉得Asp.Net2.0的Membership不够用,例如:不能自定义密码类型,不能获取角色Id,不能方便的检测用户名或Email是否存在……,总之还是不能完全满足自己的要求,那么就自己扩展吧,但是总是不那么爽,重新实现一套Provider吧,太麻烦了。今天偶然读到这个blog:《Source Code for the Built-in ASP.NET 2.0 Providers Now Available for Download》,发现可以下载其Provicer源码,这样可以在其基础上做我们自己的Provider了,省事多了!下载:http://download.microsoft.com/download/a/b/3/ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkitSamples.msi
@2007-1-5 11:09:48
摘要:asp.net 2.0的Membership组件提供了一组非常简单易用的接口供开发者进行用户管理,用户验证。本文将它对它的实现原理进行简单的分析,介绍如何正确的使用,以及如何对它进扩展。
@2007-1-5 11:15:10
ASP.NET 2.0中新增的最佳功能之一是新的成员身份服务,它提供了用于创建和管理用户帐户的易于使用的API。ASP.NET 1.x大规模引入了窗体身份验证,但仍然要求您编写相当数量的代码来执行实际操作中的窗体身份验证。成员身份服务填补了ASP.NET 1.x窗体身份验证服务的不足,并且使实现窗体身份验证变得比以前简单得多。
成员身份API通过两个新的类公开:Membership和MembershipUser。前者包含了用于创建用户、验证用户以及完成其他工作的静态方法。MembershipUser代表单个用户,它包含了用于检索和更改密码、获取上次登录日期以及完成类似工作的方法和属性。通过这两个新的类,我们可以不用写一行代码,方便得完成对用户的管理。 但是在实际开发过程中,绝对不能满足我们日常开发的需要。经过日常项目的开发和网络上资料的搜索,现将其一一列出:
一、默认的各类的数据库是使用sql express的,而我们在实际开发中往往使用sql sever 2000或者sql server 2005,这时就需要我们修改数据库的类型。
微软给我们提供了一个Aspnet_regsql的命令来修改默认数据库。打开 Visual Studio 2005 命令提示,输入aspnet_regsql,按照提示一步一步进行即可。
此时打开数据库,可以发现多处来了一系列"aspnet_"开头的存储过程,这就是我们使用membership所必需的存储过程。
此时打开IIS,[属性] →[ASP.NET] →[编辑配置]:
[常规],连接参数LocalSqlServer按照普通的sql连接字符串格式。
[身份验证],模式为Forms,管理提供程序的minRequiredNonalphanumericCharacters为0,这时就可以去掉默认变态的必需需要输入字母,数字等组合的密码安全了。此步也可修改密码最低长度和最大长度等等。
经过此步骤,系统会自动在web.config中配置好了我们所需的规则。很方便,修改web.config以后都可以通过这种图形化工具来了。
二、由于自带的login控件和membership类,只提供了简单的用户信息录入,不能满足我们项目的需要。例如:我们要用户注册的时候同时输入QQ号码,电话号码,家庭地址。那么默认的是没有办法解决的。我这里给出两种解决方案。我分别用在了不同的项目中。优缺点大家自行判断。
1、使用profile。此类方法网上教程已经很多。不在出重复叙述,免去赚稿费的嫌疑:)。这里只是给出网上没有的部分说明。
由于membership只能列出来指定组的用户名,而不能列出其他的详细信息,我们实际使用中,往往需要对组中的其它信息进行同时修改。我采用的是自行构造datatable的方法。见代码:
public static DataTable listuser(string userRoles)//列出指定组的用户信息 { string[] users = Roles.GetUsersInRole(userRoles); //列出指定组下的用户 DataTable dt = new DataTable(); dt.Columns.Add("username", System.Type.GetType("System.String")); dt.Columns.Add("QQ", System.Type.GetType("System.String")); dt.Columns.Add("phone", System.Type.GetType("System.String")); dt.Columns.Add("address", System.Type.GetType("System.String")); dt.Columns.Add("email", System.Type.GetType("System.String")); //以上构造一个数据表 foreach (string i in users) { DataRow dr = dt.NewRow(); MembershipUser mu = Membership.GetUser(i); 得到用户基本信息 ProfileCommon p = Profile.GetProfile(i); //得到用户的profile信息 dr[0] = mu. username; dr[1] = p. QQ; //profile是强类型,可以很方便的通过感知来添加。 dr[2] = p. phone; dr[3] = p. address; dr[4] = mu. email; dt.Rows.Add(dr); dt.AcceptChanges(); } return dt; } public static void deleteuser(string username)/删除指定用户 { Membership.DeleteUser(username); //系统会自动删除profile下的指定用户的信息 } public static void updateuser(string username)/更新指定用户 { ProfileCommon p = Profile.GetProfile(i); //得到用户的profile信息 p. phone="电话"; p. address="地址; p. QQ="QQ号码"; p.Save(); //保存所作修改。 } |
2、自定义一个membershipinfo表格,同membership系统标关联起来。自己编写SQL语句来进行查询,修改等功能。
列出指定组的用户 select * from aspnet_membership inner join aspnet_users on aspnet_membership.userid=aspnet_users.userid left join memberinfo on aspnet_membership.userid=memberinfo.userid where aspnet_membership.userid=(select userid from aspnet_usersinroles inner join aspnet_roles on aspnet_usersinroles.roleid=aspnet_roles.roleid where rolename='admin') |
删除、修改等功能比较简单,这里就不作叙述。可以采用membership的createuser方法建立,然后再用sql语句写入memberinfo表。
对于建立用户,我们可以采取扩展CreateUserWizard控件,或者自行写登陆界面。
@2007-1-5 11:16:37
在ASP.NET 2.0,新增加了不少新的功能和控件。其中,在数据的缓存功能,比asp.net 1.1有了很大的改变。众所周知,数据的缓存功能是十分重要的,我们可以把一些在相对一段时间内不发生改变的数据放在缓存中,这样,就不必要每次去读取数据库,当下次再需要这些数据时,可以直接从缓存中取得,大大增强了效率。
@2007-1-5 14:05:09
1、分别打开:editor/js/fckeditorcode_ie_1.js和/editor/js/fckeditorcode_gecko_1.js
找到
C.src.endsWith('.swf',true)
替换为:
C.src.endsWith('.swf',true) || C.src.endsWith('.wma',true) || C.src.endsWith('.wmv',true) || C.src.endsWith('.avi',true) || C.src.endsWith('.asx',true) || C.src.endsWith('.asp',true) || C.src.endsWith('.mov',true) || C.src.endsWith('.qt',true) || C.src.endsWith('.mp3',true) || C.src.endsWith('.rm',true) || C.src.endsWith('.ra',true) || C.src.endsWith('.rmvb',true) || C.src.endsWith('.mid',true) || C.src.endsWith('.ram',true)
2、打开/editor/dialog/fck_flash/fck_flash.js
增加
function WinPlayer(url){
var r, re;
re = /.(avi|wmv|asf|wma|mid|mp3|mpg)$/i;
r = url.match(re);
return r;
}
function RealPlayer(url){
var r, re;
re = /.(.rm|.ra|.rmvb|ram)$/i;
r = url.match(re);
return r;
}
function QuickTime(url){
var r, re;
re = /.(mov|qt)$/i;
r = url.match(re);
return r;
}
function FlashPlayer(url){
var r, re;
re = /.swf$/i;
r = url.match(re);
return r;
}
3、找到e.type = 'application/x-shockwave-flash' ;
替换为
if(WinPlayer(GetE('txtUrl').value)!=null){
e.type = 'application/x-mplayer2' ;
}
if(RealPlayer(GetE('txtUrl').value)!=null){
e.type = 'audio/x-pn-realaudio-plugin' ;
}
if(QuickTime(GetE('txtUrl').value)!=null){
e.type = 'video/quicktime' ;
}
if(FlashPlayer(GetE('txtUrl').value)!=null){
e.type = 'application/x-shockwave-flash' ;
e.pluginspage = 'http://www.macromedia.com/go/getflashplayer' ;
}
4、找到
SetAttribute( e, 'type' , 'application/x-shockwave-flash' ) ;
SetAttribute( e, 'pluginspage' , 'http://www.macromedia.com/go/getflashplayer' ) ;
替换为:
if(WinPlayer(GetE('txtUrl').value)!=null){
e.type = 'application/x-mplayer2' ;
SetAttribute( e, 'autostart', GetE('chkAutoPlay').checked ? 'true' : 'false' ) ;
}
if(RealPlayer(GetE('txtUrl').value)!=null){
e.type = 'audio/x-pn-realaudio-plugin' ;
SetAttribute( e, 'autostart', GetE('chkAutoPlay').checked ? 'true' : 'false' ) ;
}
if(QuickTime(GetE('txtUrl').value)!=null){
e.type = 'video/quicktime' ;
SetAttribute( e, 'autostart', GetE('chkAutoPlay').checked ? 'true' : 'false' ) ;
}
if(FlashPlayer(GetE('txtUrl').value)!=null){
e.type = 'application/x-shockwave-flash' ;
SetAttribute( e, 'scale', GetE('cmbScale').value ) ;
SetAttribute( e, 'menu', GetE('chkMenu').checked ? 'true' : 'false' );
SetAttribute( e, 'play', GetE('chkAutoPlay').checked ? 'true' : 'false' ) ;
}
@2007-1-16 9:51:00
有个朋友让我谈谈SharePoint2003的文件存储机制,正好这个月一直在做与SharePoint相关的工作,随便说说吧。有对SharePoint很熟悉的朋友也可以对我的理解加以指导和纠正。
@2007-1-17 8:19:31
COM:
tlbimp /out:interop.msxml2.dll msxml2.dll
非托管非COM动态链接库文件方法获取:
dumpbin /exports /out:method.txt sqlite3.dll 或者 link /dump /exports /out:method.txt sqlite3.dll
using System;
using System.Runtime.InteropServices;
class MainClass
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static int Main()
{
string myString;
Console.Write("Enter your message: ");
myString = Console.ReadLine();
return MessageBox(0, myString, "My Message Box", 0);
}
}
@2007-1-19 8:07:52
.NET Framework 工具
类型库导入程序 (Tlbimp.exe)
类型库导入程序将 COM 类型库中的类型定义转换为公共语言运行库程序集中的等效定义。Tlbimp.exe 的输出为二进制文件(程序集),该文件中包含在原始类型库中定义的类型的运行库元数据。可以使用诸如 Ildasm.exe 这样的工具检查此文件。
参数
| 参数 | 说明 |
|---|
tlbFile | 包含 COM 类型库的任意文件的名称。 |
| 选项 | 说明 |
|---|
/asmversion: versionNumber | 指定要生成的程序集的版本号。以 major.minor.build.revision 格式指定 versionNumber。 |
/delaysign | 向 Tlbimp.exe 指定使用延迟签名以强名称对结果程序集进行签名。此选项必须与 /keycontainer:、/keyfile: 或 /publickey: 选项一起指定。有关延迟签名进程的更多信息,请参见延迟为程序集签名。 |
/help | 显示该工具的命令语法和选项。 |
/keycontainer: containername | 使用在 containername 指定的密钥容器中找到的公钥/私钥对,签发具有强名称的结果程序集。 |
/keyfile: filename | 使用在 filename 中找到的发行者的正式公钥/私钥对,签发具有强名称的结果程序集。 |
/namespace: namespace | 指定在其中生成程序集的命名空间。 |
/noclassmembers | 防止 Tlbimp.exe 向类添加成员。这样可避免潜在的 TypeLoadException。 |
/nologo | 取消显示 Microsoft 启动标题。 |
/out: filename | 指定输出文件、程序集以及要写入元数据定义的命名空间的名称。如果类型库指定的接口定义语言 (IDL) 自定义属性显式控制该程序集的命名空间,则 /out 选项对程序集的命名空间没有影响。如果您没有指定此选项,则 Tlbimp.exe 将元数据写入与在输入文件内定义的实际类型库同名的文件中,并且为其分配 .dll 扩展名。如果输出文件的名称与输入文件的名称相同,则该工具将生成一个错误,以防止重写该类型库。 |
/primary | 生成指定类型库的主 interop 程序集。相关信息将被添加到该程序集中,以指示类型库的发行者已生成该程序集。通过指定主 interop 程序集,您可以将一个发行者的程序集与使用 Tlbimp.exe 从该类型库创建的任何其他程序集区分开来。如果您是正使用 Tlbimp.exe 导入的类型库的发行者,则只应使用 /primary 选项。请注意,您必须签发具有强名称的主 interop 程序集。有关更多信息,请参见主互操作程序集。 |
/publickey: filename | 指定包含用来签发结果程序集的公钥的文件。如果您指定了 /keyfile: 或 /keycontainer: 选项而非 /publickey:,则 Tlbimp.exe 将根据由 /keyfile: 或 /keycontainer: 提供的公钥/私钥对来生成公钥。publickey: 选项支持测试键和延迟签名方案。该文件采用由 Sn.exe 生成的格式。有关更多信息,请参见强名称工具 (Sn.exe) 中 Sn.exe 的 -p 选项。 |
/reference: filename | 指定程序集文件,用以解析对在当前类型库外定义的类型的引用。如果您没有指定 /reference 选项,Tlbimp.exe 将自动以递归的方式导入任何被导入的类型库引用的外部类型库。如果您指定了 /reference 选项,那么在导入其他类型库之前,该工具将尝试解析被引用程序集中的外部类型。 |
/silent | 取消显示成功消息。 |
/strictref | 如果此工具不能解析当前程序集、/reference 选项指定的程序集或已注册的主互操作程序集 (PIA) 内的所有引用,则不要导入类型库。 |
/strictref:nopia | 与 /strictref 相同,但忽略 PIA。 |
/sysarray | 指定该工具将 COM 样式 SafeArray 作为托管 System.Array 类类型导入。 |
/tlbreference: filename | 指定类型库文件,用于在不参考注册表的情况下解析类型库引用。 请注意,此选项不加载某些较早的类型库格式。但是,您仍可以通过注册表或当前目录隐式加载较早的类型库格式。 |
/transform: transformName | 按 transformName 参数的指定转换元数据。 指定 dispret 作为 transformName 参数,可以将仅支持调度的接口(调度接口)的方法的 [out, retval] 参数转换为返回值。 有关此选项的更多信息,请参见本主题后面的示例。 |
/unsafe | 在不进行 .NET Framework 安全检查的情况下生成接口。调用以此方式公开的方法可能会导致安全风险。如果您不了解公开此类代码的风险,则不应使用此选项。 |
/verbose | 指定详细模式;显示有关导入的类型库的附加信息。 |
/? | 显示该工具的命令语法和选项。 |
注意 |
|---|
Tlbimp.exe 的命令行选项不区分大小写,并可以按任何顺序提供。只需指定足够的选项来唯一标识它。因此,/n 与 /nologo 等效,/ou:outfile.dll 与 /out:outfile.dll 等效。 |
备注Tlbimp.exe 同时执行整个类型库的转换。该工具不能用于为在单个类型库中定义的类型子集生成类型信息。
能够将强名称分配给程序集通常是有用或必需的。因此,Tlbimp.exe 包括相应的选项,用以提供必需的信息来生成具有强名称的程序集。/keyfile: 和 /keycontainer: 选项均签发具有强名称的程序集。因此,一次只提供这些选项中的一个是合理的。
在从包含多个类型库的模块中导入类型库时,可以选择将资源 ID 追加到一个类型库文件中。只有当类型库文件位于当前目录或者您指定了完整的路径时,Tlbimp.exe 才能找到该文件。请参见本主题中后面的示例。
示例下面的命令所生成的程序集与在 myTest.tlb 中找到的类型库具有相同的名称,并且具有 .dll 扩展名。
下面的命令生成一个名为 myTest.dll 的程序集。
tlbimp myTest.tlb /out:myTest.dll
下面的命令生成一个名称与 MyModule.dll\1 所指定的类型库的名称相同且扩展名为 .dll 的程序集。MyModule.dll\1 必须位于当前目录中。
下面的命令为类型库 TestLib.dll 生成一个名为 myTestLib.dll 的程序集。/transform:dispret 选项将该类型库中的调度接口方法的任何 [out, retval] 参数转换为托管库中的返回值。
tlbimp TestLib.dll /transform:dispret /out:myTestLib.dll
上例中的类型库 TestLib.dll 包含一个名为 SomeMethod 的调度接口方法,它返回 void 且具有一个 [out, retval] 参数。下面的代码是 TestLib.dll 中 SomeMethod 的输入类型库方法签名。
void SomeMethod([out, retval] VARIANT_BOOL*);
指定 /transform:dispret 选项会使 Tlbimp.exe 将 SomeMethod 的 [out, retval] 参数转换为 bool 返回值。以下是当指定 /transform:dispret 选项时,Tlbimp.exe 为托管库 myTestLib.dll 中的 SomeMethod 生成的方法签名。
如果使用 Tlbimp.exe 生成 TestLib.dll 的托管库时没有指定 /transform:dispret,则该工具为托管库 myTestLib.dll 中的 SomeMethod 生成以下方法签名。
void SomeMethod(out bool x);
@2007-1-19 8:09:54
Everyone knows the ToolTip control (the programmer ones!!) which are included in the Common Controls version 4.0 since Win95 (that’s what saw first, I haven't ever caught the Win3.11). Since then the control itself have been modified and enhanced in many ways, and after a while, WinXP came to life and the Common Controls version 6.0 saw light with the Balloon ToolTip control included, which is the subject of this article. Neither creating a Balloon ToolTip nor implementing an IExtender is a new subject, not even a hard one, but getting the functionality of both techniques could have some attention, and that's what this article discusses: how to combine the good of both, in a way that's as simple as using the native .NET ToolTip control. While searching around, I found a great article about the Balloon ToolTip control (actually about the ToolTip control, in all its shapes and uses). This article (which could be found at CodeProject too) was a great reference to me and a good, live example of using the Balloon ToolTip control, but the control described suffered from its complexity (not a real complexity, but it had to be operated programmatically), something that pushed me to investigate the IExtender and to accomplish this work.
@2007-1-22 10:28:02
本文阐述了在基于.NET平台的应用程序开发中如何实现唯一应用程序运行实例,对几种实现方式进行分析测试比较,从而寻找一种合适的处理方式。单击此处才查看本文的示例代码。
@2007-1-23 9:23:23