﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>星光灿烂</title>
	<atom:link href="http://delphi.zijinshi.org/feed" rel="self" type="application/rss+xml" />
	<link>http://delphi.zijinshi.org</link>
	<description>听琴论剑山水间</description>
	<lastBuildDate>Wed, 15 Feb 2012 16:45:38 +0000</lastBuildDate>
	<language>zh-cn</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.2</generator>
		<item>
		<title>让程序只能加载一次</title>
		<link>http://delphi.zijinshi.org/archives/123</link>
		<comments>http://delphi.zijinshi.org/archives/123#comments</comments>
		<pubDate>Wed, 28 Dec 2011 16:27:25 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[技术相关]]></category>

		<guid isPermaLink="false">http://delphi.zijinshi.org/?p=123</guid>
		<description><![CDATA[很多时候，我们只允许某个程序加载一次。也就是说，不允许这个程序的两个进程同时运行。 要实现这个功能中，该怎么做呢？本文将讨论Java中是如何实现的。 我找到了如下几个备选方案。 &#160; 1.写文件。 此方法提出者的观点是这样的：当程序运行时，在某个文件临时文件中写一个标记1；在程序退出时把这个标记改成0。在程序加载时，检查这个文件中的标记值 是什么，如果是0，则意味这系统中没有程序的运行实例。此时可以继运行。如果是1，那就意味着程序已经加载了一个实例，这时就可以直接退出了。 理论上似乎是可以的，但现实往往没那么完美。假设，当程序运行时，临时文件中的标记已经改为1了，这个时候程序异常退出，或者此时强行关掉Java虚拟机呢？程序显然会终止运行，但是临时文件中的标记却停留在了1，而不是期望中的0。当再次加载程序时，显然它会错误地认为已经有一个实例在运行了。 所以，这条路走不通。 &#160; 2.从任务列表中查找进程名。 在DOS系统中，我们可以通过tasklist这个命令获取当前运行的所有进程。正好，Java给我们提供了一个运行可执行文件的方法，我们可以调用如下代码获取当前正在运行的所有进程。 Runtime.getRuntime().exec(&#34;tasklist&#34;); 于是，我们只要遍历所有的进程，只要发现进程列表中已经包含了程序名，那么就认为已经有一个实例在运行了。 但是，这样对吗？要知道，当我们运行java代码时，进程列表中显示的只是javaw.exe。也或者，把两个不同的可执行文件改成相同的文件名，在执行时，它们显示的也是相同的进程名。因此，这种方法也是靠不住的。 &#160; 3.通过JNI调用系统本地代码。 如果通过C或C++代码实现这样的功能，那是轻而易举的事情。如果我们先用C或C++代码写好判断当前程序是否已经有一个实例，然后通过JNI来调用C或C++实现的代码即可。 这条路行得通。 &#160; 4.占用端口。 如果不采用调用系统本地代码的方法，那么我们还有这种方法：占用端口。原理是当程序启动时，判断某个端口（往往设置成一个不常用的端口，如60000）是否被占用。如果占用，就证明此程序已经有一个实例在运行了。 当程序正常关闭或异常退出时，占用的端口会自动释放。 这条路也行得通，但必须注意端口号的选取。如果选取的是一个常用的端口或者正好其他的某个程序也使用了这个端口，那么这个方法就不工作了。 &#160; 5.文件锁。 最后，还有一个种方法，文件锁。 它的原理和占用端口相同，唯一的区别就是把占用端口变成了给文件加锁。在占用端口这种方法中，重要的是选取一个不常用的端口，在文件锁方法中，重要的是选择一个尽量不会重复的文件。当程序运行时，判断此文件是否加锁，如果已经加锁，说明此程序已经有一个实例在运行了，否则就给它加锁。 当程序正常关闭或异常退出时，会自己解锁。 &#160; 综上，如果对C或C++比较熟悉，或者不介意使用JNI，可以通过JNI调用本地代码的方法。如果只想使用Java实现，那么最好使用文件锁，当然，占用端口也可以。]]></description>
			<content:encoded><![CDATA[<div style="text-indent:18.0pt">很多时候，我们只允许某个程序加载一次。也就是说，不允许这个程序的两个进程同时运行。 要实现这个功能中，该怎么做呢？本文将讨论Java中是如何实现的。 我找到了如下几个备选方案。<span id="more-123"></span></div>
<div style="text-indent: 18pt;">&nbsp;</div>
<div style="margin-left:18.0pt;text-indent:-18.0pt;"><b><span>1.</span></b><strong><span style="font-family:宋体;">写文件。</span></strong></div>
<div style="text-indent:18.0pt">此方法提出者的观点是这样的：当程序运行时，在某个文件临时文件中写一个标记1；在程序退出时把这个标记改成0。在程序加载时，检查这个文件中的标记值 是什么，如果是0，则意味这系统中没有程序的运行实例。此时可以继运行。如果是1，那就意味着程序已经加载了一个实例，这时就可以直接退出了。 理论上似乎是可以的，但现实往往没那么完美。假设，当程序运行时，临时文件中的标记已经改为1了，这个时候程序异常退出，或者此时强行关掉Java虚拟机呢？程序显然会终止运行，但是临时文件中的标记却停留在了1，而不是期望中的0。当再次加载程序时，显然它会错误地认为已经有一个实例在运行了。 所以，这条路走不通。</div>
<div style="text-indent: 18pt;">&nbsp;</div>
<div style="margin-left:18.0pt;text-indent:-18.0pt;"><b><span>2.</span></b><strong><span style="font-family:宋体;">从任务列表中查找进程名。</span></strong></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">在DOS系统中，我们可以通过tasklist这个命令获取当前运行的所有进程。正好，Java给我们提供了一个运行可执行文件的方法，我们可以调用如下代码获取当前正在运行的所有进程。</span></div>
<div style="text-indent:24.0pt"><span style="font-family: &quot;Arial Unicode MS&quot;,&quot;sans-serif&quot;;">Runtime.getRuntime().exec(<span style="color: blue;">&quot;tasklist&quot;</span>); </span></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">于是，我们只要遍历所有的进程，只要发现进程列表中已经包含了程序名，那么就认为已经有一个实例在运行了。</span></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">但是，这样对吗？要知道，当我们运行java代码时，进程列表中显示的只是javaw.exe。也或者，把两个不同的可执行文件改成相同的文件名，在执行时，它们显示的也是相同的进程名。因此，这种方法也是靠不住的。</span></div>
<div style="text-indent: 24pt;">&nbsp;</div>
<div style="margin-left:18.0pt;text-indent:-18.0pt;"><b><span>3.</span></b><strong><span style="font-family:宋体;">通过JNI调用系统本地代码。</span></strong></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">如果通过C或C++代码实现这样的功能，那是轻而易举的事情。如果我们先用C或C++代码写好判断当前程序是否已经有一个实例，然后通过JNI来调用C或C++实现的代码即可。</span></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">这条路行得通。</span></div>
<div style="text-indent: 24pt;">&nbsp;</div>
<div style="margin-left:18.0pt;text-indent:-18.0pt;"><b><span>4.</span></b><strong><span style="font-family:宋体;">占用端口。</span></strong></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">如果不采用调用系统本地代码的方法，那么我们还有这种方法：占用端口。原理是当程序启动时，判断某个端口（往往设置成一个不常用的端口，如60000）是否被占用。如果占用，就证明此程序已经有一个实例在运行了。</span></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">当程序正常关闭或异常退出时，占用的端口会自动释放。</span></div>
<div style="text-indent:24.0pt"><span style="font-family: 宋体;">这条路也行得通，但必须注意端口号的选取。如果选取的是一个常用的端口或者正好其他的某个程序也使用了这个端口，那么这个方法就不工作了。</span></div>
<div style="text-indent: 24pt;">&nbsp;</div>
<div style="margin-left:18.0pt;text-indent:-18.0pt;"><b><span>5.</span></b><strong><span style="font-family:宋体;">文件锁。</span></strong></div>
<div style="text-indent:18.0pt;"><span style="font-family: 宋体;">最后，还有一个种方法，文件锁。</span></div>
<div style="text-indent:18.0pt;"><span style="font-family: 宋体;">它的原理和占用端口相同，唯一的区别就是把占用端口变成了给文件加锁。在占用端口这种方法中，重要的是选取一个不常用的端口，在文件锁方法中，重要的是选择一个尽量不会重复的文件。当程序运行时，判断此文件是否加锁，如果已经加锁，说明此程序已经有一个实例在运行了，否则就给它加锁。</span></div>
<div style="text-indent:18.0pt;"><span style="font-family: 宋体;">当程序正常关闭或异常退出时，会自己解锁。</span></div>
<div>&nbsp;</div>
<div style="text-indent:18.0pt"><span style="font-family: 宋体;">综上，如果对C或C++比较熟悉，或者不介意使用JNI，可以通过JNI调用本地代码的方法。如果只想使用Java实现，那么最好使用文件锁，当然，占用端口也可以。</span></div>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/123/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>星月天气更新</title>
		<link>http://delphi.zijinshi.org/archives/132</link>
		<comments>http://delphi.zijinshi.org/archives/132#comments</comments>
		<pubDate>Tue, 21 Jun 2011 23:38:02 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[软件共享]]></category>

		<guid isPermaLink="false">http://delphi.zijinshi.org/?p=132</guid>
		<description><![CDATA[　　星月天气版本由0.9.2升级到0.9.3，新增功能如下： 　　　　1.程序启动时，如果没有添加任何城市，那么进入设置选项的“添加城市”和“删除城市”菜单。 　　　　2.如果没有添加任何城市，进入“天气预报”菜单，系统提示“请先添加城市”。 　　　　3.如果没有添加任何城市，进入“删除城市”菜单，系统提示“尚未添加任何城市，无需删除”。 　　下载地址：星月天气]]></description>
			<content:encoded><![CDATA[<p>　　星月天气版本由0.9.2升级到0.9.3，新增功能如下：<br />
　　　　1.程序启动时，如果没有添加任何城市，那么进入设置选项的“添加城市”和“删除城市”菜单。<br />
　　　　2.如果没有添加任何城市，进入“天气预报”菜单，系统提示“请先添加城市”。<br />
　　　　3.如果没有添加任何城市，进入“删除城市”菜单，系统提示“尚未添加任何城市，无需删除”。<br />
　　下载地址：<a href="http://weather.zijinshi.org/downloads/MnS_Weather.jar">星月天气</a></p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/132/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The SWT FAQ中文(4)</title>
		<link>http://delphi.zijinshi.org/archives/119</link>
		<comments>http://delphi.zijinshi.org/archives/119#comments</comments>
		<pubDate>Sun, 10 Apr 2011 04:24:18 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[SWT faq]]></category>

		<guid isPermaLink="false">http://delphi.zijinshi.org/?p=119</guid>
		<description><![CDATA[英文原文：http://www.eclipse.org/swt/faq.php&#160; 版本：Version 1.0 The SWT FAQ 7.问: 怎样为我的平台编译Eclipse执行文件? 答：Eclipse是被二进制可执行文件加载。执行二进制文件后，它弹出进度画面，加载虚拟机。对于不同的窗口系统、操作系统和硬件构架，我们必须为之编译不同的二进制文件。要么从CVS代码库编译，要么从下载的eclipse SDK编译。 通过eclipse SDK编译可执行文件。 为了编译、运行eclipse，你需要JDK，版本要求1.4.2或更高，你可以从这个网页下载eclipse：http://www.eclipse.org/downloads/index.php. 下载后，解压缩。这样或自动创建一个目录：eclipse。这个目录我们称之为&#60;eclipseRoot&#62;。 在目录&#60;eclipseRoot&#62;/plugins/org.eclipse.platform.source_X.X.X中，找到under org.eclipse.platform_X.X.X目录下的文件launchersrc.zip。 解压缩文件launchersrc.zip，它会自动创建一个目录：library。 进入目录library/WS，这儿WS 是窗口系统的名称，例如win32、motif、gtk、photon或者carbon。在合适的.mak文件中找到每个_HOME 变量，修改它的值使路径正确。 运行build 命令（在Unix和Linux下面是sh build.sh，在Windows下是build.bat）。这样就会创建一个叫做eclipse的二进制加载文件。把eclipse二进制执行文件移动到目录 &#60;eclipseRoot&#62;下。 以上描述的原始内容由Colin R Devilbiss提供。 &#160; 8.问: 怎样编译64位的 SWT GTK? 按照以下的步骤提取64位的SWT GTK源代码进行编译。 打开Eclipse，从dev.eclipse.org下载如下的项目：: org.eclipse.swt、org.eclipse.swt.gtk.linux.x86_64、 org.eclipse.swt.tools。 打开org.eclipse.swt.gtk.linux.x86_64文件夹中的文件build.xml，运行Ant，执行build.xml 文件中定义的uild.nativeLibraries任务。 更新项目 org.eclipse.swt.gtk.linux.x86_64。 项目org.eclipse.swt.gtk.linux.x86_64 现在包括64位的本地库。64位的java和C代码已经被复制到目录org.eclipse.swt.gtk.linux.x86_64/src下。 &#160; (待续&#8230;)]]></description>
			<content:encoded><![CDATA[<p style="text-align: right;"><span style="font-size: 12px;">英文原文：<a href="http://www.eclipse.org/swt/faq.php">http://www.eclipse.org/swt/faq.php&nbsp;</a> 版本：Version 1.0</span></p>
<p><u><strong>The SWT FAQ</strong><strong> <br />
	</strong></u></p>
<dl>
<dt><strong>7.问: 怎样为我的平台编译Eclipse执行文件?</strong></dt>
<dd>答：Eclipse是被二进制可执行文件加载。执行二进制文件后，它弹出进度画面，加载虚拟机。对于不同的窗口系统、操作系统和硬件构架，我们必须为之编译不同的二进制文件。要么从CVS代码库编译，要么从下载的eclipse SDK编译。<span id="more-119"></span></p>
<p><strong>通过eclipse SDK编译可执行文件。</strong></p>
<ol>
<li>为了编译、运行eclipse，你需要JDK，版本要求1.4.2或更高，你可以从这个网页下载eclipse：<a href="http://www.eclipse.org/downloads/index.php">http://www.eclipse.org/downloads/index.php</a>.</li>
<li>下载后，解压缩。这样或自动创建一个目录：<tt>eclipse</tt>。这个目录我们称之为<em>&lt;eclipseRoot&gt;</em>。</li>
<li>在目录<tt><em>&lt;eclipseRoot&gt;</em>/plugins/org.eclipse.platform.source_X.X.X</tt>中，找到under <tt>org.eclipse.platform_X.X.X</tt>目录下的文件<tt>launchersrc.zip</tt>。</li>
<li>解压缩文件<tt>launchersrc.zip，它会自动创建一个目录：library。</tt></li>
<li>进入目录<tt>library/<em>WS</em></tt>，这儿<em>WS</em> 是窗口系统的名称，例如win32、motif、gtk、photon或者carbon。在合适的.mak文件中找到<tt>每个_HOME</tt> 变量，修改它的值使路径正确。</li>
<li>运行<tt>build</tt> 命令（在Unix和Linux下面是<strong>sh build.sh</strong>，在Windows下是<strong>build.bat</strong>）。这样就会创建一个叫做<tt>eclipse的二进制加载文件。把eclipse二进制执行文件移动到目录</tt> <em>&lt;eclipseRoot&gt;</em><tt>下。</tt></li>
</ol>
<p>以上描述的原始内容由Colin R Devilbiss提供。</p>
<p>&nbsp;</p>
</dd>
<dt><strong>8.问: 怎样编译64位的 SWT GTK?</strong></dt>
<dd>按照以下的步骤提取64位的SWT GTK源代码进行编译。</p>
<ol>
<li>打开Eclipse，从dev.eclipse.org下载如下的项目：: org.eclipse.swt、org.eclipse.swt.gtk.linux.x86_64、 org.eclipse.swt.tools。</li>
<li>打开org.eclipse.swt.gtk.linux.x86_64文件夹中的文件build.xml，运行Ant，执行build.xml 文件中定义的uild.nativeLibraries任务。</li>
<li>更新项目 org.eclipse.swt.gtk.linux.x86_64。</li>
</ol>
<p>项目org.eclipse.swt.gtk.linux.x86_64 现在包括64位的本地库。64位的java和C代码已经被复制到目录org.eclipse.swt.gtk.linux.x86_64/src下。</p>
</dd>
</dl>
<p>&nbsp;</p>
<dl></dl>
<p>(待续&hellip;)</p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/119/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用AutoIt自动安装和卸载程序</title>
		<link>http://delphi.zijinshi.org/archives/102</link>
		<comments>http://delphi.zijinshi.org/archives/102#comments</comments>
		<pubDate>Fri, 26 Nov 2010 06:43:46 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[技术相关]]></category>

		<guid isPermaLink="false">http://delphi.zijinshi.org/?p=102</guid>
		<description><![CDATA[　　由于代码每天都会更新，编译组每天晚上会针对当天的代码编译出一个新的Build（除非编译不通过），而测试组第二天早上都会安装前一天晚上编译出的Build进行测试。 　　一直以为测试组每天都手动地重复着这些枯燥无味的卸载、安装工作，直到同组的一个同事告诉我，测试组每天的卸载和安装工作都是通过脚本自动实现的，无需人为干预。 　　原来他们使用了一款叫做AutoIt的工具。个人以为，要实现这种自动化的功能，要么让程序以控制鼠标或键盘的方式进行实际的操作，要么让程序通过给系统发消息的方式模拟鼠标和键盘的操作。无论使用哪种方式，要写一个通用的工具，工作量还是比较大的。而这款现成的软件，正好实现了期望中的功能。 　　出于好奇的心理，从官方网站上下载了安装文件autoit-v3-setup.exe。安装完后，我们可以看到AutoIt不仅附有很详细的文档，而且还提供了丰富的样例。这种脚本比较简单，很容易上手。 原理和应用范围 　　AutoIt把Windows系统的API封装成易用的Script函数。通过调用这些函数，我们就能很容易地让程序模拟鼠标和键盘的操作。当调用某些函数的时候，相当于我们对鼠标或键盘做了相应的操作。AutoIt的脚本非常简单，我们只需要写一段比较简洁的脚本，调用某些函数就可实现模拟键盘或鼠标操作的功能。如果用C/C++来实现相同功能，代码量可能就不仅仅是一两行了。 　　在批量的自动化处理或重复性任务的处理时，使用AutoIt可以大幅减少我们的工作量。比如说，每天定时让程序自动卸载、自动安装一次。 实现自己的安装/卸载程序 　　这儿，我尝试着写了一个能够让AutoIt自动安装和卸载的脚本。包括2个脚本：1.自动安装AutoIt3；2.自动卸载AutoIt3。 　　由于AutoIt不支持Debug（或许可以通过某些方式或第三方工具实现Debug的功能，但至少我没发现），我通过写Log文件来排查错误。每执行一个操作，都会在Log文件中记下执行的操作。 1.运行步骤 　　• 自动安装： 　　1) 先判断AutoIt的默认安装文件夹中是否存在Uninstall.exe文件，如果存在，则说明AutoIt已经安装，否则表明尚未安装。（在实际情况中，Uninstall.exe是否存在与程序是否已经安装并没有直接的关系，此处之所以这么做是为了简化判断。同样，在安装的时候，用户可以自定义安装目录，为了简化操作，此处我使用了默认安装路径&#8221;C:\Program Files\AutoIt3\&#8221;。) 　　2) 如果AutoIt已经安装，那么直接退出安装，否则进入步骤3； 　　3) 通过自动点击Next按钮进行安装AutoIt。安装完成后，点击Finish，退出。 　　• 自动卸载： 　　1) 先判断AutoIt的默认安装文件夹中是否存在Uninstall.exe文件，如果存在，则进入步骤2，否则表明Uninstall文件不存在，那么退出卸载。 　　2) 通过自动点击Next按钮进行安装AutoIt。安装完成后，点击Close，退出。 稍加说明：我的运行环境是英文Windows XP，实际的情况可能因为操作系统、运行环境和安装程序的差异稍有不同。在这个例子里，为了避免操作复杂化，我并没有把运行环境的所有可能情况都考虑进去，程序也没有异常处理。 2.代码编写 　　尽管可以使用文本编辑器或其他文本处理软件编辑源代码，不过使用AutoIt自带的编辑器会更加方便。在本文的最后，提供了源代码链接。 　　现在，我们可以开始编写代码了。首先，我们写自动安装的程序。 　　记得前面，我们提到过，AutoIt不支持Debug。因此，我们只好通过写Log的方式排错。在每次执行程序之前，我们必须先删掉以前的Log文件，然后判断Uninstall.exe文件是否存在，如果存在，则在Log文件中写上“Already Installed.”，并退出程序；否则在Log文件中记下“Starting Install”。代码如下： [java] 　　; THIS SCRIPT WILL DELTE THE LOG FILE 　　FileDelete ( $logFileName ) 　　If FileExists( $uninstallFile ) Then 　　　　_FileWriteLog( $logFileName, &#8220;Already [...]]]></description>
			<content:encoded><![CDATA[<p>　　由于代码每天都会更新，编译组每天晚上会针对当天的代码编译出一个新的Build（除非编译不通过），而测试组第二天早上都会安装前一天晚上编译出的Build进行测试。<br />
　　一直以为测试组每天都手动地重复着这些枯燥无味的卸载、安装工作，直到同组的一个同事告诉我，测试组每天的卸载和安装工作都是通过脚本自动实现的，无需人为干预。<span id="more-102"></span><br />
　　原来他们使用了一款叫做AutoIt的工具。个人以为，要实现这种自动化的功能，要么让程序以控制鼠标或键盘的方式进行实际的操作，要么让程序通过给系统发消息的方式模拟鼠标和键盘的操作。无论使用哪种方式，要写一个通用的工具，工作量还是比较大的。而这款现成的软件，正好实现了期望中的功能。<br />
　　出于好奇的心理，从官方网站上下载了安装文件autoit-v3-setup.exe。安装完后，我们可以看到AutoIt不仅附有很详细的文档，而且还提供了丰富的样例。这种脚本比较简单，很容易上手。</p>
<p><strong>原理和应用范围</strong></p>
<p>　　AutoIt把Windows系统的API封装成易用的Script函数。通过调用这些函数，我们就能很容易地让程序模拟鼠标和键盘的操作。当调用某些函数的时候，相当于我们对鼠标或键盘做了相应的操作。AutoIt的脚本非常简单，我们只需要写一段比较简洁的脚本，调用某些函数就可实现模拟键盘或鼠标操作的功能。如果用C/C++来实现相同功能，代码量可能就不仅仅是一两行了。<br />
　　在批量的自动化处理或重复性任务的处理时，使用AutoIt可以大幅减少我们的工作量。比如说，每天定时让程序自动卸载、自动安装一次。</p>
<p><strong>实现自己的安装/卸载程序</strong></p>
<p>　　这儿，我尝试着写了一个能够让AutoIt自动安装和卸载的脚本。包括2个脚本：1.自动安装AutoIt3；2.自动卸载AutoIt3。<br />
　　由于AutoIt不支持Debug（或许可以通过某些方式或第三方工具实现Debug的功能，但至少我没发现），我通过写Log文件来排查错误。每执行一个操作，都会在Log文件中记下执行的操作。</p>
<p><strong>1.运行步骤<br />
</strong>　　• 自动安装：<br />
　　1) 先判断AutoIt的默认安装文件夹中是否存在Uninstall.exe文件，如果存在，则说明AutoIt已经安装，否则表明尚未安装。（在实际情况中，Uninstall.exe是否存在与程序是否已经安装并没有直接的关系，此处之所以这么做是为了简化判断。同样，在安装的时候，用户可以自定义安装目录，为了简化操作，此处我使用了默认安装路径&#8221;C:\Program Files\AutoIt3\&#8221;。)<br />
　　2) 如果AutoIt已经安装，那么直接退出安装，否则进入步骤3；<br />
　　3) 通过自动点击Next按钮进行安装AutoIt。安装完成后，点击Finish，退出。<br />
　　• 自动卸载：<br />
　　1) 先判断AutoIt的默认安装文件夹中是否存在Uninstall.exe文件，如果存在，则进入步骤2，否则表明Uninstall文件不存在，那么退出卸载。<br />
　　2) 通过自动点击Next按钮进行安装AutoIt。安装完成后，点击Close，退出。<br />
稍加说明：我的运行环境是英文Windows XP，实际的情况可能因为操作系统、运行环境和安装程序的差异稍有不同。在这个例子里，为了避免操作复杂化，我并没有把运行环境的所有可能情况都考虑进去，程序也没有异常处理。</p>
<p><strong>2.代码编写<br />
</strong>　　尽管可以使用文本编辑器或其他文本处理软件编辑源代码，不过使用AutoIt自带的编辑器会更加方便。在本文的最后，提供了源代码链接。</p>
<p>　　现在，我们可以开始编写代码了。首先，我们写自动安装的程序。<br />
　　记得前面，我们提到过，AutoIt不支持Debug。因此，我们只好通过写Log的方式排错。在每次执行程序之前，我们必须先删掉以前的Log文件，然后判断Uninstall.exe文件是否存在，如果存在，则在Log文件中写上“Already Installed.”，并退出程序；否则在Log文件中记下“Starting Install”。代码如下：</p>
<p>[java]<br />
　　; THIS SCRIPT WILL DELTE THE LOG FILE<br />
　　FileDelete ( $logFileName )<br />
　　If FileExists( $uninstallFile ) Then<br />
　　　　_FileWriteLog( $logFileName, &#8220;Already installed.&#8221;)<br />
　　　　Exit<br />
　　Else<br />
　　　　_FileWriteLog( $logFileName, &#8220;Starting install.&#8221;)<br />
　　EndIf<br />
[/java]</p>
<p>　　上面的一段代码，; THIS SCRIPT WILL DELTE THE LOG FILE 是代码的注释。FileDelete ( $logFileName ) 执行删除$logFileName文件的任务。此处，FileDelete()函数是删除一个指定的文件，而$logFileName就是删除的文件名。在引用变量$logFileName之前，我们必须保证它初始化过。它的赋值函数如下：<br />
[java]<br />
$logFileName=@ScriptDir &amp; &#8220;\&#8221; &amp; &#8220;InstallLog.txt&#8221;<br />
[/java]<br />
　　其中，@ScriptDir是当前运行的Script文件所在的目录。关于更多的函数、预定义变量或其他信息，可以查看程序自带的文档，非常详尽。</p>
<p>　　执行完以上代码后，如果没有安装过，程序向下执行： </p>
<p>[java]<br />
　　; Run Setup<br />
　　Run($SetupFile)<br />
　　Sleep(9000)<br />
[/java]</p>
<p>　　Run($SetupFile)就是运行autoit-v3-setup.exe文件。Sleep(9000)让程序睡眠9000毫秒，也就是9秒。为什么要让它睡眠呢？首先，程序启动需要一定的时间，其次，也是为了方便我们目测程序的安装进度。至于睡眠的时间是9000毫秒还是8000毫秒，这并不重要，只要够长就行。</p>
<p>　　现在，我们需要等待安装文件出现，然后点击“Next”按钮进行下一步的操作。但是，我们如何让程序知道我们要打开哪个对话框，点击哪个按钮，或者在哪个文本框里输入什么内容呢？<br />
具体到当前例子中，我们怎么告诉程序要点击下图中的Next按钮呢？<br />
　　我们可以通过函数ControlClick()来实现。<br />
　　在AtuoIt的文档中，提到CtrolClick向指定控件发送鼠标点击命令。输入的参数如下：</p>
<p>　　ControlClick ( &#8220;窗口标题&#8221;, &#8220;窗口文本&#8221;, 控件ID [, 按键 [, 点击次数 [, X坐标 [, Y坐标 ]]]] )</p>
<p><strong>参数</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="91">窗口标题</td>
<td width="490">目标窗口标题。</td>
</tr>
<tr>
<td width="91">窗口文本</td>
<td width="490">目标窗口文本。</td>
</tr>
<tr>
<td width="91">控件ID</td>
<td width="490">目标控件。</td>
</tr>
<tr>
<td width="91">按钮</td>
<td width="490">[可选参数] 要点击的按钮，可以是 &#8220;left&#8221;(左键),&#8221;right&#8221;(右键), &#8220;middle&#8221;(中键), &#8220;main&#8221;, &#8220;menu&#8221;, &#8220;primary&#8221;, &#8220;secondary&#8221;。默认值为 left(左键)。</td>
</tr>
<tr>
<td width="91">点击次数</td>
<td width="490">[可选参数] 要点击鼠标按钮的次数。默认值为 1.</td>
</tr>
<tr>
<td width="91">X坐标</td>
<td width="490">[可选参数] 要点击控件的位置(X坐标). 默认为控件中心.</td>
</tr>
<tr>
<td width="91">Y坐标</td>
<td width="490">[可选参数] 要点击控件的位置(Y坐标). 默认为控件中心.</td>
</tr>
</tbody>
</table>
<p><strong> </strong><strong>返回值</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="91" valign="top">成功:</td>
<td width="490" valign="top">返回值为1。</td>
</tr>
<tr>
<td width="91" valign="top">失败:</td>
<td width="490" valign="top">返回值为0。</td>
</tr>
</tbody>
</table>
<p>　　那么，怎样得到参数信息呢？我们可以使用AutoIt自带的Window信息查看器。打开Window信息查看器之后，把鼠标悬浮在Next按钮上，此时，在查看器中立刻会出现鼠标所在位置的信息，如下图：</p>
<p style="text-align: center;"><a href="http://delphi.zijinshi.org/wp-content/uploads/2010/11/AutoIt.png"><img class="size-full wp-image-103 aligncenter" title="AutoIt" src="http://delphi.zijinshi.org/wp-content/uploads/2010/11/AutoIt.png" alt="" width="680" height="410" /></a></p>
<p> </p>
<p>　　因此，我们调用ControlClick(“AutoIt v3.3.0.0 Setup”, &#8220;&amp;Next &gt;&#8221;,&#8221;Button2&#8243;)就表示按下了Next按钮。<br />
　　AutoIt支持自定义函数。由于很多地方需要点击按钮，然后输出Log。为了提高代码利用效率，我们就自定义了一个函数ControlClickWithLog来完成此功能。关于ControlClickWithLog的实现，可　以查看本文源代码。<br />
　　在函数ControlClickWithLog完成后，我们可以通过如下代码实现点击Next按钮的功能：</p>
<p>[java]<br />
　　;Click &#8220;Next&#8221;<br />
　　WinWaitActive($setupWinTitle)<br />
　　ControlClickWithLog($setupWinTitle,&#8221;&amp;Next &gt;&#8221;,&#8221;Button2&#8243;,<br />
　　　　　　　　　　　　$logFileName,&#8221;Next Clicked.&#8221;,&#8221;Next Not Clicked.&#8221;)<br />
　　Sleep(2000);<br />
[/java]</p>
<p>　　对当前实例而言，安装和卸载的步骤中的主要工作是点击按钮，所以其它部分和点击Next基本上大同小异。在此就不再赘述。如需要更多信息，可以查看源代码。<br />
　　另外，由于InstallAutoIt3和UninstallAutoIt3中有一些共用的部分，例如常量和函数。为了提高代码重用的效率，我们可以把共用的部分放到一个命名为UserFunction.au3的文件中。在其他文件中，只需在文件开始处加上#include ，我们就可以使用UserFunction.au3中定义的常量和函数了。</p>
<p><strong>3.编译exe文件<br />
</strong>　　安装和卸载的源代码分别是InstallAutoIt3.au3和UninstallAutoIt3.au3。选中InstallAutoIt3.au3，右键，点“Run Script”，就可以运行自动安装了。当然，我们还可以选中“Compile Script”生成InstallAutoIt3.exe可执行文件。这样，无论目标机器上是否安装了AutoIt，都可以运行。<br />
　　稍加说明，在程序中，我们假设autoit-v3-setup.exe、InstallAutoIt3.exe和UninstallAutoIt3.exe都放在了同一个目录中。<br />
　　更进一步，如果希望每天都定时安装或卸载，我们可以把程序InstallAutoIt3.exe和UninstallAutoIt3.exe加到Windows的计划任务中，让操作系统定时运行安装或卸载程序。</p>
<p><strong>小结<br />
</strong>　　除了模拟鼠标和键盘操作之外，AutoIt还提供了UI的脚本，本文就不再继续讨论。对AutoIt有兴趣的朋友可以参考AutoIt联机帮助和样例。联机帮助写得很详尽，样例很容易上手。<br />
　　毫无疑问，AutoIt是一款非常不错的软件。不过很遗憾，它并不是一款开源软件。尽管作者声称开放的源代码包含了大部分功能，但也仅限于较早的几个版本。如果对早期AutoIt的源代码感兴趣，可以从其官方网站下载。</p>
<p><strong>相关资源</strong><br />
　　链接：<br />
　　　　AutoIt官方网站：http://www.autoitscript.com<br />
　　　　历史版本和部分源代码下载：http://www.autoitscript.com/autoit3/files/archive/autoit/<br />
　　　　本文源代码下载：<a href="http://delphi.zijinshi.org/wp-content/uploads/2010/11/Install_UnInstall_AutoIt.zip">http://delphi.zijinshi.org/wp-content/uploads/2010/11/Install_UnInstall_AutoIt.zip</a><br />
　　参考资料：<br />
　　　　AutoIt的联机帮助和样例</p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/102/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>工作压力测试</title>
		<link>http://delphi.zijinshi.org/archives/88</link>
		<comments>http://delphi.zijinshi.org/archives/88#comments</comments>
		<pubDate>Wed, 04 Aug 2010 09:32:24 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[生活相关]]></category>

		<guid isPermaLink="false">http://delphi.zijinshi.org/?p=88</guid>
		<description><![CDATA[来自http://exam.datihu.com/ws_exam/systemintro.aspx。 个人基本信息 公司： 性别： 男 年龄： 29 婚姻状况： 未婚 学历： 本科 工作年限： 7 职业： 软硬件开发人员 职位： 普通员工 公司规模： 50-100人 公司性质： 外资企业 个性化报告 　　工作倦怠是在长期的工作压力下产生的一种症状，工作倦怠会使个体工作满意度低下，工作绩效降低，还可能引发离职，影响职业发展等。工作倦怠影响个体的身心健康，症状严重的会出现疲乏、失眠、头痛、胃肠功能紊乱等身体问题，以及自尊水平下降、抑郁、焦虑、无助感等心理问题。 　　您这次测试的结果情况如下： 　　您有明显的工作倦怠症状。 　　您在现在的工作中 　　有明显的疲惫不堪，精力丧失的症状。 　　对工作的各个方面产生了消极的、冷漠的或过度疏离的态度和反应。 　　总结和建议：您的工作倦怠症状明显，您的工作压力已经在一定程度上影响了您的身心健康和职业发展。建议您仔细阅读报告的内容，并寻找引起工作压力的原因，您很有必要做减压的调试，以免工作倦怠进一步加深，带来身心健康的更大影响。 　　感谢您的参与，祝工作顺利！]]></description>
			<content:encoded><![CDATA[<p>来自http://exam.datihu.com/ws_exam/systemintro.aspx。</p>
<p>个人基本信息<br />
公司： 		性别： 	男<span id="more-88"></span><br />
年龄： 	29 	婚姻状况： 	未婚<br />
学历： 	本科 	工作年限： 	7<br />
职业： 	软硬件开发人员 	职位： 	普通员工<br />
公司规模： 	50-100人 	公司性质： 	外资企业</p>
<p>个性化报告<br />
　　工作倦怠是在长期的工作压力下产生的一种症状，工作倦怠会使个体工作满意度低下，工作绩效降低，还可能引发离职，影响职业发展等。工作倦怠影响个体的身心健康，症状严重的会出现疲乏、失眠、头痛、胃肠功能紊乱等身体问题，以及自尊水平下降、抑郁、焦虑、无助感等心理问题。</p>
<p>　　您这次测试的结果情况如下：<br />
　　您有明显的工作倦怠症状。</p>
<p>　　您在现在的工作中<br />
　　有明显的疲惫不堪，精力丧失的症状。<br />
　　对工作的各个方面产生了消极的、冷漠的或过度疏离的态度和反应。<br />
　　总结和建议：您的工作倦怠症状明显，您的工作压力已经在一定程度上影响了您的身心健康和职业发展。建议您仔细阅读报告的内容，并寻找引起工作压力的原因，您很有必要做减压的调试，以免工作倦怠进一步加深，带来身心健康的更大影响。</p>
<p>　　感谢您的参与，祝工作顺利！</p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/88/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>标签删除工具(V1.0.1)</title>
		<link>http://delphi.zijinshi.org/archives/84</link>
		<comments>http://delphi.zijinshi.org/archives/84#comments</comments>
		<pubDate>Tue, 11 May 2010 16:15:00 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[代码共享]]></category>

		<guid isPermaLink="false">http://delphi.zijinshi.org/?p=84</guid>
		<description><![CDATA[　　标签删除工具（RemoveTagPlugin）已经有一年多没有更新了。 　　晚上，突然想看看自己一年前写的这个可以删除标签的插件，向一年前的自己学习学习。顺便把它更新到了一下，使之在较新的Eclipse版本下可以运行。实际上，代码基本上没有做任何修改，仅仅是在Menifest文件中修改了一些版本相关的信息，于是它就可以在Eclipse 3.5.x上运行了。由此可见，Eclipse 3.5在Team这一块，与前一个版本3.4相比，并没有做很大的改动，或者说与前一个版本的兼容性比较好。 　　此版本的运行环境Eclipse 3.5.x（在Eclipse3.5.1上测试通过，没有在其它版本上测试过），JRE 6。下载（包含Binary和Source）：RemoveTagPlugin1.0.1.jar 　　Eclipse在线更新网址：http://plugin.zijinshi.cn/rtp。 　　关于此插件的更多介绍，可以参见过去的这篇文章：标签删除工具(适用于Eclipse 3.4.0)。 　　Eclipse Market 网址:Remove Tag Tool。]]></description>
			<content:encoded><![CDATA[<p>　　标签删除工具（RemoveTagPlugin）已经有一年多没有更新了。<br />
　　晚上，突然想看看自己一年前写的这个可以删除标签的插件，<span id="more-84"></span>向一年前的自己学习学习。顺便把它更新到了一下，使之在较新的Eclipse版本下可以运行。实际上，代码基本上没有做任何修改，仅仅是在Menifest文件中修改了一些版本相关的信息，于是它就可以在Eclipse 3.5.x上运行了。由此可见，Eclipse 3.5在Team这一块，与前一个版本3.4相比，并没有做很大的改动，或者说与前一个版本的兼容性比较好。<br />
　　此版本的运行环境Eclipse 3.5.x（在Eclipse3.5.1上测试通过，没有在其它版本上测试过），JRE 6。下载（包含Binary和Source）：<a href="http://delphi.zijinshi.org/wp-content/uploads/2010/05/RemoveTagPlugin1.0.1.jar"><strong>RemoveTagPlugin1.0.1.jar</strong></a><br />
　　Eclipse在线更新网址：<a href="http://plugin.zijinshi.cn/rtp">http://plugin.zijinshi.cn/rtp</a>。<br />
　　关于此插件的更多介绍，可以参见过去的这篇文章：<a href="http://delphi.zijinshi.org/archives/41">标签删除工具(适用于Eclipse 3.4.0)</a>。<br />
　　Eclipse Market 网址:<a href="http://marketplace.eclipse.org/content/remove-tag-tool">Remove Tag Tool</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/84/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>赶路</title>
		<link>http://delphi.zijinshi.org/archives/83</link>
		<comments>http://delphi.zijinshi.org/archives/83#comments</comments>
		<pubDate>Mon, 10 May 2010 10:00:16 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[观点想法]]></category>

		<guid isPermaLink="false">http://delphi.zijinshi.org/?p=83</guid>
		<description><![CDATA[　　很久很久以前，应该是11年前吧。 　　那个时侯，刚跨入大学不久。一天晚上的《思想道德修养》课上，老师讲道，“……大家坐着同一辆车，开向终点。有的人流连于路上的美景而选择中途下车，有人则坚持一直坐到终点……” 　　她的一番话是非常激动人心的。至少在大学的前两年里，我一直都在马不停蹄的向前走，丝毫不敢懈怠。记得当年微软研究院来学校宣传的时候，我读完张亚勤的简历，竟然还要把自己和他比照一番。 　　那个时侯，我曾经憧憬着，N年之后，自己在IT行业的某一领域是一个卓有成就的人。现在，N年过去了…… 　　聊天的时候，我说，我希望以后，自己开一家软件公司，做自己的产品。闲暇之余，画画漫画，写写科幻小说。嗯，对，其实这个愿望也并不是太遥远。 　　现在要做的事呢，呵呵~~~ 　　]]></description>
			<content:encoded><![CDATA[<p>　　很久很久以前，应该是11年前吧。<br />
　　那个时侯，刚跨入大学不久。一天晚上的《思想道德修养》课上，老师讲道，“……大家坐着同一辆车，开向终点。有的人流连于路上的美景而选择中途下车，有人则坚持一直坐到终点……”<span id="more-83"></span><br />
　　她的一番话是非常激动人心的。至少在大学的前两年里，我一直都在马不停蹄的向前走，丝毫不敢懈怠。记得当年微软研究院来学校宣传的时候，我读完张亚勤的简历，竟然还要把自己和他比照一番。<br />
　　那个时侯，我曾经憧憬着，N年之后，自己在IT行业的某一领域是一个卓有成就的人。现在，N年过去了……</p>
<p>　　聊天的时候，我说，我希望以后，自己开一家软件公司，做自己的产品。闲暇之余，画画漫画，写写科幻小说。嗯，对，其实这个愿望也并不是太遥远。<br />
　　现在要做的事呢，呵呵~~~<br />
　　</p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/83/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>笔记：自己做WordPress语言包</title>
		<link>http://delphi.zijinshi.org/archives/71</link>
		<comments>http://delphi.zijinshi.org/archives/71#comments</comments>
		<pubDate>Tue, 12 Jan 2010 05:27:32 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[技术相关]]></category>

		<guid isPermaLink="false">http://blog.zijinshi.cn/delphi/?p=71</guid>
		<description><![CDATA[　　利用Wordpress(v2.9.1)构建了Bus Line之后，从官方网站下载了一个语言包zh_CN.mo，上传到目录/wp-content/languages中，然后修改wp-config.php文件，把define (&#8216;WPLANG&#8217;, &#8221;);修改成define (&#8216;WPLANG&#8217;, &#8216;zh_CN&#8217;);。 　　完工。 　　但发现有的翻译不是很好，于是自己改。 　　从Wordpress官方网站得知，可以通过诸多工具Translation Tools修改语言包.po文件，并将其编译成.mo文件。 　　我选取了poEdit。 参考资料： 　　1.Translating WordPress 　　2.WordPress in Your Language]]></description>
			<content:encoded><![CDATA[<p>　　利用Wordpress(v2.9.1)构建了<a href="http://bus.zijinshi.org/">Bus Line</a>之后，从官方网站下载了一个语言包zh_CN.mo，上传到目录/wp-content/languages中，然后修改<em>wp-config.php</em>文件，把<strong>define (&#8216;WPLANG&#8217;, &#8221;);</strong>修改成<strong>define (&#8216;WPLANG&#8217;, &#8216;zh_CN&#8217;);</strong>。<span id="more-71"></span><br />
　　完工。</p>
<p>　　但发现有的翻译不是很好，于是自己改。</p>
<p>　　从Wordpress官方网站得知，可以通过诸多工具<a href="http://codex.wordpress.org/Translating_WordPress#Translation_Tools">Translation Tools</a>修改语言包.po文件，并将其编译成.mo文件。<br />
　　我选取了<a title="http://www.poedit.net/" href="http://www.poedit.net/">poEdit</a>。</p>
<p>参考资料：<br />
　　1.<a href="http://codex.wordpress.org/Translating_WordPress#Translating_With_poEdit">Translating WordPress</a><br />
　　2.<a title="WordPress in Your Language" href="http://codex.wordpress.org/WordPress_in_Your_Language">WordPress in Your Language</a></p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/71/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>数独的解决方案</title>
		<link>http://delphi.zijinshi.org/archives/77</link>
		<comments>http://delphi.zijinshi.org/archives/77#comments</comments>
		<pubDate>Sun, 03 Jan 2010 06:33:34 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[代码共享]]></category>
		<category><![CDATA[技术相关]]></category>
		<category><![CDATA[解决]]></category>
		<category><![CDATA[sudoku]]></category>
		<category><![CDATA[数独]]></category>

		<guid isPermaLink="false">http://blog.zijinshi.cn/delphi/?p=75</guid>
		<description><![CDATA[　　坐在可颂坊休息的时候，她问我有没有做过数独，我说做过。 　　她竟然掏出一本书，说感兴趣的话做做看。挑了一个，做了十来分钟，无果。算了，不做了，本来就是通过穷尽的方式来达到解答的目的，既然能用机器去做，我实在是不愿动脑子。于是，向她许诺回去后写个可以解决数独问题的程序。 　　在此，与大家共享源代码和程序。点击此处下载。 　　一个很简单的程序，在算法上我没有做任何优化。 如何使用： 　　解压缩Sudoku.zip，确保所需的文件sudoku.exe和input.txt放在同一个目录中。 　　打开input.txt文件，输入数独题目：每行输入9个数字，要填的数字用0代替，共输入9行。 　　例如，对于如下题目： 　　可以在input.txt文件中输入： 　　0 0 1 0 8 0 0 0 0 　　0 2 0 0 0 0 4 0 0 　　0 0 9 0 0 7 0 8 0 　　0 5 0 0 3 0 0 0 1 　　0 4 0 0 0 0 0 5 0 　　7 [...]]]></description>
			<content:encoded><![CDATA[<p>　　坐在可颂坊休息的时候，她问我有没有做过数独，我说做过。<br />
　　她竟然掏出一本书，说感兴趣的话做做看。挑了一个，做了十来分钟，无果。算了，不做了，本来就是通过穷尽的方式来达到解答的目的，既然能用机器去做，我实在是不愿动脑子。于是，向她许诺回去后写个可以解决数独问题的程序。<span id="more-77"></span><br />
　　在此，与大家共享源代码和程序。点击此处<a href="http://delphi.zijinshi.org/wp-content/uploads/2010/01/Sudoku.zip"><span style="color: #c60a00;"><strong>下载</strong></span></a>。<br />
　　一个很简单的程序，在算法上我没有做任何优化。</p>
<p>如何使用：<br />
　　解压缩Sudoku.zip，确保所需的文件sudoku.exe和input.txt放在同一个目录中。<br />
　　打开input.txt文件，输入数独题目：每行输入9个数字，要填的数字用0代替，共输入9行。<br />
　　例如，对于如下题目：<br />
<a href="http://delphi.zijinshi.org/wp-content/uploads/2010/01/example.jpg"><img class="alignnone size-medium wp-image-77" src="http://www.delphi.zijinshi.org/wp-content/uploads/2010/01/example-300x292.jpg" alt="" width="300" height="292" /></a><br />
　　可以在input.txt文件中输入：<br />
　　0 0 1 0 8 0 0 0 0<br />
　　0 2 0 0 0 0 4 0 0<br />
　　0 0 9 0 0 7 0 8 0<br />
　　0 5 0 0 3 0 0 0 1<br />
　　0 4 0 0 0 0 0 5 0<br />
　　7 0 0 0 0 9 0 6 0<br />
　　0 7 0 5 0 0 2 0 0<br />
　　0 0 2 0 0 0 0 3 0<br />
　　0 0 0 0 4 0 8 0 0</p>
<p>　　保存，然后关闭文件input.txt。<br />
　　双击运行sudoku.exe，程序一闪而过。此时目录下面多了个文件ouput.txt，这个文件里面就是答案。:)</p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/77/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>“绿坝”最终会不了了之</title>
		<link>http://delphi.zijinshi.org/archives/62</link>
		<comments>http://delphi.zijinshi.org/archives/62#comments</comments>
		<pubDate>Sun, 14 Jun 2009 14:33:44 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[观点想法]]></category>

		<guid isPermaLink="false">http://blog.zijinshi.cn/delphi/?p=62</guid>
		<description><![CDATA[　　作为一个IT人，最近最关心的事情莫过于“绿坝”事件了。 　　2009年6月9号，工信部发出了《关于计算机预装绿色上网过滤软件的通知》。在通知中指出，“7月1日以后，在我国境内生产销售的计算机出厂前将预装一款名为‘绿坝-花季护航’的绿色上网过滤软件，而进口计算机在我国销售前也将预装该软件。” 　　工信部在通知中提到，个人电脑预装绿坝的主要目的是“旨在创造一个绿色、健康、和谐的互联网环境，防止互联网上的有害信息影响和毒害青少年”。还指出，“为进一步巩固整治互联网低俗之风专项行动成果，坚持惩防结合，切实保护未成年人健康成长，推动互联网健康有序发展”，而预装该软件也是“根据全国整治互联网低俗之风专项行动的总体部署”。 　　说实话，看到这个报道的第一感觉就是，原来工信部也很有娱乐精神的嘛！接下来的几天，网上似乎炸开了锅，试用、评测、破解、评论的文章铺天盖地。在此，我无意去揣测这件事情的前因后果，也不关心此事的内部细节。不过呢，无论是从用户、厂商的角度、法律的角度，还是“绿坝”的技术这几个方面进行分析，我都能得出一个结论：“绿坝”事件最后会不了了之。我指的不了了之，就是说工信部的这个《通知》最终会被撤销。 　　首先，从用户方面看。 　　“在我国境内生产销售的计算机出厂前将预装一款名为‘绿坝-花季护航’的绿色上网过滤软件”。也就是说无论用户愿不愿意，只要我们买了电脑，上面都会预装这款软件。 　　我很奇怪，为什么一定要预装这样的软件？我用我自己的电脑，只要不违法，你管我的机器里面装什么软件呢？照你这个意思，卫生部是不是也可以强制这样的规定：从某年某月某日开始，为了保证食品的安全，全国所有出售的馒头必须使用某某厂商提供的面粉？说得严重点，正如有的网友说的，在我自己家里，我想干什么就干什么，你凭什么要强制在我家里装个摄像头呢？ 　　好吧，即便强制安装软件这种做法是正确的，那为什么就一定要强制使用指定的软件呢？此类的软件种类繁多，用户如果就是不喜欢这款软件，他就是喜欢另一款软件呢？是不是他必须割舍自己的喜好以此来迎合这个貌似合理的规定？显然，只要合法，只要不违反道德的底线，用户喜欢什么不喜欢，其他人都是没权干涉的。 　　也或许基于这些质疑，工信部又出来澄清了：“用户可以自行选择安装或卸载”。我又纳闷了，一边说“强制预装”，一边又说“可以自行安装或卸载”，是不是自相矛盾？既然是强制的，干嘛又可以卸载？好，如果用户卸载了，工信部的好心岂不是被大家白白浪费了？毕竟4000多万，不是小数目，如果就这样随随便便地被浪费掉，我不知道大家做何感想。 　　另一方面，此软件的目的“旨在创造一个绿色、健康、和谐的互联网环境，防止互联网上的有害信息影响和毒害青少年”。我看清楚了，主要是针对青少年的。这时，我又犯迷糊了，中国所有用电脑用户都是青少年么？既然是针对青少年，那是不是只要在部分的电脑上预装就可以了，何必要延伸到所有的电脑呢？我们知道，小儿麻痹症一般都发生在幼儿身上，对于一个三口之家，为了预防小儿麻痹症，幼儿去打预防针就够了吧？我很难想象孩子的父母也跟着一起打针的情景！ 　　还有，既然该软件是为了“巩固整治互联网低俗之风”，那好，我的电脑如果不上网，总该可以不装吧？不，答案是否定的！所有的，不论你上网与否都必须装。一个简单的对比：对于一个上班族来说，如果上班的时候穿正装，可以理解，但是如果他回到家里还穿正装，我就觉得有些奇怪了，如果洗澡的时候还穿正装，那我只能说他是神经不正常了。 　　站在用户的角度，这件事情根本就是没法忍受的。站在厂商的角度呢？ 　　对于电脑硬件提供商来说，在自己的系统中预装他人的软件，得不到任何推广费用，还得自掏腰包为别人的软件而折腾，不仅如此，因此而得到用户的不停抱怨，我不知道哪个电脑公司愿意这么做？ 　　对于软件提供商，估计也很郁闷。不少软件厂商也提供了很多同类软件，他们也做得很好，为什么唯独指定这一家，那他们的呢？更何况，如果就指定了你一家，那其他的还要不要活了？所有软件厂商里面，最纳闷的估计要数微软了。既然“绿坝”是运行在windows系统上面的，如果用户装个linux或其他的操作系统，“绿坝”不就鞭长莫及了？“绿坝”这样把用户都往linux上面赶，这分明是想整死windows么？这真让微软郁闷啊！郁闷？且慢！不是说所有的电脑都必须装“绿坝”么？而“绿坝”又是运行在windows系统上的，那工信部的潜台词是不是说所有的电脑都必须预装windows系统？哇，这样看来，那微软岂不是开心死了？那其他的操作系统提供商呢？好说，你们去死吧！这时，我脑子里突然闪现出当年传说中的国产操作系统“麒麟”，呵呵！ 　　好，软硬件提供商讨论完了，现在轮到法律方面了。 　　工信部发出这样的通知有没有法律依据我不知道，但是这个通知触犯了法律倒是真。这一点，网上早有大虾指出。 　　《反不正当竞争法》第七条第一款规定：政府及其所属部门不得滥用行政权力，限定他人购买其指定的经营者的商品，限制其他经营者正当的经营活动。 　　《反垄断法》第八条、第三十二条、第三十七条分别规定:“行政机关和法律、法规授权的具有管理公共事务职能的组织不得滥用行政权力，排除、限制竞争”；“行政机关和法律、法规授权的具有管理公共事务职能的组织不得滥用行政权力，限定或者变相限定单位或者个人经营、购买、使用其指定的经营者提供的商品”；“行政机关不得滥用行政权力，制定含有排除、限制竞争内容的规定”。 　　国家法律条文，这个没什么好正争辩的。我不是法律工作者，就只能关注了。当然，白纸黑字，如果一定要说工信部没有违法，我也无话可说。 　　最后，再来看看“绿坝”到底是一款怎样的软件呢？网友们经过测试和研究后，指出了其三大软肋：一.用户体验差；二.安全性差；三.侵犯知识产权。 　　关于用户体验差，网上的分析真是太多了。我不可能囊括所有的，就举几个简单的例子。 　　1.安装后，如果要卸载，没法完全卸载。卸载、系统重启后，仍旧有进程进驻系统。既然已经卸载了，为什么还有进程在运行？是不是很熟悉？对了，3721是这方面的鼻祖。 　　2.“绿坝”的图片过滤存在很多误判，很多色情图片不会过滤，但很多正常图片却被过滤了。当然，“绿坝”在《免责条款》中提到：“本产品可以过滤互联网上的不良信息，但不保证不良信息能完全被过滤，也不保证被过滤的信息完全是不良信息。” 你说你可以过滤图片，但是又不能过滤所有的图片，而且还说你不保证你过滤的所有图片都是不良信息。你想说什么？一个网友曾经这样戏谑：这是不是说倒洗澡水的时候，我可以倒洗澡水，但是不保证洗澡水能够全部倒掉，也不保证澡盆的“孩子”一定没有随着洗澡水倒出去。 　　3.上网时仅能过滤IE，至于其他的浏览器Firefox等等，统统不工作。呵呵，浏览器又不只IE一个，不知道所谓的这样的过滤有何存在意义。 　　4.在Word中输入了某个关键字，就会被自动关掉。如果用户没保存呢？是不是很让人恼火？的确，现在，打了这么多字，然后文档被突然关掉了，我很难想像自己是怎样一种心情！ 　　至于安全性方面，实在不敢恭维。 　　刚发布不久，江民、360安全卫士就发现了“绿坝”的漏洞（bigdouya.blogbus.com/logs/40945681.html，www.wabei.com/news/200906/229078.html）。另外，稍懂电脑的人一两分钟就可以破解这个软件（www.kenengba.com/post/1149.html）。其他的不提，仅仅这两条，我想已经足够了。 　　再看看知识产权方面的侵权。 　　1. 违反BSD许可证在软件中使用OpenCV库。 　　2. 将OpenCV的算法和技术用于申请专利。 　　3. 抄袭美产过滤软件CYBERsitter的关键字列表（猜测应该还有更多代码抄袭）。 　　关于这些，我不多说，大家可以参见这篇文章《Analysis of the Green Dam Censorware System》，呵呵，竟然有人如此较真地来分析这款软件。 　　至于其他的一些评论，网上有朋友说，此软件的成本最多4万，我表示赞同。但是为什么价值4万的东西，不仅能够卖出4000万价格，而且还有工信部为之作免费的推广 呢？背后的细节，我不愿去揣测，更不愿深究，还是就事论事吧！ 　　啊，终于写完了！说实话，毕业这么多年，看到类似的事情往往都一笑而过，很少像今天这样较真了！ 　　分析完毕。我很难想像《通知》能够在7月1日如期执行，要不拭目以待吧！ 参考资料： 1.http://news.qq.com/a/20090609/000517.htm 2.http://news.ifeng.com/mainland/200906/0610_17_1196272.shtml 3.http://www.dffy.com/fayanguancha/sd/200906/20090610205808.htm 4.http://www.cse.umich.edu/~jhalderm/pub/gd/]]></description>
			<content:encoded><![CDATA[<p>　　作为一个IT人，最近最关心的事情莫过于“绿坝”事件了。<br />
　　2009年6月9号，工信部发出了《关于计算机预装绿色上网过滤软件的通知》。在通知中指出，“7月1日以后<span id="more-62"></span>，在我国境内生产销售的计算机出厂前将预装一款名为‘绿坝-花季护航’的绿色上网过滤软件，而进口计算机在我国销售前也将预装该软件。”<br />
　　工信部在通知中提到，个人电脑预装绿坝的主要目的是“旨在创造一个绿色、健康、和谐的互联网环境，防止互联网上的有害信息影响和毒害青少年”。还指出，“为进一步巩固整治互联网低俗之风专项行动成果，坚持惩防结合，切实保护未成年人健康成长，推动互联网健康有序发展”，而预装该软件也是“根据全国整治互联网低俗之风专项行动的总体部署”。<br />
　　说实话，看到这个报道的第一感觉就是，原来工信部也很有娱乐精神的嘛！接下来的几天，网上似乎炸开了锅，试用、评测、破解、评论的文章铺天盖地。在此，我无意去揣测这件事情的前因后果，也不关心此事的内部细节。不过呢，无论是从用户、厂商的角度、法律的角度，还是“绿坝”的技术这几个方面进行分析，我都能得出一个结论：“绿坝”事件最后会不了了之。我指的不了了之，就是说工信部的这个《通知》最终会被撤销。</p>
<p>　　首先，从用户方面看。<br />
　　“在我国境内生产销售的计算机出厂前将预装一款名为‘绿坝-花季护航’的绿色上网过滤软件”。也就是说无论用户愿不愿意，只要我们买了电脑，上面都会预装这款软件。<br />
　　我很奇怪，为什么一定要预装这样的软件？我用我自己的电脑，只要不违法，你管我的机器里面装什么软件呢？照你这个意思，卫生部是不是也可以强制这样的规定：从某年某月某日开始，为了保证食品的安全，全国所有出售的馒头必须使用某某厂商提供的面粉？说得严重点，正如有的网友说的，在我自己家里，我想干什么就干什么，你凭什么要强制在我家里装个摄像头呢？<br />
　　好吧，即便强制安装软件这种做法是正确的，那为什么就一定要强制使用指定的软件呢？此类的软件种类繁多，用户如果就是不喜欢这款软件，他就是喜欢另一款软件呢？是不是他必须割舍自己的喜好以此来迎合这个貌似合理的规定？显然，只要合法，只要不违反道德的底线，用户喜欢什么不喜欢，其他人都是没权干涉的。<br />
　　也或许基于这些质疑，工信部又出来澄清了：“用户可以自行选择安装或卸载”。我又纳闷了，一边说“强制预装”，一边又说“可以自行安装或卸载”，是不是自相矛盾？既然是强制的，干嘛又可以卸载？好，如果用户卸载了，工信部的好心岂不是被大家白白浪费了？毕竟4000多万，不是小数目，如果就这样随随便便地被浪费掉，我不知道大家做何感想。<br />
　　另一方面，此软件的目的“旨在创造一个绿色、健康、和谐的互联网环境，防止互联网上的有害信息影响和毒害青少年”。我看清楚了，主要是针对青少年的。这时，我又犯迷糊了，中国所有用电脑用户都是青少年么？既然是针对青少年，那是不是只要在部分的电脑上预装就可以了，何必要延伸到所有的电脑呢？我们知道，小儿麻痹症一般都发生在幼儿身上，对于一个三口之家，为了预防小儿麻痹症，幼儿去打预防针就够了吧？我很难想象孩子的父母也跟着一起打针的情景！<br />
　　还有，既然该软件是为了“巩固整治互联网低俗之风”，那好，我的电脑如果不上网，总该可以不装吧？不，答案是否定的！所有的，不论你上网与否都必须装。一个简单的对比：对于一个上班族来说，如果上班的时候穿正装，可以理解，但是如果他回到家里还穿正装，我就觉得有些奇怪了，如果洗澡的时候还穿正装，那我只能说他是神经不正常了。</p>
<p>　　站在用户的角度，这件事情根本就是没法忍受的。站在厂商的角度呢？<br />
　　对于电脑硬件提供商来说，在自己的系统中预装他人的软件，得不到任何推广费用，还得自掏腰包为别人的软件而折腾，不仅如此，因此而得到用户的不停抱怨，我不知道哪个电脑公司愿意这么做？<br />
　　对于软件提供商，估计也很郁闷。不少软件厂商也提供了很多同类软件，他们也做得很好，为什么唯独指定这一家，那他们的呢？更何况，如果就指定了你一家，那其他的还要不要活了？所有软件厂商里面，最纳闷的估计要数微软了。既然“绿坝”是运行在windows系统上面的，如果用户装个linux或其他的操作系统，“绿坝”不就鞭长莫及了？“绿坝”这样把用户都往linux上面赶，这分明是想整死windows么？这真让微软郁闷啊！郁闷？且慢！不是说所有的电脑都必须装“绿坝”么？而“绿坝”又是运行在windows系统上的，那工信部的潜台词是不是说所有的电脑都必须预装windows系统？哇，这样看来，那微软岂不是开心死了？那其他的操作系统提供商呢？好说，你们去死吧！这时，我脑子里突然闪现出当年传说中的国产操作系统“麒麟”，呵呵！</p>
<p>　　好，软硬件提供商讨论完了，现在轮到法律方面了。<br />
　　工信部发出这样的通知有没有法律依据我不知道，但是这个通知触犯了法律倒是真。这一点，网上早有大虾指出。<br />
　　《反不正当竞争法》第七条第一款规定：政府及其所属部门不得滥用行政权力，限定他人购买其指定的经营者的商品，限制其他经营者正当的经营活动。<br />
　　《反垄断法》第八条、第三十二条、第三十七条分别规定:“行政机关和法律、法规授权的具有管理公共事务职能的组织不得滥用行政权力，排除、限制竞争”；“行政机关和法律、法规授权的具有管理公共事务职能的组织不得滥用行政权力，限定或者变相限定单位或者个人经营、购买、使用其指定的经营者提供的商品”；“行政机关不得滥用行政权力，制定含有排除、限制竞争内容的规定”。<br />
　　国家法律条文，这个没什么好正争辩的。我不是法律工作者，就只能关注了。当然，白纸黑字，如果一定要说工信部没有违法，我也无话可说。</p>
<p>　　最后，再来看看“绿坝”到底是一款怎样的软件呢？网友们经过测试和研究后，指出了其三大软肋：一.用户体验差；二.安全性差；三.侵犯知识产权。<br />
　　关于用户体验差，网上的分析真是太多了。我不可能囊括所有的，就举几个简单的例子。<br />
　　1.安装后，如果要卸载，没法完全卸载。卸载、系统重启后，仍旧有进程进驻系统。既然已经卸载了，为什么还有进程在运行？是不是很熟悉？对了，3721是这方面的鼻祖。<br />
　　2.“绿坝”的图片过滤存在很多误判，很多色情图片不会过滤，但很多正常图片却被过滤了。当然，“绿坝”在《免责条款》中提到：“本产品可以过滤互联网上的不良信息，但不保证不良信息能完全被过滤，也不保证被过滤的信息完全是不良信息。” 你说你可以过滤图片，但是又不能过滤所有的图片，而且还说你不保证你过滤的所有图片都是不良信息。你想说什么？一个网友曾经这样戏谑：这是不是说倒洗澡水的时候，我可以倒洗澡水，但是不保证洗澡水能够全部倒掉，也不保证澡盆的“孩子”一定没有随着洗澡水倒出去。<br />
　　3.上网时仅能过滤IE，至于其他的浏览器Firefox等等，统统不工作。呵呵，浏览器又不只IE一个，不知道所谓的这样的过滤有何存在意义。<br />
　　4.在Word中输入了某个关键字，就会被自动关掉。如果用户没保存呢？是不是很让人恼火？的确，现在，打了这么多字，然后文档被突然关掉了，我很难想像自己是怎样一种心情！</p>
<p>　　至于安全性方面，实在不敢恭维。<br />
　　刚发布不久，江民、360安全卫士就发现了“绿坝”的漏洞（bigdouya.blogbus.com/logs/40945681.html，www.wabei.com/news/200906/229078.html）。另外，稍懂电脑的人一两分钟就可以破解这个软件（www.kenengba.com/post/1149.html）。其他的不提，仅仅这两条，我想已经足够了。</p>
<p>　　再看看知识产权方面的侵权。<br />
　　1. 违反BSD许可证在软件中使用OpenCV库。<br />
　　2. 将OpenCV的算法和技术用于申请专利。<br />
　　3. 抄袭美产过滤软件CYBERsitter的关键字列表（猜测应该还有更多代码抄袭）。<br />
　　关于这些，我不多说，大家可以参见这篇文章《Analysis of the Green Dam Censorware System》，呵呵，竟然有人如此较真地来分析这款软件。</p>
<p>　　至于其他的一些评论，网上有朋友说，此软件的成本最多4万，我表示赞同。但是为什么价值4万的东西，不仅能够卖出4000万价格，而且还有工信部为之作免费的推广 呢？背后的细节，我不愿去揣测，更不愿深究，还是就事论事吧！<br />
　　啊，终于写完了！说实话，毕业这么多年，看到类似的事情往往都一笑而过，很少像今天这样较真了！<br />
　　分析完毕。我很难想像《通知》能够在7月1日如期执行，要不拭目以待吧！</p>
<p>参考资料：<br />
1.http://news.qq.com/a/20090609/000517.htm<br />
2.http://news.ifeng.com/mainland/200906/0610_17_1196272.shtml<br />
3.http://www.dffy.com/fayanguancha/sd/200906/20090610205808.htm<br />
4.http://www.cse.umich.edu/~jhalderm/pub/gd/</p>
]]></content:encoded>
			<wfw:commentRss>http://delphi.zijinshi.org/archives/62/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

