August 2007 - Posts
说明:
CButton:在Blend 2中制作了一个ColorAnimation的Button,在Orcas中添加了一个DoubleAnimation
HelloWorld:分别使用XAML,C#,JavaScript(两种方式)的Hello World
JSInteration:JavaScript和托管代码进行交互,包括事件监听处理、方法调用
ShowHello+ShowHelloWeb:一个SL项目,一个Web Site,Web Site Link SL项目。SL + Ajax
下载:http://gadgets.chinacars.com/sl/sl.rar
之前提到了 VSTO 2005 SE (以下简称 Cypress) 开发的 Office 插件可能无法被装载,微软已经提供了修正此问题的更新程序。现在我们来探究一下引发此问题的根本原因——谁动了我的插件?
先了解一下 Cypress 针对 Office 2003 插件的基本装载原理。用 Cypress 开发的 Office 插件并不是直接被 Office 应用程序加载的,编译得到的 .NET 程序集没有被注册为 COM 组件,而是由一个 Cypress 提供的“Loader”加载。向 Office 应用程序注册插件信息的时候,COM 注册信息中“InprocServer32”实际上指向 Cypress Add-in Loader,并且提供一个清单文件(Manifest)告诉 Loader 真正应该加载的 .NET 程序集信息。这样做的好处有很多:各个 VSTO 开发的插件不会互相干扰(Loader 会为它们创建各自的应用程序域);Loader 还可以帮助检查插件的新版本、提供插件自动升级功能;还可以对插件程序集的安全权限进行控制等等。
至于 COM 注册信息,我们知道在 Windows 中有三个地方可以存放(不考虑 Wow64 的情况):
HKEY_CURRENT_USER\Software\Classes
HKEY_LOCAL_MACHINE\Software\Classes
HKEY_CLASS_ROOT (上面两个的合并版本)
在 Cypress 的 RTM 版本中,插件的 COM 注册信息被写入 HKEY_CURRENT_USER\Software\Classes。因为这样做可以保证开发人员不需要管理员权限就可以调试、部署。这种方法在 Windows 2000 / XP / 2003 的平台上没有任何问题。而在 Windows Vista 中,新的安全特性“Mandatory Integrity Control ”使包括 Office 2003 在内的 COM 应用程序行为发生了变化。如果应用程序是以“中等”或者更低的 Integrity Level 运行,COM 信息会从 HKEY_CLASS_ROOT 读取,包含了 Cypress 写入 HKEY_CURRENT_USER\Software\Classes 中的信息;但是如果应用程序以高于“中等”的 Integrity Level 运行(即“以管理员身份运行”),或者 UAC 关闭,COM 信息只从 HKEY_LOCAL_MACHINE 中读取。在这种情况下,Office 2003 无法找到 Cypress 插件写入的信息,所以就导致插件装载失败!
如果开发者在 Windows Vista 中“以管理员身份”启动 Visual Studio 2005,就会因为上述的原因无法在 IDE 中调试插件。因为此时的 Visual Studio 2005 进入调试模式启动的 Office 2003 程序默认也是“以管理员身份”运行的。
为了修正这个问题,Cypress 的修正程序将改变插件信息的写入行为:先尝试写入 HKLM,如果因为没有权限而失败,再写入 HKCU。这样,即便 Visual Studio 和 Office 2003 被提升为“管理员身份”运行,也能够保证插件的 COM 信息被找到。
值得开发人员注意的是,这次发布的 Cypress 修正程序并没有对插件工程配套的安装程序工程作任何修改(见图)。我们必须要自己在 HKLM 中添加和 HKCU 中同样的信息,才能保证插件安装在 Windows Vista 的机器上也可以完全正常工作。

最后顺带提一下,Office 2007 “天生”就认识 VSTO 开发的插件,所以就没有 Office 2003 那样的麻烦事儿了。
[原文地址] China - interesting opportunities!
[原文发表时间] Sunday, August 26, 2007 11:30 PM
Ni Hao !
几星期前我在中国(上海),有机会与我们上海的团队共度了一天。 令人非常兴奋的是,从无到有,我们的上海团队的建立仅仅花了一年的时间,并且现在他们正从事着一系列开发工具部(Developer Division)的创新开发和产品技术的工作。
我有机会观看了上海团队对他们正在进行的工作所作的演示——支持C++ 的类设计器,一套 VB 控件,功能增强了的架构师工具,等等。我还看到了一些对Express Blend、 VisualStudio、 Silverlight 和 Windows Presentation Foundation 进行的一些早期的应用:内置游戏、 多媒体广告和 HD 视频播放机。这些成果都来自于我们的开发团队、 微软开发和平台合作部以及我们的合作伙伴之间的良好合作。
另一件很吸引我的事情是中国开发人员数量的快速增长——对此的估计值约为年增长13%。每年中国有超过30万的电子工程/计算机专业的毕业生,并且这保证了中国开发人员社区在可以预见的未来仍将有非常健康的增长。中国拥有1.62亿互联网用户,是仅次于美国 (2.11亿互联网用户)的第二大用户群体,并且正在成为一个新技术的庞大使用群体。在中国的机会好得不可思议——作为一个消费者市场、 作为一个潜在的客户群、 作为一个庞大的开发人员基地、 作为一个强大的合作伙伴群体以及作为一个巨大的人才库。
我的上海团队很乐意帮我把我的网络日志翻译为中文。翻译开始后,我会在这里提供一个链到我的中文网络日志的链接,给那些希望阅读我的中文版网络日志的你们。
Namaste!
可能在下个月月中,我们部门将会向中国所有的CSS设计人员开放一个网站(目前我还不能透露这个网站的域名),并且同时展开一个CSS大赛。基本上的方式就是只要通过提交一个CSS以及图片组合的模板,就改变该网站的整个外观,以便让更多的开发人员/设计人员了解CSS的强大威力。在这个网站上进行这个赛事是我的创意。
当然这个创意的来源是来自于VisitMix,在这个网站当中有一个子栏目叫ReMix,这其实就是一个CSS大赛,在里面的Gallery当中,有很多网友上传的CSS模板,感兴趣的话,你只需要点击某一个item,就会把整个网站的外观风格完全变一个样子(其实这个创意可能最初来自于CSS禅意花园),记得在去年第一次见到这个网站的时候,感觉非常新奇,那时候就有一个想法,我可不可以把博客堂也做成这个样子?
大家都知道,无论是.Text还是后来的SubText或者BlogEngine,还有DasBlog,其实所使用的模板机制大同小异,除了CSS外,还都使用了类似于Master方式的一个文件来控制所有控件的布局,以便产生更多的风格。有没有可能把这个Master式的控制文件移掉,而只使用CSS或者图片呢?所以我就开始做了一个实验。但至少到现在为止,尚未解决一些关键性难题。以下这些问题我曾经向三位CSS高手求教,答案都是很难实现,或者只能兼容某种浏览器。
好了,以下是我的问题,如果大家有解答,欢迎直接通过邮件与我联系。(joy ^ joycode.com,把^替换为@)。
有以下的HTML架构,希望实现以下三种不同的用户体验,并且兼容IE 6+,Firefox 1.5+以上的浏览器。
<div id=”Header”>这是标题</div>
<div id=”Main”>
<div id=”Content”>这是主内容</div>
<div id=”Sidebar”>
<div id=”Stats”>
<ul><li>主页</li><li>目录1</li><li>目录2</li></ul>
</div>
<div class="other">这是其它内容</div>
</div>
</div>
<div id=”Footer”>这是结尾</div>
第一种布局:
| Header内容 |
| Sidebar内容(width:200px) | Content主内容(Width:Screen.Width-200px); |
| Footer内容 |
第二种布局
| Header内容 |
| Stats内容(Width:200px) | Content(Width:Screen.Width-400px) | Sidebar当中除Stats之外的内容(Width:200px) |
| Footer |
第三种布局
| Header内容 |
| Stats内容(由竖直排列改为水平排列) |
| Sidebar内容,除Stats之外的内容(width:200px) | Content内容(Width:Screen.Width-200px) |
| Footer内容 |
| 刚刚上网看了看,这本书是available的 Q: 这本书对我合适吗? A: 如果你正在计划学习(或者已经开始学习)SharePoint开发(“苍天啊,谁能告诉我,我应该如何开始啊...”),或者需要在短时间内迅速了解SharePoint开发(你的老板或客户:“给你1个月时间够了吧?到时候我希望看到一点东西...”),或者虽然很熟悉ASP.NET但对SharePoint没有任何概念(“Ft...这玩意儿太麻烦了,还是ASP.NET好使...”),或者正对着SharePoint SDK犯晕(“Kao...这说的是啥意思啊...”),那么这本书会对你很有用。 如果你已经脱离了“苦海”,比如没事就翻SharePoint SDK里面的Reference玩儿,或者常用Reflector看Microsoft.SharePoint.dll,甚至20分钟就用Visual Studio + Windows Workflow Foundation做一个像模像样的工作流顺便把别人唬得一楞一愣的,那么你已经不需要这本书了,你要做的仅仅是订阅一下Ted、Patrick等等人的blog,然后等着SharePoint Server 2007 SP1出来... |  |
企业服务优化原则中有下面一条原则,最近我优化一个企业服务时,对此有了特别深刻的体验,特整理本篇博客:
使用 COM 可封送的参数
如果企业服务组件的方法接受调用方传递数据时所用的参数,强烈建议您尽量使用 COM 和 .NET 之间易于封送的类型,例如:
? Boolean
? Byte、SByte
? Char
? DateTime
? Decimal
? Single、Double
? Guid
? Int16、UInt16、Int32、UInt32、Int64、UInt64
? IntPtr、UIntPtr
? String
如果仅使用这些类型,且要避免传递其他复杂的类型(例如 structures 或 arrays),.NET 序列化程序可以优化调用处理堆栈,并将调用直接序列化到线缆上(对于 RPC)或到虚拟线缆上(对于 LRPC)。这样,调用的执行速度更快。不过,如果您的方法要求复杂的类型,代码将使用通常的 DCOM 调用堆栈调用,这将产生额外的处理。
以上文字来自: .NET 企业服务性能
我最近优化的这个企业服务是CSDN新积分制论坛帖子列表企业服务缓存。
这个帖子列表缓存工作机制如下:
1、启动一个 ActivationOption.Server 的企业服务(ServicedComponent),这个企业服务是工作在一个独立的服务程序进程。
2、这个企业服务中,通过单件模式启用了一个缓存,缓存了CSDN每个大小论坛的帖子列表。
3、当WEB应用启动时候,把每个论坛,每种帖子列表的帖子都从数据库中获得,然后记录到缓存中。方便以后使用。
4、在优化前,这个版本的新积分制论坛并不是所有CSDN的论坛,有100左右的大小论坛,每个大小论坛又有6种帖子列表,每个帖子列表最多显示满足条件的500条记录。这样,初始化数据大致就需要 100*6*500 大致20万左右的数据需要初始化到帖子列表企业服务缓存。
下面是我做测试的三种情况:
1、优化前我代码逻辑:每一个论坛做一次初始化操作,也就是100个论坛调用企业服务的一个方法100次。
这样的代码逻辑,本地测试环境,完成初始化大致需要130秒左右。
2、我把这个初始化的代码,即从数据库获得并写到缓存的代码搬到企业服务内部执行,外部只需要传递一个简单的论坛编号即可。这样优化后,这个初始化过程大致需要40秒。
3、另外一种方法,我把100个论坛所有帖子列表的数据库都在企业服务外部计算好,然后一次性提交给企业服务,即企业服务这个初始化方法只调用一次,完成这个初始化大致需要190秒左右。
对比我做的上面三个测试情况,我们可以看到,业务逻辑没有发生任何变化,变化的只是企业服务接口参数发生变化了,把一些工作从企业服务外搬到了企业服务内部执行。三种情况对企业服务来说,差别就在于企业服务的参数发生变化了。
上面情况2的企业服务参数最简单,用的是Guid 类型的参数。
情况1和情况3用的是自定义的可序列化的类。
情况1企业服务调用了100次,情况3企业服务只调用了1次。
结论:
1、企业服务的参数要尽量使用 COM 和 .NET 之间易于封送的类型,而不是自己定义的实体和传递其他复杂的类型。
2、企业服务使用自己封装的实体或者复杂的类型,带来的性能损耗,比多次调用企业带来的损耗更厉害(对比情况1和情况3)
参考资料:
.NET 企业服务性能
刚刚过去的几个星期里,因公因私,连续的造访了济南、广州、深圳、香港、上海、南京、武汉、长沙……
终于回到北京,有时间写写东西,上上网了。
这篇跟技术无关,推荐给大家一个喜欢在名片背后画漫画的家伙:Hugh MacLeod

他其实还是个Web2.0市场策略顾问。
刚才想在自己的邮件机器上做一个 Outlook 插件的小实验,却发现 Visual Studio 2005 不能正确启动 Outlook 进入调试模式。感觉奇怪之余,马上想到“不能启动 Outlook”的真正原因可能是 Outlook 已经在内存中了。随后打开任务管理器证实了这一点。原来是 Windows Mobile Device Center 已经通过 COM 调用启动了 Outlook(同步数据用,无界面显示),所以 Visual Studio 2005 就无法再启动一个 Outlook 进程开始调试了。
解决方法就是断开 Windows Mobile 设备连接,WMDC 会释放对 Outlook 的 COM 引用;如果没有别的程序也保持着对 Outlook 的 COM 引用,那么 Outlook.exe 就会从内存中卸载。
平时一般都在专门的 Lab 机器上做实验,没有其它软件的干扰。如果在相对杂乱的环境里面做开发,务必要先排除其它软件可能造成的影响。特此记录。

我的一个同事杨华今天开始写博客了,第一篇就介绍了关于SharePoint传入/传出电子邮件的用法。
以前很多人发邮件问过我这些邮件设置怎么用,那么,请参考这篇文章吧:
http://www.cnblogs.com/yanghua/archive/2007/08/24/868380.html
由于 Visual Studio Tools 2005 第二版(代号 Cypress)早于 Windows Vista 发布,在后来发现了一些针对 Windows Vista 环境中用 Cypress 开发 Office 2003 插件时产生的问题。微软已经分别发布了一个设计时更新(Design Time,针对 Visual Studio)和一个运行时更新(Runtime,针对发布后的环境)。
下载地址分别如下:
建议开发环境/部署环境是 Windows Vista / Windows Server 2008 的 Cypress 用户安装这两个更新,可以避免一些麻烦哦!
本来打算在另外一个挺大的中文社区写写关于 VSTO / VSTA 的东西,但是那个社区的文章编辑器实在是太不好用,最终弃暗投明来了这里。
在这个Blog中,我会主要写一些关于 Visual Studio Tools for Office / Application 的技术文章,也会翻译一些资料和大家共享。希望我们可以通过 VSTO 这座桥梁,联结起强大的开发平台和办公平台,构建出最棒的应用!
我们要在这篇文章中将实现的功能:
如上图荧光笔画的地方所示:
我们需要通过编写服务程序的安装程序,把企业服务上面 Run application as NT Service 选择框的进行选中操作。
阅读本文基础:
如果你对企业服务不是很了解,可以阅读我之前写的一系列跟企业服务有关的博客。我书写的跟企业服务有关的系列文章可以访问以下链接。
http://blog.joycode.com/ghj/category/1320.aspx
如果你对编程控制企业服务根本不了解,需要首先阅读我之前写的这篇博客:
编程控制企业服务的行为
本文是在上述文章基础上的加深。
正文
编程控制企业服务的行为 这篇博客中我讲到,我们可以通过遍历 COMAdminCatalogCollection 来寻找到我们需要操作企业服务的某个属性,然后更新这个属性。这种做法适用于大多数编程操作企业服务属性。但是我们上面这个需求就无法用这种方式来作了。
我们遍历 COMAdminCatalogCollection 可以更新的属性时候,我们在微软提供的可操作属性列表(如下链接可以看到)中并没有找到可以设置 Run application as NT Service 的选项。
http://msdn2.microsoft.com/en-us/library/ms686107.aspx
只能看到一个可能跟这个需求有关的属性:
ServiceName
The service name corresponding to the application configured to run as an NT service. If this value is NULL, the application is not configured to run as an NT service. Otherwise, the configuration information for the service can be found by using the service name.
Access: ReadOnly
Type: String
Default: ""
Platform Requirements: Windows XP, Windows Server 2003
这个属性是只读的,我们又没法设置。
如何解决这个问题呢?
很简单,这个需求不是通过属性来指定的,而是通过 COMAdminCatalog 类的 CreateServiceForApplication 方法。
简单来说,我们就是要安装代码中有以下代码:
COMAdmin.COMAdminCatalog ca = new COMAdmin.COMAdminCatalogClass();
ca.CreateServiceForApplication(ApplicationName, NTServerName, "SERVICE_DEMAND_START", "SERVICE_ERROR_NORMAL", "", null, null, false);
CreateServiceForApplication 函数的定义如下:
HRESULT CreateServiceForApplication(
BSTR bstrApplicationIDOrName,
BSTR bstrServiceName,
BSTR bstrStartType,
BSTR bstrErrorControl,
BSTR bstrDependencies,
BSTR bstrRunAs,
BSTR bstrPassword,
VARIANT_BOOL bDesktopOk);
每个参数介绍如下:
bstrApplicationIDOrName
应用ID或者应用名字,我们安装这个企业服务后,在服务程序列表中,这个值就是我们看到的 NT Service 的Name 就是这个值。
bstrServiceName
服务名字,我们安装这个企业服务后,在服务程序列表中,这个值就是我们看到的 NT Service 的 Description 就是这个值。
bstrStartType
服务开始的几种情况,这里可以是下面几个值
SERVICE_BOOT_START, SERVICE_SYSTEM_START, SERVICE_AUTO_START, SERVICE_DEMAND_START, and SERVICE_DISABLED.
bstrErrorControl
服务错误发生时的情况,可以是以下几个值
SERVICE_ERROR_IGNORE, SERVICE_ERROR_NORMAL, SERVICE_ERROR_SEVERE, and SERVICE_ERROR_CRITICAL.
其他几个参数一般都比较固定,我直接Copy MSDN的说明。 bstrDependencies [in] A list of dependencies for the service. There are two possible formats for the string: a standard null-delimited, double-null-terminated string (exactly as documented for CreateService); or a script-friendly list of service names separated by "\" (an invalid character to have in a service name). The rpcss service is implicit in this parameter and does not need to be specified. bstrRunAs [in] The user name to run this service as. This may be NULL to indicate that it should run as Local Service. bstrPassword [in] The password for the system user account. This must be NULL if the service is configured to run as Local Service. bDesktopOk [in] Indicates whether or not the service should be allowed to interact with the desktop. This parameter is valid only when the service is marked as Local Service and must be FALSE otherwise.
参考资料:
Register your Enterprise Service App as NT Service
做了多个SL Project,其间多次发现无法Debug,即设置了BreakPoint但是无法Break,由于之前对此没有太重视,所以一直没有考虑这件事情,今天开始准备周五的提纲了才发现这是个必须找出原因的问题,所以花了点事情研究了一下,终于找到了原因所在:我的default browser是Maxthon 2,而Maxthon是单一Process,打开一个页面只是建一个Thread而已(或者从threadPool中取一个,这个没有研究过),当我每次Debug SL Project时,我的Maxthon都是打开状态,而他又是default browser,
,结果造成VS Debuger打开的不是一个独立的Process,没有Pid,所有VS Debuger没有权限去Break。从这个原理看,所有使用multi-tab的浏览器都会造成这个问题。包括firefox。
Visual Studio 2005 Extensions for WSS 1.1 CTP:下载,有哪些新东东
如果你痛苦于手工写BDC的定义文件,那么除了BDC Meta Manager可以帮你之外,MOSS SDK 1.2中也带了一个“官方”的定义文件编辑器。
每个程序员,都会有自己的技术梦想,想借自己手中的一点技术,做一些有意义的事情,这也是我们努力钻研技术的一点原动力——看着我们的梦想在努力后变成现实,那种快乐是没有什么能代替的^_^
我的第一个技术梦想是想做一个自己的个人主页,正是由于这个梦想将我引进了技术世界,从此和软件开发结缘。后来又有各种各样的技术梦想,正是这样一个个的梦想,让我对技术开发产生了浓厚的兴趣和激情,为了实现这些梦想,让我刻苦的钻研相关技术。
当年脚本还不太熟的时候,刚开始用msn messenger,觉得界面好酷啊,想要是能用网页来做一套一样多好,于是就开始留意和学习脚本知识,查MSDN,论坛发帖问人,不久做出来了可以以假乱真的Msn Messenger界面,后来又做了好多模拟windows程序的页面,例如模拟Msn Explorer的、模拟Windows Explorer的界面、模拟Media Play的、模拟小人在地图中行走等脚本。正是由于此,打下了良好的脚本基础。
刚毕业的时候,特别怀念学校,那时候学校没有自己的BBS,只能到其他BBS的西工大版块去寻找一下精神寄托,就特别想有一个属于我们工大校友同学自己的BBS,于是有了今天的开放实验室,有了CnForums,有了CCS。CCS一段时间之后,由于不满意CS的性能,以及基于CS本地化的种种不便,并且很想将自己多年Web开发的经验有一个总结,于是创建了Openlab项目,经历了各种技术障碍,牺牲了若干休息时间,到今天终于略有小成。
还有一些很有意思的梦想,例如我们项目组内部灌水成风,有专门的Chat邮件组用于灌水,有不少有意义的邮件,但是作为邮件不容易保存,一次重装系统很可能就丢了很多宝贵的邮件,所以当时JJ同学就提议能不能有一个程序可以把邮件都同步到论坛,当时还没有什么头绪,后来在Openlab开发期间,逐渐有了思路,并且基于Openlab框架完成了这一很有创意的梦想,将很多宝贵的历史邮件以论坛帖子形式保存了下来,甚至于邮件中的图片附件都可以保持原有格式。
邮件同步到论坛的成功,这又间接帮助我完成了另外一个梦想——刚毕业时公司网络是封禁的,除了邮件什么都用不成,就想能不能通过邮件来完成论坛的看帖发帖回帖,或者有时候看到有好玩的邮件想转到论坛,却没办法直接把邮件的内容发到论坛(里面很多本地图片)。在邮件同步论坛梦想实现后,解决了邮件格式到帖子格式转换的一大难题,要实现邮件发帖到论坛,最有效的方式就是自己写一个SmtpServer,于是开始尝试参照SMTP协议写简单的SmtpServer,经过多次的失败和努力,终于又实现了一个多年的梦想。
正是这样一个个技术的梦想,给我无限的激情,指引着我前进的方向。
你的技术梦想是什么?
More Posts
Next page »