During the WB Editor 2.5 testing, we found an interesting concurrency control issue. In this version, we allowed multiple program instance for ease of cross posting.
Now in multiple instance windows, user can setup blog server accounts differently. Which one is the winner?
“Last one wins” was disapproved by QA.
Maybe we need optimistic concurrency. I this case user will receive a dialog saying “another instance has modified the settings”, do you want to overwrite or discard or reload?
Another option is concurrency control with change notifications. Using FileSystemWatcher to detect changes of configuration file, but what should happen next in UI?
Tgas: WB Editor concurrency control Last one wins optimistic change notifications multiple instance blog cross posting FileSystemWatcher
May 10th, 2006
在 VSLive Toronto 上见到两个人物,Steve Lasker 和 Daniel Cazzulino
Steve Lasker 介绍了使用 SQL Server Everywhere 的 Occasionally Connected Systems。 SQL Server Everywhere(SQL/e) 何须人也?原来2-4年前做 Pocket PC 程序就相识,那时它叫 SQL Server CE,后来又叫 SQL Server Mobile。 Visual Studio 2005 带的 SQL Server Mobile 被限制只能运行在 Tablet PC 上。SQL/e 就是解除了这个限制的版本。SQL/e 因此能运行在台式 Windows 上。
SQL/e 计划在 2006年下半年发布。 Steve 演示了目前如何在 VS 2005 中试验开发的和可以通过 ClickOnce 安装的办法。
这就解决了一个版本 WB Editor 的数据库选择问题。 本来正在犹豫是否应该用 SQL Server 2005 Express (SQL/x)。这个家伙 55M,还需要 Admin 用户权限才能安装。 比较 SQL/x 和 SQL/e,SQL/e 才 1.4M。看来SQL/e 更加适合 WB Editor 3.0。
Daniel Cazzulino 讲的内容也很有用,将会在下一篇笔记内介绍。
May 8th, 2006
An icon in the system tray kept poping up a notification saying “Your computer is infected! …”. If clicked the message, it opens the browser and connects to spywarequake.com.
Scanned with Windows Defender and Windows Live Safety Center, they could not find anything …
Finally used the old Spy tool to catch that popup’s class name is “ballon window”. Then searched DLL to find out suprox.dll. In the registry:
[HKEY_CLASSES_ROOT\CLSID\{AC1B4DA2-12FA-31F2-1A7D-CD2B14E6AD4E}\InProcServer32]
@=”C:\WINDOWS\system32\suprox.dll”
“ThreadingModel”=”Apartment”
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\
CurrentVersion\Explorer\SharedTaskScheduler]
“{AC1B4DA2-12FA-31F2-1A7D-CD2B14E6AD4E}”=”USB Mouse Driver”
SharedTaskScheduler!, a new place to watch out.
Tags: system tray spyware malware spy tool clsid popup SharedTaskScheduler Your computer is infected
April 15th, 2006
Server Side
1. IIS Configuration - Directory Security Tab of Site / Virtual Root Properties
- Disable anonymous access
- Enable ONLY Integrated Windows Authentication
2. Web.config
<authentication mode=”Windows” />
<authorization>
<deny users=”?” />
</authorization>
<identity impersonate=”true” />
3. NTFS Security Tab of the physical folder
- Add allowed user / user group
Client Side (IE)
- Add the server IP / Machine name / domain name to Intranet Sites
- Bypass proxy for the server if proxy server causing problem
- IE Security Setting, select “Automatic logon only in Intranet zone”
March 7th, 2006
Flickr 是免费的图片发布和分享网站。最近被收购到 yahoo 旗下。
把图片存在 Flickr 然后连接到自己的 blog 中 是个很不错的做法。
WB Editor 2 已经支持直接上传图片到 Flickr 了。另外还会有一个插件,来管理和检索图片。
December 10th, 2005
开发个 Biztalk 系统真是颇费周折。记下一些经验备用。
1. Error about enlisting DTC.
Solution:
1) Turn off the RPC security on your Windows Server 2003 computers.
http://support.microsoft.com/default.aspx?scid=kb;en-us;839187
2) Turn off DTC authentication.
http://support.microsoft.com/default.aspx?scid=kb;en-us;884623
Error Messages:
Failed to execute SQL Statement. Please ensure that the supplied syntax is correct. An error occurred while enlisting in a distributed transaction.
2. Unable to deploy early bindings… Access is denied.
Solution: Add user id / group to Biztalk Admin group and SSO admin group
Error Messages:
[Microsoft.BizTalk.Deployment.DeploymentException] Unable to deploy early bindings.
[Microsoft.BizTalk.Deployment.Binding.BindingException] Failed updating binding information.
BindingException: Could not store transport type data for Primary Transport of Send Port ‘xxSendPort’ to config store. Access is denied.[Microsoft.BizTalk.ExplorerOM.BtsException] Could not store transport type data for Primary Transport of Send Port ‘xxSendPort’ to config store. Access is denied.
3. Event Log is full of ENTSSO events?
Solution: C:Program FilesCommon FilesEnterprise Single Sign-Onssoconfig -backupsecret mybackup.bak
Error Messages:
The master secret has not been backed up. If you lose the master secret all the information stored in the SSO system will be lost permanently and your systems may fail to work correctly. Please use the SSO admin tools to back up your master secret.
4. Cannot deploy without strong name
Solution: Assign strong name from within the BizTalk project’s properties window.
Error Messages:
[Microsoft.BizTalk.Deployment.DeploymentException] Unable to install the “….dll” assembly into the Global Assembly Cache. Exception: A strongly-named assembly is required.
[Microsoft.BizTalk.Gac.GacException] A strongly-named assembly is required.
5. Cannot Access Schema Based Message’s Property in the Expression Editor
Solution: Open the XSD, right click the property name, select Promote | Show Promotions ..
Promote the properties to be distinguished.
November 18th, 2005
搞定 支持 aspx 语法的 Template 引擎 后即开始编写 template以及试验从 windows forms 程序传递数据。在我的设计标准中,数据结构 Custom Object 有先于 DataSet,一般尽量避免 late-bound data binding:
< %#="" databinder.eval(container,="" "dataitem.title")="" %="">
而是建议 bind to cutom object:
< %#="" ((wbeditor.post)="" container.dataitem).title="" %="">‘>
asp.net web 系统是应该这么做的,但是用在 Template 引擎 中有个问题:asp.net host 固定要到 bin 目录下去找包含 WBEditor.Post 类定义的 DLL。从程序发布 (depolyment) 的观点来看,不是很舒服的结构。这种情况下 late-bound data binding 就很有用了。它不要依赖于 DLL,而是在 run-time 通过 reflection 去取值。
有趣的是 DataBinder.Eval 不仅仅能对付 Container.DataItem,还能用在 object 上。< %#="" databinder.eval(post,="" "createddate",="" "d")="" %="">
March 28th, 2005
最近需要一个 .NET 下的 Template 引擎来支持自定义网页模版。一般如 Velocity(java), Smarty(php) 等 Template 引擎都自带一套语法。而 CodeSmith 的概念是用 ASPX 语法。这个概念卖点不仅仅在于能直接用已经熟悉了的ASPX 语法,还在于能嵌入 inline code,并且能用 server control,例如 DataGrid DataList 和 Repeater。Template 本身可以用 WebMatrix 来编辑。所以是很酷的设计。
在 m3rlin 中找到了 hosting the ASP.NET runtime 的办法,包括创建新的 AppDomain 和 通过 HttpContext 传递数据等等。这样我有了能用在 windows forms 程序中的支持 ASPX 语法的 Template 引擎。
ps. Template 引擎通常可以用来做代码生成工具的核心。
March 28th, 2005
终于为下一版的 WB Editor 搞定了HTML 语法加亮编辑器。
老的编辑器的原理同这篇文章。它实现了实时染色的功能 (highlight on the fly),但是一篇文章新载入时,全文染色效率极差 (feel it’s being choked)。
想了很多办法试图分页,但不成功。于是开始分析 SharpDevelop 的编辑器和 JSource 的编辑器的代码。发现如果自己从头做工程量巨大。接着向 SharpDevelop 开发者询价,得到个目前无法支付的价格。
回头再想,全文染色慢的主要原因就是用 SelectionStart 和 SelectionLength 两个属性来操作。甚至根据 Syntax colorizing with Speller engine using TOM and CSAPI 一文,用了 TOM 接口也没有改观。
再研究,能不能直接生成 rtf,终于发现 Delphi 的文章 Automatic Syntax Highlighting Using a RichEdit Control 介绍了 rtf 的格式以及 Syntax Highlighting With RichEdit 一文给出了生成 HTML 语法加亮 rtf 的办法。
用我现成的 HTML Tokenizer 接上去一试效果很好,200 多K 的HTML 加亮没有延迟的感觉。准备升级 WB Editor 2 了。
March 24th, 2005
折腾了两天,才发现 OLE DB .NET 不支持 named parameters。
The SQL Server .NET data provider (SqlClient) supports named parameters. Therefore, when you use the SqlCommand object, you do not have add the parameters in any particular order, but the parameters must have the correct name. In this case, you must add the at sign (@) prefix to the parameter names.
Alternatively, the OLE DB .NET data provider does not support named parameters. Therefore, when you use the OleDbCommand object, you must add the parameters in the correct order (which is the same order that is defined at the backend stored procedure). In this case, you do not need to add the “@” prefix to the parameter names, and the parameter names do not have to match those that are defined at the stored procedure.
From: http://support.microsoft.com/kb/310071/EN-US/
另:Microsoft Support 开始用 URL Re-Write 技术了
March 18th, 2005
前文描述了.NET 为 Shareware 程序开发提供了许可证检测机制,使得开发者可以集中精力到如何验证许可证。
把一个信息经由不可信任的途径传达给接受者的时候,就需要进行加密。对于信息接受者来说,则需要确认信息的来源是来自正确的,就需要进行数字签名。Shareware 程序拥有者要告诉远在用户机器上的自己的程序用户有权使用这么个信息,是要加密的。因为你不想让其他人知道这个信息是如何表达的,更不能让人家如法炮制出相同的信息。
.NET 提供了加密和数字签名等现在用在网络安全方面的技术用到 Shareware 上是绝对好的。下面是用 .NET RSACryptoServiceProvider 的一个办法。
RSA 是一种非对称加密技术 Asymmetric Cryptography,即加密用的密码和解密用的密码是分开,相互不能推演的。如果知道了解密用的密码,无法知道加密用的密码。这比对称加密安全性好,因为 Shareware 总是需要一个密码用来解注册码,用对称加密的情况下,如果被人从程序中分析到了解密的密码,有可能复制注册机。而用非对称加密,即使解密的密码泄漏,也无法做出注册机。
1、生成和保存密码
创建个新的 RSACryptoServiceProvider 对象,.NET 就随机生成了密码。
RSACryptoServiceProvider 对象可以把密码输出成 xml。
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
Console.WriteLine(rsa.ToXmlString(true));
这个 xml 是要好好保存起来的秘密。其中包含了用来做注册机的加密用的 private key 和 将来在程序中用来解密的用 public key。
<RSAKeyValue>
<Modulus>…</Modulus>
<Exponent>…</Exponent>
<P>…</P>
<Q>…</Q>
<DP>…</DP>
<DQ>…</DQ>
<InverseQ>…</InverseQ>
<D>…</D>
</RSAKeyValue>
2、注册机
根据上面的密码 xml,可以这样生成注册机所需要的 RSACryptoServiceProvider 对象。然后用数字签名的办法生成注册码。
SignData 是做数字签名。它与单纯的加密解密有区别。
如果要变成注册码是这样一句话:某人于某时某地购买了我的软件。单纯的加密后的解密你会看到这句原话(从内存里什么地方挖出来)。而用数字签名办法,解密后看不到原话,而是一个单向计算出来的 Hash 值。所以对所传送的信息多了一层保护。RSACryptoServiceProvider 提供了直接的生成数字签名和验证数字签名的方法。
private static byte[]CreateKey()
{
byte[] digestInput = fileEncoding.GetBytes(GetRegistrationInfo());
RSACryptoServiceProvider RSAalg= new RSACryptoServiceProvider();
RSAalg.ImportParameters(GetPrivateKeyParam());
return RSAalg.SignData(digestInput, new SHA1CryptoServiceProvider());
}
private static string GetRegistrationInfo()
{
return GetValue(“NAME”)+GetValue(“PURCHASE_TIME”)+GetValue(“FROM”);
}
private static RSAParametersGetPrivateKeyParam()
{
RSAParameters param = new RSAParameters();
param.D= Convert.FromBase64String(“…”);
param.DP = Convert.FromBase64String(“…”);
param.DQ = Convert.FromBase64String(“…”);
param.Q = Convert.FromBase64String(“…”);
param.P = Convert.FromBase64String(“…”);
param.Exponent= Convert.FromBase64String(“…”);
param.Modulus= Convert.FromBase64String(“…”);
param.InverseQ= Convert.FromBase64String(“…”);
return param;
}
从 XML 中生成 private key 来制作数字签名,需要用到全部参数:D, DP, DQ, P, Q, Exponent, Modulus, InverseQ.
3、验证数字签名
在 Shareware 程序中,从密码 xml 文件生成验证数字签名所需要的 SACryptoServiceProvider 对象,然后请用户输入他的名字、以及购买软件的时间地点。组成一个句子:某人于某时某地购买了我的软件,用 SACryptoServiceProvider 验证一下它的数字签名是否符合注册机生成注册码。
private static bool VerifyKey(byte[]digestInput, byte[] signed)
{
RSACryptoServiceProviderRSAalg = new RSACryptoServiceProvider();
RSAalg.ImportParameters(GetPublicKeyParam());
return RSAalg.VerifyData(digestInput, new SHA1CryptoServiceProvider(),signed);
}
private static RSAParametersGetPublicKeyParam()
{
RSAParameters param = new RSAParameters();
param.Exponent = Convert.FromBase64String(“…”);
param.Modulus = Convert.FromBase64String(“…”);
return param;
}
从 XML 中生成 public key 来验证数字签名,只要用两个参数:Exponent, Modulus. 别人即使从你散发出去的程序本身破解得到了public key,没有其它多大用处。
当然,破解不仅仅是要得到密码。如果来个暴力破解,把你的程序反编译出来,把你的 public key 换成他的,与他自己的注册机配合的,那你不就被抢劫一空了,或者反编译出来删掉前文所述的 LicenseProvdier,或者 …….,还有很多办法。
.NET 提供的许可证监测机制,非对称加密是否能真正发挥,还得看程序本身的加扰程度。下一篇文章介绍。
Tags: shareware asymmetric cryptography rsa private key public key
March 16th, 2005
制作 Shareware 有三个关键点:
- 如何保护对象(程序),在创建对象的时候检测许可证 (License)。
- 加密/解密 用户信息和注册信息。
- 程序加扰 (obfuscate) 或者程序加密,反破解。
.NET 为前两者提供了基本支持,非常方便。这里先说检测许可证。许可证可以有通用注册码、验证用户名的注册码、验证用户机器的注册码等形式。当用户花钱购买了 Shareware 程序,Shareware 程序拥有者就会发送注册码给用户。(Share-It 有在线注册码生成功能,一收到钱立即自动生成注册码)。
Shareware 程序运行时要检测和验证用户是否具有有效的注册码,以决定用户是否能执行程序。
.NET 下的程序都是面向对象的,所以 .NET 在对象的创建机制上,提供了许可证检测的一个接口,Shareware 程序开发可以在此基础上加入自己的注册码验证算法。
.NET Licensing 一文介绍了许可证检测的办法:
[LicenseProviderAttribute(typeof(LicFileLicenseProvider))]
public class LicensedClass : IDisposable
{
private License license = null;
public LicensedClass()
{
license = LicenseManager.Validate(typeof(LicensedClass), this);
Console.WriteLine(“Hello from the licensed class.”);
}
public void Dispose()
{
if (license != null)
{
license.Dispose();
license = null;
}
}
}
有了这么个结构,程序开发可以把检测许可证交由 .NET 完成,而自己集中精力设计如何验证注册码。把上面的 LicFileLicenseProvider 换成自己的 Custom LicenseProvider。比如,不读文件而去读注册表,见:CodeGuru: Licensed Applications using the .NET Framework 。我的一些文章收藏 (RSS格式) 。
不论是从文件或者从注册表得到注册码,它包含了户是否可以运行程序的信息,而且它一定是只能 Shareware 程序拥有者说了算。因此这个信息是必须加密的。
.NET 提供了非对称加密 (Asymmetric Cryptography) 工具可以用来处理注册码。下一篇文章里继续介绍。
March 3rd, 2005
随着 WB Editor 2 的发布,它提出的口号是: Blogging is not just editing and posting. Feel the fun and the power with WB Editor 2.
在 再议 WB Editor 插件 一文中提到了不少浏览器无法实现的功能。这里再比较一下即使浏览器也用上了 htmlarea, FreeTextBox, CuteEditor, FCKEditor 等编辑器,也不能达到 WB Editor 提供的那种细致程度。
November 10th, 2004
2004 年 7 月 MSDN 的 IUIs and Web-Style Navigation in Windows Forms, Part 1 结合最近开发 WB Editor 的实践,引发了我对 Windows 程序界面设计的一些新感想。
WB Editor 是个典型的 Windows 程序。在开发过程中总是感觉它的界面不对劲,它应该面向最普通的计算机用户,而实际上它的界面却是令人望而生畏的。
阅读那篇文章后感觉它为 WB Editor 的界面问题提供了今后开发的方向,那就是 Web-Style。 按照上文,MS 正在把 Web-Style Navigation 的支持做到 Avalon (Longhorn 的显示部分) 里面。WB Editor 2.0 的目标之一也就尝试是 Web-Style Navigation。
我预计从现在开始,会看到越来越多 Windows 程序界面设计大量采用 Web-Style,这就是我所说的酝酿中的变革。
November 10th, 2004
曾经有人问,写 blog 用浏览器足够了,为什么还要 WB Editor 这样的工具?
答案很简单,WB Editor 提供了浏览器无法提供的功能。
试想在用 WB Editor 写作的时候,
- 可以用 webcam 拍张照片,插入文章。
- 可以随机插入一个名言警句。好好学习,天天向上 :-)。
- 可以接驳 GPS,把过去走过的路线下载到 blog 里面。
- 可以复制些文字,发个手机短信。
- ……
自从 WB Editor 有了插件支持,做些都不再是遥远的梦想。
现在已经有了插件做语法检查、快速排版、代码加亮。新近还完成了个插件,可以用来管理(自定义)所有插件的快捷键,正在制作 FTP 插件(用来上传文件)、连接分析插件(提取、保存文章中的连接,自动加连接) ……
真是不怕做不到,只怕想不到。
有了这些插件,为写 blog 增添无数的乐趣。
November 10th, 2004
BlogJet 的作者 Dmitry Chestnykh 和我打算建立一个关于 blog 客户端工具的 Wiki。网址是 blogclients.info 。我可以在那里介绍 WB Editor。
blog 客户端工具的境地十分奇特,它背负着 blog 服务器 bug 的黑锅。
对于 blog 服务器来说,web 界面是主要的,xml-rpc 支持是次要的,很多系统的 xml-rpc 错误百出。 WB Editor Knowledge Base 收录了很多服务器断的错误。为了研究 blog 服务器的问题,我都快成 PHP 专家了。
blog 服务器的 xml-rpc 支持还会变化,donews 关闭了 .Text 系统的 blog 部分,blogger.com 的 utf-8 支持坏掉了等等情况,用户第一个抱怨的是 blog 客户端工具不工作了。还很难解释。
November 10th, 2004
WB Editor 可以通过插件可以丰富其功能。比如,拼写检查、Wiki 排版、语法加亮插件等等。WB Editor 插件是外挂的软件模块。它编译成 DLL 的形式,当把它放到 WB Editor 的运行目录,WB Editor 能自动识别它。
November 10th, 2004
WYSIWYG 编辑器
WB Editor 的核心是大名鼎鼎的 Nikhil Kothari 的 HtmlEditor Control,它什么都好就是载入内容到编辑器去的方法是错的。它生成的 stream 不支持中文。于是我改进了它,中文、日文没有问题了。但是,如果 IE Encoding 用 UTF8,WB Editor 可能中文出乱码。后来在 http://www.itwriting.com/htmleditor 的 htmleditor 中找到了创建 unicode stream 的正确办法,还实现了印度文支持。
xhtml
WB Editor 无法连接 b2evo,因为 b2evo 要求输入为 xhtml。逼得我从 dasBlog 中挖掘出了个html formatting 工具包,也是 Nikhil Kothari 的作品。
安装程序
原先用 MAKEMSI 工具做的 WB Editor 安装程序有个缺点,就是无法检测并提醒用户去下载安装 .NET Framework。以至于不看 readme.txt 的用户不知道这一先决条件。受到 WiX for dummies 一文的启发,找到了个办法: 找来原始的 wbeditor.msi,再找来一个能检测 .NET 的 msi 。两个 msi 都用 wix 反编译出来 (用其 dark /x 工具),然后,把得到的两个 wix xml 文件巧妙地和并起来,最后用 candle 和 light 工具重新编译生成新的 msi。
HTML 语法加亮
参考了很多资料,总算做出了一个不闪烁的 html 加亮编辑器。但是自己非常不满意:相应速度不好,没有代码提示、自动完成、没有 as you type 语法检查。准备有空研究研究 SharpDevelop 里的编辑器。
插件技术
另文详细介绍。
November 10th, 2004
在 究竟什么是 blog 1 - 个人的网上日记 一文中,总结了 blog 的两大特点:个人特点和群体特点。
个人特点是指写什么发布什么应该是很自由的。
群体特点是在具有相同兴趣爱好者之间相互交流。
因此,blog 服务器应该有多个。其中一个是自己的所有文章的汇集,其他是 group blog。自己个人的服务器放全部的文章,并且分门别类地复制发送到其它 group blog 服务器上 (cross post)。
应该选什么样的blog 服务商?
blogger.com 等 blog 服务商把 blog 当作个人主页的扩展,这些比较适合架设个人 blog 服务器。 它甚至鼓励在 blog 里面放你自己 google adsense 广告。
另外一些 blog 服务商把 blog 当作论坛的扩展,这个比较适合 group blog 而不适合做个人 blog 服务器。因为它可能会
有个斑竹/管理员什么的来封杀你的内容。
在它自己的首页弄个无聊的阅读排行榜。
因为不知道什么人的内容不好关闭网站,影响你的文章发布。
不允许你放的 google 广告,而放进 (inject) 它自己的google 广告。
要加入 group blog,当然需要遵守它的规则和协议,由它限制内容、放进它的广告 …
而架设自己的个人 blog 服务器,应该有充分的自由,选择个人主页扩展型 blog 服务商为好,免费的服务也可能会有被加上它的页眉等,但是付钱就好了。
如果选不到好的 blog 服务商,自己租个web 服务器(虚拟主机),可以更加自由地架设自己的 blog 服务器,因为有很多现成的免费的软件。将在下文介绍。
November 10th, 2004
blog 是在网上写日记。可是,就象用 web 浏览器不是唯一看 blog 的方法一样,用 web 浏览器登陆 blog 服务器去写作也不是唯一的写作办法。
写作 blog 可以用专门的写作工具,称为 desktop blog editing tool 或者 posting tool。它们具有更好的类似 word 的操作界面,来更加容易直观控制排版。还可以把 blog 文章、草稿保存到自己机器的硬盘上。甚至还有些有趣的功能,例如,把 windows media player 里面正在播放的音乐信息,插入到你的 blog 中。
http://www.microsoft.com/windowsxp/windowsmediaplayer
/downloads/create.asp
这么好的东西。十分遗憾的是,能支持中文 blog 写作的工具,并不多见。为此,我专门制作了一个 WB Editor。
WB Editor 通过 IBlogExtension 挂接到支持这个接口的程序下,例如 SharpReader,RSS Bandit,NewsGator …
WB Editor 又通过 blogger API 和 metaWeblog API 连接众多支持这些标准的 blog 系统,例如,delphibbs, drupal, xoops, .text, b2, nuclues, pmachine, Moveable Type ……
都是标准化的东西,上下通吃,应该前途不错
November 10th, 2004
Next Posts
Previous Posts