2006年12月12日

CommunityServer中的页面布局都是由一些MasterPage定义,这些MasterPage页在定义布局的同时也给出了部分默认的填充内容(实现),可以把这些MasterPage看成是一个个的基类,而我们访问的都是一个个从这些基类派生的具体类,可以选择继承默认实现,也可以Override

这里用Default.aspx进行一个示例分析,结果如下图,其中淡绿部分在MasterPage中给出了默认内容。

Default.aspx中包含的控件MPContainer指定MasterPageHomeMaster.ascx,而HomeMaster.ascx中包含的控件MPContainer未指定MasterPage属性,因此默认为Master.ascx。因此Default.aspx通过HomeMaster.ascx包含了Master.ascx中的内容。

Master.ascx定义了页面布局。

Default.aspx剩下的内容就是指定页面布局中指定的各个MPRegion由哪些MPContent来填充。

CommunityServer中的页面都是模块化的,除了该页的个性内容外,都是通过声明一个个控件来组成,而这些控件的SKIN由对应的ASCX文件描述,往往控件中又包含子控件,子控件的SKIN又由子控件的ASCX文件描述。

CommunityServer中的各种应用的地址统一保存在SiteUrls.config文件中,如果需要自定义就需要查找并修改此文件。程序中用到的字符串都保存在Languages文件夹下对应语言的文件夹中的Resources.xml文件内。如果想汉化或修改显示的内容就是通过修改此文件内容实现。

2006年11月27日

自使用笔记本电脑以来,一直很在意看书时硬盘的噪音。以前是内存容量小,导致不断的硬盘缓存交换,现在笔记本的内存扩到768M,系统物理内存占用只有200M,看书时不翻页应该不读盘,为什么看书时硬盘还是每隔35秒就要响一下呢?

今天使用ProcessMonitor解决了一次,通过它显示系统对文件系统的访问情况,发现迅雷或Web迅雷一直周期性地访问硬盘。于是我把这两个软件都关闭,稍等片刻后,电脑彻底安静了。

这个工具真不错,不过长时间地开着它进行监视,同样会占用大量的内存,所以用完后或者关掉它或者停止监视。

2006年11月24日

年轻时喜欢变化,喜欢新鲜事物,对技术演变接受速度快,总体体验是刺激、兴奋,而且有足够的精力去沉浸,去探索,在不断学习的过程中,内心不断获得满足感。还记得刚开始学习写程序,使用汇编,通过调用BIOS,在一台386电脑屏幕上打印出一行字符,现在看起来微不足道的一件事,当时却兴奋不已,可以控制这机器的感觉真好,从此走进这片新天地。有那么多东西可以学习,与机器交互的过程单纯而愉快,经常独自研究到深夜。一本Undocumented DOSC的启动代码,谈到DOS内部机制,读完后感觉掌握了很多流行商业软件的关键技术,Cutting Edge的感觉真好。


现在InternetUndocment很少见,Overdocument则随处可见。


这时Windows开始进入视野了,DOS开始被称为一种小型操作系统,原来让人欣喜若狂的技巧突然无用武之地,最喜欢读的书成了Undocmented WindowsUnauthorized Windows95。那个时代真有意思,那么多Windowsdocuments,但真正让我理解Windows内部机制却是两本UndocumentedUnauthorized的书。原来高级的“菜单”、“按钮”技术成了基本配置,“常驻内存”被并行运行的程序代替。平台升级了,原来的很多问题不再是问题,但真想写软件时问题却一点没减少。


因为不喜欢MFC那种简陋地开发方式,转向VBDelphi这种RAD开发环境,学会在VB中操作指针后不满意VB生成的庞大执行文件,转向使用DelphiDOS时代我就在TCTP之间选择了TP,我属于喜欢PASCAL那类。学习过CC++,但用得最多的还是PASCAL


这时候.Net出现了,原来还在比较VCLMFC谁优谁劣,突然发现Microsoft竟然把类似VCL一样的类库集成到操作系统中去了。免费就可以下到.Net Framework SDK,免费就可以得到所有的编译器和整套的类库。使用Delphi成了隔靴搔痒,于是开始学习C#


现在.Net Framwork3.0Vista已在眼前,面对WPFWCFWWFLINQAtlas这一连串眼花缭乱的技术,感觉窒息。


了解原理,了解机制,不等于可以开发出有用的软件。但技术演变给我的时间好像只够理解它而不是开始利用它。也许让自己成为Evangelist更适合一些,而不是Developer


 

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年10月31日

一、人之初,性本善

一次与豆豆去超市,在下楼的电梯旁有一个垃圾筒,豆豆走到旁边突然蹲下去,用手去抓地上的一个什么东西,我和老婆跟在后面喊“豆豆,脏脏。。。”,就在这时豆豆把拣起来的纸扔进了垃圾筒里。

二、时刻注意自己的素质

豆豆爱面子,从1岁多就开始了。2006年春节,我们把豆豆带到她姥姥家住了几天。我们发现,豆豆在姥姥家表现的特别听话懂事,吃饭很自觉,一到晚上8点多,就拉着妈妈上床睡觉,我们和她姥姥都特别高兴,觉得生了个模范宝宝。过完年,豆豆回到我们家,一进家门,就象换了个人一样,不那么乖了。等到和爷爷奶奶回老家后,豆豆就更加“肆无忌惮”,更放松,更任性了。三个地点,三种表现。

前段时间国庆放假,我和老婆回老家。有一天带豆豆出去坐电马,就是那种“摇摇”。当豆豆走到电马前,不是一下跨进去,而是这儿看看,那儿摸摸。老婆拿出一元硬币说:“豆豆你坐上去,妈妈把钱放进去。”,豆豆不愿意,用小手从妈妈手中拿过来一元钱,还是这儿摸摸,那儿看看。老婆又说:“豆豆你自己来放。。。”,接着就要帮豆豆把钱投进去。豆豆还是不愿意,小手把钱攥的紧紧地,然后把妈妈挂在身上的包拉过来,要妈妈拉开拉链,我们都以为她要翻一翻妈妈的包,小宝宝都喜欢这样做。可是豆豆用小手把紧攥着的一元硬币放回到妈妈的包里。回家之后,我们高兴地把经过告诉奶奶,还说豆豆真懂事。可我妈妈说,上次豆豆和爷爷妈妈去坐电马,坐上去就不愿下来,花了7、8块钱呢。

三、会说话,懂事理

豆豆大了,说话已经很清楚了,而且越来越讲究“技巧”。

一次我妈妈给我打电话时说,在被问到爸爸好还是妈妈好时,豆豆说爸爸好。当时我就乐坏了,我妈妈还说,豆豆有一次自己突然说:“小雷坏死了!”(我老婆姓雷),我就更高兴啦。国庆结束后,我和老婆又离开老家回单位上班。在一次电话里,又问起豆豆爸爸妈妈哪个好,豆豆说爸爸好,然后再问她妈妈呢,豆豆说妈妈也好。奶奶在电话那边说,豆豆真会说话。

我妈妈还给我说了一件事:对门的邻居一天逗豆豆玩,拿了一根手指粗细的小木棍,假装要砸豆豆。豆豆跑到奶奶身后一站,说:“我站在奶奶前面,你不能砸到我的好奶奶!”我妈一听乐坏了,邻居说:你看,带孩子带出功劳来了吧。

 

2006年06月29日

这两天写了一个小程序,试用一下BackgroundWorker这个控件,发现一些文档之外的东西。
程序好象MSDN中的示例一样,有两个按钮,一个进度条。一个按钮是Start,一个按钮是Cancel,分别调用BackgroundWorker的RunWorkerAsync和CancelAsync。
BackgroundWorker几个事件都有,代码如下:
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int i = 0;
            while (i < 1000000)
            {
                if (this.backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                };
                i++;

                if (i % 1000 == 0)
                {
                    //System.Threading.Thread.Sleep(0);

                    backgroundWorker1.ReportProgress(i);
                };

            };
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
                this.progressBar1.Value = e.ProgressPercentage;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
          
            if(e.Cancelled)
                MessageBox.Show("Canceled");
            else
                if(e.Error!=null)
                    MessageBox.Show("Error");
                else
                    MessageBox.Show("Finished");
        }

文档中说即使调用了CancelAsync,可能是在DoWork事件最后一次检测CancellationPending之后,这样DoWork仍将执行完毕。在执行上面的程序时,点击Cancel按钮很难使进度停下来,在第一次Start后停的概率大一些,在几次Start后,Cancel按钮基本不响应,不管怎么点,DoWork将是执行完毕,显示“Finished”对话框。
开始我想,是不是DoWork早就执行结束了,而ReportProgress是按消息方式执行了,所以虽然点击了Cancel按钮,实际最后一次CancellationPending检测已经过去,结果就是看到进度条不停地走到头,再显示“Finished”。
但是这个解释不完美,程序响应也不完美,大多数时候,在点击了Start之后,Cancel按钮就不响应了,这没有达到使用BackgroundWorker控件的目的,使用这个控件本来就是为了生成更好用户响应的程序。
于是我在DoWork事件中加入了注释的一行,对Sleep的调用。这时不管进度条走到哪儿,都可以点击Cancel按钮,而且Cancel按钮也始终有用户响应指示(当鼠标移动到它上面时),点击之后,DoWork事件被中止,程序结果提示“Cancel”对话框。
Thread.Sleep(0)起的作用是主动把时间片交给其它线程,在没有它时,也许操作系统觉得执行DoWork的线程更重要,所以会分较长的时间片给它,而用户界面线程的时间片被ProgressChanged事件占用完了,从而导致用户界面失去响应。
为进一步证实以上猜测,我将DoWork事件中的ReportProgress和Sleep同时注释掉,这时虽然看不到进度变化,但Cancel按钮有响应,而且可以将DoWork事件中止。
更准确的解释需要对Windows线程调度细节更进一步的了解。
另外还有一个需要注意的地方是,调用CancelAsync之后,在DoWork事件中可以进行CancellationPending的检测,但当运行到RunWorkerCompleted事件时,CancellationPending状态已经改变了。所以必须要在DoWork中对DoWorkEventArgs 的Cancelled进行设置,以便在RunWorkerCompleted中进行检测,判断是执行完毕还是中途取消了。

2006年06月06日

豆豆是我的宝贝女儿,今年两岁,长得很是小巧,但颇有些神奇的地方,今天说的就是其中之一。


在我的家乡,鱼刺被称为“鱼卡”,简称“卡”。豆豆上次从老家回来,一岁半,不知道从什么时候开始,在喂她吃鱼时,她都会看着你说:“卡,有卡,卡不能吃”,那个“吃”字还拐着弯,奶声奶气,但又说得十分认真,听着非常好笑。每夹一次,她都会说一遍提醒你,生怕你不知道,而且声音不时还会突然提高,唯恐你听麻木了。


有几次,我真的不小心把卡混在鱼肉里喂给她,都被豆豆准确地发现,嘴里念着“卡,有卡”,然后把鱼肉和卡吐了出来。一边为自己的大意冒冷汗的同时,一边感叹着豆豆的神奇。


豆豆从生下来就“谨小慎微”,对自己特别小心。一次洗澡时,我一大意没扶住她,结果她一滑,差点淹到澡盆里。从此,豆豆每次洗澡,刚一下水,都是两手紧握盆边,以防不测。


一次给豆豆冲奶,温度有点高,把她烫了一下,从此豆豆在喝奶时,都先把奶嘴挡在外面,感觉一下温度,再慢慢把奶嘴含入嘴中。


不知道从什么时候开始,因为什么事情,豆豆每次在开始吃一样东西时,都是先试着尝一下,味道好才会吃,不会听大人的花言巧语。


也许正是我们这种大意的父母,才会培养出这种细心的儿女。

2006年05月23日

这一年多来,工作非常繁忙,每天上班被事情赶着走,经常加班,下班后仍然是一脑子事情,没有自己思考的时间,直到最近才得到些缓解。


我不喜欢这样的工作,这段人生只被一件事情占据太无趣了。为人打工是如此,不知道那些自己创业的人是什么感受。这样的工作让我找到一些做老板的感觉,也许真的自己做老板的时候,全部身心都投入到工作中去会觉得更值得。


老板没有退路,老板会非常投入的工作,也会希望员工与自己一样投入,为做到这一点,过去靠思想政治工作,现在靠企业文化。但从人的本性来说,这样的生活方式是不理想的。


Google可以允许员工拿出20%的工作时间来做自己感兴趣的事,顺应人的本性需要。其实对于Knowledge Worker,工作时间与工作绩效并不成正比。高技术公司靠的是人的脑力,而高技术人才追求的是个人价值的实现,技术方面的成就,Google的这种制度将两者协调的联系在一起。知识工作者不希望自己所有的工作时间在重复的做一件事情,他们更希望能有所创新,有所突破,不断进入新的领域,更希望将自己的长处发挥的淋漓尽致,这实际上也是企业对员工的期望。


马克思设想在共产主义社会,劳动成为人的第一需要,以前看来有点可笑,感觉和共产主义一样是遥远的事情。现在看来,这个论断的合理性在解决了温饱问题的人群中正在显现。人生来面临死亡,在基本生存需要得到满足的情况下,没有追求,没有自己喜欢做的事情称不上幸福。


当然这种劳动是劳动者自身需要的劳动,而不是被迫从事的劳动。当科技、社会进步到一定阶段,人类可以从被迫进行的劳动中解放出来,而是主动自发地去从事自己需要的工作,这应该是全人类的追求。


从某种角度说,Google公司部分进入了共产主义社会。

2006年05月06日

原来运行正常的软件今天出了问题,通过查看调试信息发现,最里层的错误信息是“加载类型库/DLL 时出错”,上网搜了一遍解决办法,未果,只能自己动手了。

这个软件出错的时候是使用System.Web.Mail进行邮件发送,而这个功能.Net Framework是调用CDO的COM控件实现的,根据出错信息可以猜到,可能是在加载包含此COM控件的文件时出了问题。那么是哪个文件呢?

使用.Net Reflector可以在System.Web.Mail命名空间中找到如下代码:

static CdoSysHelper()
{
      SmtpMail.CdoSysHelper._helper = new SmtpMail.LateBoundAccessHelper("CDO.Message");
}
CDO.Message就是COM控件的ProgID,可以在注册表中HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CDO.Message位置找到。
再通过CLSID找到包含控件的文件位置,在出错的机器上是
出错电脑的文件指向:
C:\Program Files\Common Files\Microsoft Shared\CDO\cdoex.dll,
而正常的电脑的文件指向:
C:\windows\system32\cdosys.dll
于是使用RegSvr32对原文件进行解除注册,并对正确文件进行注册后,一切恢复正常,命令如下:
RegSvr32 -u C:\Program Files\Common Files\Microsoft Shared\CDO\cdoex.dll
RegSvr32 C:\windows\system32\cdosys.dll
 
2005年07月08日

游戏有外挂,浏览器也有吗?

我把使用HTTP协议模拟浏览器动作的软件称为浏览器的外挂。

比如说有个网站,在登录之后可以访问一个表单,通过这个表单可以发送短消息。那么就可以编写一个winform外挂软件,实现自动登录网站,并将用户录入的内容通过HTTP提交,完成发送短消息的功能。

此类外挂软件有个很大的好处,就是如果软件被扩散出去,而你想使它失效时,只需改掉网站的登录密码即可。

我写过使用Websphere构建的网站的外挂,有时间把其中的经验分享一下。

2004年12月24日

 

配置Win2003的终端服务,使用Win2003的远程桌面

办公室有两台电脑,A17″液晶显示器,B15″CRT显示器,在使用远程桌面后,就可以只使用17″液晶了,感觉很爽。但为了达到这一目的,还是遇到了一些“坎坷”。

基本设置网上都有了,就不说了。远程的机器必须启动终端服务并允许远程连接。首先是访问远程桌面的工具,我先使用的是管理工具中的远程桌面,结果找不到如何设置成全屏的办法,上网一搜发现附件中通讯菜单下有个远程桌面连接,搞定。

在远程桌面连接中设定将远程计算机的音频带入本地计算机,并在远程计算机中安装了声卡驱动,结果怎么也听不到声音,MediaPlayer一播放就提示声卡出错,而且声音的播放设备始终是Microsoft RDP 音频驱动程序,不是我安装的声卡驱动程序(CMI8738)。这个RDP迷惑了我,实际上它是“远程桌面协议”的意思,这个驱动程序就是远程桌面的声音驱动程序。我的声卡驱动安装是没有问题的,明白这一点时我已反复安装了N遍。

其实不能播放声音的原因是远程计算机的终端服务设置中禁用了音频映射。在终端服务配置程序中打开对应连接的属性对话框,在客户端设置选项卡中清除禁用音频映射的设置就好了。

安装SQLServer2005 Express B2

由于安装的.NetFramework2.0B1不正确,因此安装SSX时报错。之前使用的是同事在BT上下载的VS Express B1版本,Express工具一套,但里面的.NetFramework2.0B1版本的BuildNo不是MS网站上的B1版本。

换成MS网站上的B1版本后安装成功。