发现了 UltraEdit 的一个 Bug

  一直以来都非常喜欢 UltraEdit 这个 Windows 下的编辑器,普通文本编辑、写代码、十六进制编辑样样都能胜任,而且功能强大,实为居家旅行、杀人灭口的必备良药:-)

  最近抽空在 Windows 环境学习 Ruby 的时候也用 UltraEdit 作代码编辑器(我不喜欢 Ruby Windows 二进制分发包里面自带的那个 SciTE,在 Windows 下我绝对不会选它,在 *nux 下我当然实用 (G)Vim 了),照我的习惯,像这种 command line 程序我都是在 UE 里面创建一个自定义菜单工具来使用的,这样不用切换到其它程序就可以运行程序得到结果了。点击“工具”->“工具栏配置”,配置好了就可以按热键“Ctrl+Shift+数字”来执行自定义命令了,执行完得出的结果可以被捕获并显示在编辑窗口下方的输出窗口,而问题就出在这里。

  因为是初学,我对 Ruby 的语法掌握还不太自信,所以就在 UE 里创建了一个 Ruby 语法检查的自定义工具,命令行是“ruby -c %f”,谁知运行的结果是:如果程序没有语法错误会得到“Syntax OK”的结果,但是有语法错误时什么信息都得不到,可是在 cmd.exe 下面执行时如果有语法错误的话是会返回错误信息的,看来 UE 在这个地方有 Bug!

  由于以前自己写过 Web Server,当时实现 Windows 平台下的 CGI 程序支持时有过类似的经验,所以我猜想是 UE 在执行用户自定义工具程序时有问题。大家大概都或多或少的接触过命令行程序的 GUI 前端吧?!比如 Lame、MPlayer 这些程序的 GUI 前端,这些前端程序不仅能知道它们调用的后台程序的运行结果是否正确,甚至还可以捕获到程序的文本输出。这是怎么做到的呢?其实很简单,在调用 CreateProcess() 这个 API 创建进程的时候可以传入一个 STARTUPINFO 结构体指针,这个结构体中包含了三个句柄,分别对应于新建进程的 stdin、stdout 和 stderr。我们可以创建三个 pipe 通过这三个参数传给子进程,然后通过 read 相应的 pipe 就可以捕获到子进程的输出了。是不是 Ruby 通过 stdout 来输出“Syntax OK”,而通过 stderr 来输出语法错误信息,而 UE 偏偏又没有处理 stderr 导致没有捕获到程序输出呢?

  光猜没用,可以试试,创建个控制台工程,写个非常简单的小程序如下:

  1. #include "stdio.h"
  2.  int main( void )
  3.  {
  4.    fprintf( stdout, "stdout\n" );
  5.    fprintf( stderr, "stderr\n" );
  6.    return( 0 );
  7.  }

  直接运行的话会显示出“stdout”和“stderr”这两个字符串,在 UE 里新建一个自定义工具来运行这个测试程序,在输出窗口中只能得到“stdout”,看来我的猜测是对的,是 UE 没有处理子进程的 stderr 导致了这个问题。为了让我喜欢的 UltraEdit 变得更好,抽时间给 UE 的开发人员写个 mail 吧,但愿他们能早日修复这个问题!

Leave a Reply