

Code Soil
CODE SOIL - コードソイル [by Smalldust]
There are 37 Posts and 21 Comments so far.
Subscribe to Posts (Powered by feedburner)


CODE SOIL - コードソイル [by Smalldust]
There are 37 Posts and 21 Comments so far.
Subscribe to Posts (Powered by feedburner)
花了四天时间,终于上完了全部的课——这个又贵又长($2995,四整天)的培训,也给我这个玩了近半年VMware VI3的人带来了一些新的收获。
本次培训课程的全称是VMware Infrastructure 3: Install and Configure,是一套覆盖了从初级到中级的、全面介绍VI3的功能和具体用法的课程。对于有一定VI3基础的人来说,可能这个课程的前半部分过于简单,因此我也考虑过是否要参加VMware最新的课程:VMware Infrastructure 3: Deploy, Secure & Analyzer。后者主要涵盖中级到高级内容,包括scripting(我最想学的部分),security(也是极其重要的部分,应该包括了firewall的设置等很重要的内容),以及更深入的DRS和HA,最后还有问题分析的工具和方法(和我现在的业务关系紧密)。——但是,遗憾的是该课程目前在我们这里还没有,于是我只好选择了前者。
上课的形式是50%讲座,50%实习 (Hands-on)的形式,使用的机器全都在美国。我们通过教室里PC机上安装的Citrix终端远程访问位于美国VMware总部的工作站,再从那里远程访问ESX Server和VirtualCenter Server(感觉就是特别绕,经常用着用着就不知道自己在哪里了)。参加这个课程除了可以得到一套全英文的教材,还赠送一套VI3的CD-ROM(但是License要到VMware公司去下载试用版),另赠送一VMware帆布包。
闲话不多说,下面就是一些课堂上注意到的一些Tips。
Tip 1 VMware ESX Server 可以安装在单CPU系统上
VMware的很多技术文档中都明确说明,ESX必须安装在双CPU或更多CPU的系统上。的确,这是官方的说法,但是事实上在单CPU服务器上安装ESX也并不会导致出错、无法安装。不过,在了解了VMkernel的CPU调度的原理之后,可以很明显地看出单CPU、特别是单Core、不支持Hyperthreading的CPU将会大幅度拖慢系统性能,尤其是在VM的CPU使用率较高的时候。可想而知在这样的环境下VMware DRS/VMware HA是难以运行,或者行为异常。
因此作为测试来说,实在没有Dual CPU的机器单CPU的也凑合着用吧,不过最好有Hyperthreading功能。至于production环境,务必使用双CPU或更多CPU的服务器。
Tip 2 VMotion的充分必要条件
要使用VMotion功能(以及依靠VMotion的其它功能例如DRS),有无数条件需要满足,例如首先要有一个用于VMotion的VMkernel,此外被移动的VM必须是存储在SAN之类的共有设备上等等。关于两台ESX的CPU,VMware说需要compatible CPU,也就是说进行VMotion的两台ESX Server的CPU要兼容。什么是“兼容”呢?当然,如果你去看Basic Administration Guide可以获得既详细却又冗长的答案,这里就把VMotion对CPU的要求做一总结:
| CPU Characteristics | 是否需要完全相同? | 为什么? |
|---|---|---|
| CPU的个数,Core数,是否支持Hyperthreading,CPU的主频,缓存大小 | No | VMkernel已经通过虚拟技术使得VM不依赖于这些物理特性 |
| 制造商 (Intel还是AMD),Family (P4,Xeon还是Opteron) | Yes | 不同制造商、不同Family的CPU的指令集有细微的差别 |
| 是否有SSE3指令 | Yes | Guest OS上的程序有可能使用这些指令 |
| 硬件协助 (Virtualization Hardware Assist) | 32-bit VM: No | VMkernel已经通过虚拟技术使得VM不依赖于这些物理特性 |
| 64-bit VM on Intel: Yes |
目前在VMware中对Intel 64-bit的虚拟化是要依靠Intel的VT技术的 |
|
| Execution Disable | Yes (但是可以更改) |
Guest OS检测到NX/XD bit时就可能会利用这一特性(如Windows XP的数据执行保护) |
当然,与其要记住这么多,不如直接下载VMware提供的CPU Compatibility Tools,这个工具是专门为VMotion设计的,用来检查两台ESX Server的CPU兼容性。
Tip 3 Service Console是一个特殊的VM
很多人有一种误解,就是ESX Server启动之后看到的这个很像Linux界面——Service Console,就是ESX的OS本身。因此,很多人认为ESX Server是基于Linux的,或者说是安装在一个经过修改的Linux的上面的。
这种说法其实也不能说是完全错误,但是说ESX是构建在Linux之上的却是错误的——因为正相反,这个“Linux”也是运行在ESX之上的一个特殊的VM。
Service Console只被分配给一个CPU,无论物理服务器拥有多少个。这个CPU固定是CPU0,也即系统中的第一个逻辑CPU。和其他VM不同的是,Service Console可以直接和ESX的核心VMkenel打交道,进行系统管理操作。
此外,还有一些关于SAN的Multipathing,以及资源管理的话题,以后找时间专门说吧。
在前一篇文章中提到,VMware Workstation 6当中引入了众多server-like的新特性,这其中一个引人注目的特性就是可以不必打开Workstation的管理界面,而是在后台运行VM。这一功能使得Workstation可以在后台同时运行多个VM,在操作形式上更像VMware的Server系列产品了。
要使用这一功能很简单——只需要直接关闭Workstation的界面即可。关闭时它会提示你:是需要Suspend (挂起),Power Off还是Run in Background。选择Run in Background,Workstation就会关闭,但是VM继续运行。只需通过任务栏托盘里的图标,就可以在此打开该VM。
但是一个问题就是,不用打开Workstation就能在后台执行的确可以节省资源,可是要使用VM毕竟还要打开Workstation,难道就没有别的办法吗?
办法当然有,其一就是使用RDP或VNC等远程桌面协议。但是,无论是仅限于某些Windows平台的RDP也好,号称跨平台的VNC也好,甚至企业级的Citrix Presentation Server也罢,无需置疑都是在OS启动之后才能连接的。既然是虚拟PC,能否就算是OS启动前也能远程连接呢?此外像DOS这种根本不支持远程桌面的Guest OS又要如何远程使用呢?
显然,要远程使用Guest OS,不能依赖于该OS上特定的技术。VMware Workstation就提供了这样的一种凌驾于Guest OS之上的、与Guest OS完全无关的远程服务——Remote Display。
在Workstation 6当中,只要对某个Guest OS启动了Remote Display,就可以通过VNC协议连接并使用这一Guest OS。这里的VNC不同于直接在Guest OS上安装VNC,而是在虚拟化层中直接将输入输出按照VNC协议与远程的VNC Client进行通信,效率非常高。要使用这一功能,只需要在Guest OS的Setting中,将Remote Display设置为Enable,并选择一个端口号即可。
一切设置好之后,下载个免费的VNC Viewer连接试试看吧!需要注意的是,在使用VNC Viewer (Client)进行连接时,并不是连接Guest OS,而是连接Host也即Workstation所在的主机,因此不要填错主机地址。在虚拟机Power On到Power Off之间的任何时候都可以连接。
此外,不知为什么,在使用ReadVNC连接时,必须用Full Color进行连接,否则就会被VNC服务器(Workstation)断开。看着POST自检画面和Windows的启动LOGO出现在VNC上,是不是别有一番感受呢。
很多人都弄不清楚VMware Workstation和VMware Server之间到底有什么功能差别。从名字上看,Server似乎应该比Workstation功能更强,可是Server居然是免费的,Workstation反倒要花钱。两者之间到底有什么区别呢?
其实,首先从用途上分,正如VMware网站上所说的,Workstation是用来搭建测试、临时环境的,也就是说Workstation上面的Guest OS通常是为了测试、评估某个软件,或者是为了临时运行某个与当前系统不兼容的应用程序,通常不作为正式的系统、特别是服务器系统使用。而VMware Server则可以看成是VMware公司的旗舰产品——GSX的一个免费入门版,其上面通常会同时运行多个Guest OS,并且是作为稳定的服务器系统运行的,换句话说,一台服务器上安装了VMware Server之后,就可以作为几台虚拟服务器使用。从某种角度讲,如果在VMware Server上只运行一台VM,也就没有什么意义了。
那么,从技术角度上看两者有什么不同呢?VIRTUALIZATION.INFO在5月10日的一篇文章中,比较了两者的最新版本:VMware Workstation 6.0.0 (5月9日发布)和 VMware Server 1.0.3 (4月26日发布)。由于两者面向的市场不同,这个比较可能没有什么实际意义,但是由于在新版本的Workstation中包含了很多server-like的特性,在一些模棱两可的环境中还是值得参考的。
| VMware Workstation 6.0.0 | VMware Server 1.0.3 | |
|---|---|---|
| 作为Service启动 | No | Yes |
| 在系统启动时启动VM | No | Yes |
| Headless Interface | Yes | No |
| 本地管理 | UI+Command Line | UI+Command Line |
| 远程管理 | No | Yes |
| Virtual SMP (CPUs / VM) | 2 | 2 (experimental) |
| 支持Intel VT | Yes | Yes (experimental) |
| 每个VM的最大内存容量 | 8GB | 3.6GB |
| 所有VM的内存总和 | 无限制 | 最多64GB |
| 每个VM的IDE控制器/磁盘数 | 1/4 | 1/4 |
| 每个VM的SCSI控制器/磁盘数 | 1/7 | 4/60 |
| 每个VM的最大硬盘容量 (IDE/SCSI) | 950GB | 950GB |
| 每个VM的网络适配器数量 | 10个 | 4个 |
| 虚拟交换机数量 | 10个 | 9个 |
| 可否建立多个Snapshot | Yes | No |
| VM克隆 | Yes | Yes (需要VirtualCenter) |
| VM Recoding/Replaying | Yes (experimental) | No |
| VM Movie Capture | Yes | No |
| Host和Guest之间的Drag & Drop | Yes | No |
| 支持64-bit OS | Yes | Yes |
| 支持Para-virtualization | Yes (仅支持VMI3.0) | No |
| 价格 | $189 (网上下载) $209 (包装零售) |
免费 |
此外,VMware Server还不支持WinXP Home/Pro、Win2000 Pro等不是服务器版本的OS作为Host OS。
Capture和Record两个英文单词在中文中都有“记录”的涵义,但是在VMware Workstation 6中,这两项看上去相似实际上截然不同的功能常常会让没用过的人混淆。
Capture Movie是一项录制Guest OS为AVI视频的功能。这项功能非常适合用来做视频演示,例如演示一段关于某个新软件的使用方法等等。这一功能极其“傻瓜化”,只需要在启动Guest OS后,在VMware Workstation的菜单中选择VM > Capture Movie…,就会弹出一个对话框提示AVI保存的场所,以及画质(目前有高中低三种选项,并可选择忽略没有变化的帧)。之后,在窗口右下方的状态栏就会出现一个红色的圆表示正在录制中。录制过程中基本不会感觉到速度变慢等影响。
而Record/Replay则是Workstation 6中新增加的一个测试中的功能。该功能有些类似Snapshot——它不仅能记录下过去的某一点,而且会记录那一点之后到现在为止的期间中的所有系统的动作。这里的工作不仅包括鼠标键盘等输入动作,更包括内存、I/O等系统状态。该功能最大的用处就是,对于那些特别难以再现的系统现象(如BUG)一旦加以录制,就可以反复回放,极大地方便了程序特别是系统应用程序的DEBUG。
一点小小的遗憾的就是,由于目前Record/Replay功能不支持对虚拟外部设备的记录(想想也是,如果这些外部设备被移走了,读写外部设备的动作是无法再现的),在使用它之前必须移除VM设置中的USB Controller / 软驱 / 光驱 / 声音适配器 / SCSI设备 / LSI Logic Adapter,否则无法使用。另外,在录制过程中也要避免进行网络操作,否则将难以正确回放。
此外,设置了虚拟SMP的系统和64-bit OS也无法使用该功能。

VMware Converter是什么?对于经常使用VMware产品群的人来说,VMware Converter是一个不能不用的工具,主要用与各种虚拟机格式间的转换。
也许VMware老用户们会记得两个有名的工具:VMware P2V Assistant 和 VMware Virtual Machine Importer。前者大名鼎鼎是因为,它可以把一台物理计算机 (Physical Machine) 原封不动地转换为一台虚拟计算机 (Virtual Machine)。后者则是VMware为了与竞争对手抗衡,而推出的能够将其他形式的虚拟机映像(如微软的Virtual PC)转换为VMware的映像。
那么VMware Converter呢?VMware Converter就是上面两个工具合二为一,并且增添了众多新功能之后的新版本了。旧的P2V Assistant和VM Importer将不再有新版本,将会逐渐淡出市场。
VMware Converter有两个版本,入门的Starter版,企业级的Enterprise版本。Starter版是免费的,可以从VMware的主页上下载;而Enterprise版则是VirtualCenter Management Server的一部分,不单独出售。但是,除了要用VMware Converter进行大规模的、全自动的、企业级的转换之外,Starter版本和Enterprise版本基本上没有差别。这样,使用VMware Converter + VMware Player这两个免费产品,任何用户都可以把自己的电脑转换成虚拟PC,在虚拟世界里遨游一番了。
VMware Converter里最引人注目的,就是增强了的P2V (Physical to Virtual)功能了。VMware Converter 3里,有两种P2V方法:

0 comments smalldust | VDI & Virtualization | converter, p2v, vmware
今天在@IT网站看到一篇关于Expression Blend的文章,这篇文章开头部分对于.NET 3.0/WPF时代微软产品结构、地位作了简单介绍,觉得概括的很精妙,这里就加以借题发挥,做一个WPF入门。
什么是WPF?
要是到微软的网站查找答案,肯定能得到一大堆华丽却让人糊涂的辞藻。WPF (Windows Presentation Foundation)是.NET 3.0的一部分,是一种新的用户界面技术,用术语说是一种新的“图形子系统 (Graphic Subsystem)”。换句话说,在.NET 2.0当中我们可以开发两种应用程序:
那么在.NET 3.0当中,可以开发的应用程序又多了一种:
而WPF Application则又可以继续分成下面两种:
那么最近沸沸扬扬的Silverlight又是什么呢?Silverlight的前身是很早以前就万人期待的WPF/E,其中E的意义是Everywhere。众所周知,要想使用WPF,就必须安装.NET 3.0;而.NET 3.0虽然宣称跨平台,但目前还仅限于Windows XP以上版本。因此,WPF/E最初的目标,就是把WPF/XAML的丰富的用户界面表现能力带到各个平台。
带着这个目标,WPF/E经历了数十个月的秘密开发之后,作为Silverlight诞生了——其诞生之日起,就被人们命名为Flash杀手——因为它和Adobe的Flash太相似了。很多.NET程序员都乐了——以后可以用C#开发Flash了!从这一点,想必Silverlight的特点已经很清晰了:客户端是浏览器,在下载一个插件之后即可享受Silverlight带来的激动人心的用户体验了。
最后,用一张图表来总结各种产品的关系、地位:
0 comments smalldust | .Net Programming | silverlight, wpf, xbap
今天,正当我在Wordpress(版本:2.0.10)中开始一个新帖子,打算上传一张图片的时候,在点击了Upload按钮之后,出现的却是下面的这条消息:
The uploaded file could not be moved to .
奇怪,明明上传目录的权限都没问题,为什么会无法上传呢?查找了一下上面消息的来源,发现wp-admin/admin-functions.php的大概位于1776行处有如下代码:
可见,问题的原因是move_uploaded_file函数无法正常将文件拷贝所致。在允许显示错误信息后,可看到类似下面的错误信息:
Warning: move_uploaded_file(): SAFE MODE Restriction in effect. The script whose uid is 1525 is not allowed to access /somefolder/wp-content/uploads/2007/05 owned by uid 48 in /somefolder/wp-admin/admin-functions.php on line 1778
可见,这是因为SAFE MODE功能阻止了uid为1525的脚本访问uid为48的用户所拥有的上传目录(uploads/2007/05)。那么,什么是SAFE MODE呢?
SAFE MODE(安全模式)是为了解决共用服务器(例如一台服务器划分成多台虚拟主机的服务商)中的安全问题而被添加到PHP中的一种功能。该功能通过一些强制性的限制而提高安全性,但是反之这些限制使得程序受到约束,甚至产生问题。
SAFE MODE中很重要的一个功能就是,在PHP脚本进行文件系统操作时,对uid/gid进行比较、核查。当一个用户的脚本试图访问另一个用户的目录时,系统就会拒绝访问并给出上面那样的错误信息。
那么,为什么目录“uploads/2007/05”会是“另一个”用户的目录呢?这“另一个”用户,到底是谁呢?
继续调查,找到了创建这个目录的代码。该代码位于/wp-includes/functions-post.php的约867行开始的wp_mkdir_p()函数中:
问题就出在mkdir函数上面。在SAFE MODE模式下,PHP的mkdir()函数所创建的目录,owner并不是script,而是Apache。因此,上面消息中“uploads/2007/05”的owner ID 48,就是Apache进程的uid了。
由此可见,在不改变服务器端设置的前提下(跟服务商打交道比较麻烦,而且让他们更改SAFE MODE不大现实),要想解决这个问题,只能想办法不使用mkdir()了。幸好Wordpress里面,需要创建目录的也就是上传的时候,因此作为workaround,手动用ftp事先创建好每个月的上传目录就是了。因为ftp所使用的帐号是和自己的www服务挂钩的,因此不存在uid不同的问题。
那么,对于必须使用mkdir的程序,有什么办法呢?据说,PHP6里面就会取消SAFE MODE——不过,等PHP6大功告成,再等保守的服务提供商们更新换代,估计都到了Web 4.0时代了。目前的解决方案来说,既不改变服务器设置、也不对应用程序本身进行大规模的重新设计的workaround,就是以ftp_mkdir()替换mkdir()。原理就是因为ftp是以和script相同的用户操作文件系统的。当然,这个替换并不是简单的把mkdir换成ftp_mkdir,而是需要ftp服务器的IP地址,用户名和密码,很有局限性,使用前需要仔细权衡。
0 comments smalldust | Web Development | mkdir, safe mode, uid
和许多人一样,我也是在转移blog时才发现这个问题。虽然是一个很老的问题了,为避免沉痛教训,这里就把相关知识做一总结,以方便后人。
【现象】
本来我的blog是放在家里的服务器的,最近因为要迁到租用的主机上,就开始了搬家工作。首先是文件的拷贝,一切顺利;接下来是把数据库从家里的MySQL中导出,然后导入到主机提供商的MySQL上去。由于两边虽然MySQL版本不同(家里是5.x,租用的主机那边是4.1x),但是由于都安装有PMA(PHPMyAdmin),应该没什么问题。
这么想着,等我在家里的PMA里执行“导出”之后,就犯嘀咕了——怎么打开生成的sql文件一看,wp_posts的贴子内容都是乱码啊?通过查看了一下数据库、各个表,发现collation一栏里面写的都是utf8_general_ci……虽然不大懂collation,但是应该字符编码都是utf-8,怎么会是乱码呢?不管三七二十一,先导入到租用的主机上再说!——结果,导入到租用主机上,仍然是乱码。
【预备知识】
为了解决问题,有必要学习和复习一下相关的基础知识。
首先是MySQL里面关于character set(字符集)和collation(整理?我认为翻译成比较规则可能更贴切)的概念。
Character set顾名思义,就是字符、以及字符对应的编码的集合。例如简体中文字符集gb2312就包括简体中文中的所有规定汉字,以及每个汉字对应的代码。
Collation,是指比较字符的规则的集合。有了比较规则,才能够将一组数据排序——例如按照英文字母顺序排序、汉字按照拼音顺序排序等等。显然,针对同样一组字符集可以有不同的排序标准、规则。例如汉字可以按照拼音排序,也可以按照笔画多少排序。尤其是Unicode的字符集,由于其可以包含不同种类的语言,所以可以按照各种语言的排序方法排序。此外,完全按照字符在字符集里的编码进行比较的方式称为binary比较。
到了这里我们就容易理解了。举例来说,MySQL支持的gb2312字符集中,有gb2312_bin和gb2312_general_ci两种collation。很显然前者是binary比较规则,后者是一般的中文字符比较规则。
每种字符集都有其默认的collation。对于utf8字符集来说,其默认collation是utf8_general_ci。要获得MySQL里面支持的字符集和默认collation列表,可以使用SHOW CHARACTER SET语句:
mysql> SHOW CHARACTER SET; +----------+-----------------------------+---------------------+ | Charset | Description | Default collation | +----------+-----------------------------+---------------------+ | big5 | Big5 Traditional Chinese | big5_chinese_ci | | dec8 | DEC West European | dec8_swedish_ci | | cp850 | DOS West European | cp850_general_ci | ...
其次,是MySQL中,在哪些地方需要这些字符集和collation。总体上分,在MySQL的体系中有三处字符集和collation:服务器(数据),连接,客户端。乍一看体系清楚明了,其实并不是这样。下面就一一介绍。
[1] 服务器(数据)端的字符集和collation,可以分成四级逐层指定——server, database, table, column。当MySQL存取位于某一列(column)的数据时,如果column的字符集和collation没有指定,就会向上追溯table的;如果table也没有指定字符集和collation,就以database的字符集和collation作为默认值;如果database仍旧没有指定,那么就以服务器的字符集和collation作为默认值。
那么server的字符集和collation的默认值又是从哪里来的呢?答案是,配置文件(my.ini)和mysqld(或者mysqld-nt)的命令行参数中都可以指定。如果不幸的,你根本没有在my.ini或者命令行中指定,那么MySQL就会使用编译MySQL时指定的默认字符集——latin1。
但是,需要注意的是,如果安装MySQL时选择了多语言支持(一般用中文的都会选择吧),安装程序会自动在配置文件中设置default-character-set=utf8
这样,所有创建的数据库、表,除非明确指出使用其它字符集,都会默认的使用utf作为数据的字符集(同时使用utf8_general_ci作为默认collation,因为它是utf8的默认collation)。
相关系统变量
[2] 客户端。对于客户端传送来的literal string(例如INSERT,UPDATE语句当中的值),MySQL需要知道它们是什么编码。同时,MySQL返回给客户端的值(例如SELECT语句的返回值),也可以按照指定的编码返回。
相关系统变量
[3] 连接。用于连接的字符集和collation,是指MySQL在接受到客户端发送来的文本之后,转换成何种字符集,用什么规则进行比较。需要注意的是,如果是将文本和数据库中某个column的值比较,将优先使用该column的字符集和collation。
相关系统变量
【问题的分析】
有了上面的预备知识,我们就开始分析最初的问题:本来是应该作为UTF-8字符保存的数据,为什么到了数据库中就变成了“乱码”?而且这些乱码居然还能毫无问题地被wordpress显示?为什么一旦导入到租用的主机那里就不能正常显示了呢?
首先让我们来看一下,我家里的服务器上,MySQL的系统变量(System Variables)是如何设置的。
注意:因为一些系统变量是根据客户端不同而不同的,所以用mysql命令行登陆所看到的和PHP下看到的并不相同。此外,似乎也不能用PMA查看——似乎在PMA中也已经更改了默认的系统变量。因此,要查看PHP作为客户端时的默认系统变量,可以编写一个类似下面的PHP小程序:
其中$result就包含着所有系统变量。在我家里的服务器上得到了如下结果(以下只列出跟字符集有关的系统变量):
可见,默认的客户端编码、默认的连接编码是latin1——这也就是说,虽然实际上wordpress传递给MySQL的文本都是用UTF-8编码的,但是由于上述系统变量设置不当,这些UTF-8编码的文本被MySQL当作是latin1编码的,并且由于数据库本身是utf8,因此把这些“latin1文本”又转换成了utf8。这样,一个汉字居然需要6bytes(一个汉字作为UTF-8是3bytes,被当作latin1进行了转换,每个latin1字符转换成2bytes的UTF-8编码)。这就不难理解为什么数据库存储的是“乱码”了。
那么为什么这些“乱码”在wordpress显示时没问题呢?这是因为,character_set_result也是latin1,也就是说MySQL在取出数据交给wordpress时,把这些数据从utf8转换回latin1,然后wordpress将这些latin1又当作了utf8——正好是上面的逆过程。
那么,为什么到另一台服务器上面就无法正常显示了呢?请看看那台租用主机的系统变量设置:
可见,其默认的客户端编码是ujis。也就是说,MySQL把utf8数据取出后,将会转换成ujis并传递给wordpress。这经历了latin1 - utf8 - ujis转换的原本是utf8的字符,早已面目全非了……
【解决方案】
解决方案在很多论坛、网页上已经有提到了,在wordpress的trac也已经有人提出过。
但是在解决问题之前,我却很想知道一个问题的答案,那就是:这到底是MySQL的问题,还是PHP(特别是php_mysql extension)的问题,还是wordpress的问题?甚至是用户配置的问题?我倾向于认为这是一个wordpress的问题。因为无论MySQL还是PHP都不知道wordpress使用了什么字符编码,所以无法更改客户端字符集;而作为一般的wordpress用户,要求他们设置字符编码——可以,但是必须要提供一个用户界面,而不是直接修改源程序。
那么解决方案(或者说只是一个workaround)就是,修改wordpress的\wp-uncludes\wp-db.php。在第40多行的function wpdb中,在$this->select($dbname);之前添加一句
SET NAMES语句的功能就是,执行了SET NAMES 'x'相当于下面三条语句的功能。
这样,在默认客户端字符集是ujis的租用主机上,导入的wordpress文章也能正常显示了。当然,这不是彻底的解决方案——这只是“将错就错”,反正数据库里面存储的已经是被当作latin1而转换成utf8的utf8了,那么就将其转换回所谓的latin1就是了。这样做将使其他程序无法读取wordpress的数据,并且更重要的是,数据库中存储的“utf8数据”无法真正按照utf8应有的排序规则来排序。
那么最彻底的做法,就是在安装wordpress时就添加上面所说的SET NAMES语句,并且设置客户端的字符集为utf8:
但是这样做的话,已经被当作latin1写到数据库里面的文章就会无法正常显示了。要让他们正常显示,必须经过utf8 - latin1的转换。如果数量较多,可以考虑编写一个程序进行转换;数量较少的话……手动转换吧。
BTW,国内高手们汉化的中文版的wordpress中已经添加好这一句了,上面的信息只适用于那些使用英文wordpress的朋友,以及喜欢追根问底的朋友。
最后推荐一篇参考文章:Portable php-mysql connection charset fix
针对Microsoft Office系列的编程一直是比较麻烦的领域;这主要是因为Office里面大量的COM对象构成的庞大的体系结构让人望而生畏。
编写Outlook插件也是如此。虽然.Net的到来使得深入系统底层的RAD开发成为了可能,但是由于Outlook仍然是COM接口,要写Outlook插件,从根本上来说仍旧是编写Outlook COM插件的过程。凭借.Net和COM的互操作能力,才使得C#/VB.Net等语言编写的插件能够被Outlook等Office程序调用。
首先,无论是Outlook也好,Word也好,所有的Office应用程序都使用了共同的COM接口_IDTExtensibility2来与插件进行通信。因此,要开发一个Outlook插件(当然其他Office插件也一样),必须实现这个接口。这个接口定义在AddInDesigner Object Library当中,位于<drive>\Program Files\Common Files\DESIGNER\MSADDNDR.DLL文件中。在Visual Studio.Net当中,对这个COM接口进行了包装,包装后的Assembly名为Extensibility,该接口名为IDTExtensibility2。
下面就通过一个演示项目来说明一下。
在Outlook当中有一个BUG/设计缺陷,就是当回复、转发一封邮件的时候,这封回复/转发邮件的文字编码会自动变得和收到的邮件相同。例如,我经常从美国收到编码为US-ASCII的邮件,当我用中文添加一些评注,转发给中国人的朋友时,如果我忘记了手动把编码改成UTF-8或GB2312,邮件内容就会变成乱码。即便我在“新邮件选项”里面把新邮件的默认编码设置为UTF-8也没有用。
这种时候,如果有一个Outlook插件能够自动将所发送邮件的编码改成UTF-8有多好啊。于是,就有了下面的制作过程。
Step 1 创建Outlook插件项目
首先,在Visual Studio 2005(其他版本也可。这里以2005为例说明)中,新建一个Project,类型为Other Project Types > Extensibility > Shared Add-in,并在Application Host画面选择要使用这个Add-in的Office程序。这样一个Add-in Project就生成了。在这个Project当中,我们可以看到如下两个平时不常见的Reference被添加到了项目当中:
Step 2 实现IDTExtensibility2接口
打开Connect.cs文件,我们就可以看到VS已经帮我们创建好了一个叫做Connect的类,来实现IDTExtensibility2接口。这个接口和一般的Host/Add-in体系结构类似,内容如下:
void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom);
当COM add-in被连接到host应用程序时OnConnection事件将被触发。
简单实现上面几个接口的例子可以参考微软知识库的302901号文章。
Step 3 截获ItemSend事件 更改MailItem属性
实现了上面的接口,我们就要在其中添加代码了。由于我们的目的是在发送邮件时强制改变邮件的编码(encoding),因此只需要在OnConnection当中添加截获发送邮件的事件即可:
之后,我们就可以在事件函数中控制邮件的编码了:
在完成上面的代码之后,我们只需要打开Outlook,就可以测试这个插件的效果了。要确认该插件是否安装,可以在Outlook的菜单上选择Tools > Options > Other,然后按Advances Options按钮,COM Add-ins即可看到插件的列表,以及启用和禁用插件。
0 comments smalldust | .Net Programming | add in, interop, outlook
DDC和EDID是显示器硬件方面的技术标准,最早的标准诞生于1994年。该标准简单地说就是为了让计算机知道显示器的各种规格信息(如支持的分辨率模式,支持的刷新频率,支持的行场频范围,产品型号,生产厂商等等)的一个通信标准。这样,当显示器接到计算机上时,几乎不用做任何调整,系统(Windows)就可以自动为用户设置好显示器,达到了“即插即用”(Plug and Play)。
DDC是Display Data Channel的缩写,是display adapter(显示卡)和display device(显示器)之间的通信标准。所有的信息都将从显示器当中的ROM传送到显示卡。这个信息就叫做EDID(Extended Display Identification Data)。
当然,EDID里提供的信息毕竟是显示设备(显示器)所支持的各种规格,如果显示卡不支持,终于还是不会被系统支持。此外,由于驱动程序决定了显示卡的行为,因此有时候需要升级驱动程序以支持某一种特定的显示规格。
在Windows当中,Windows就是利用显示卡的DDC功能来获取所支持的显示模式、分辨率列表的。