隐藏DOS窗口,并转储DOS窗口的输出信息

隐藏DOS窗口,并转储DOS窗口的输出信息
我们的产品中间件的启动是由批处理文件开始,这就导致,始终有个DOS窗口,来显示服务器的运行情况。可客户不乐意啊:他们就想万一谁不小心把那窗口给关了,损害了数据,那问题可就大了!这个问题确实是挺有价值的。
首先,我们考虑WINDOWS环境吧,我不认为WINDOWS环境下和*NIX环境下的实现有很大差别。想到以前看到的,听到的,再加上自己的经验,大概有这么集中方式:
  • 包装bat文件为exe文件,然后以后台服务的形式注册
  • 利用windows自带的Wscript.Shell
  • 写个Swing界面小程序,利用多线程,启动应用服务,把DOS窗口替换成应用窗口。
  • 但我们需要考虑另外一点:我们的应用在运行的时候,会向dos窗口输出一些出来的一些信息,这些信息在很多情况下都是很有用的。现在如果把DOS窗口隐藏了,那么那些信息我把他们存放到哪儿呢?我想最好还是以文件的形式保存起来,将来如有问题还可以追查!
    现在考虑各种实现方式。包装为exe的形式,也只能在windows环境下运行,并且需要额外的工具;Swing界面小程序这个其实是最可行的,但我这个人比较懒,比较讨厌写界面;利用windows自带的Wscript.Shell,自然也只能依赖于windows环境,后来我想了下,其实这个方案可以和swing界面那个方案有不少东西是可以公用的。最后决定,为了简单期间,偶就先用Wscript.Shell,来做测试了。
    实际的情况大致是:
  • 应用服务的启动脚本是/startup.bat 实际中我们可以使用vbs脚本:
  • dim ws
    Set ws = CreateObject("Wscript.Shell")
    ws.run "cmd /c /startup.bat >> myServer.log" ,vbhide
    通过这样简单的设置,我们可以做到隐藏DOS窗口,但是,如果我们的应用一下子运行好几个月,那我们的日志文件myServer.log的日积月累地,就太大了。我们在查找问题的时候,也很不容易!所以我们应该想法子把日志文件myServer.log,按时间或者按大小分开存储。这也是我们应用服务器日志的做法。所以,我们需要再做一步中间处理,想想看"appRoot/startup.bat"这一步,我们在程序当中还是可以获得它的输出结果的。看下面java程序:
    package nc.client.StartupUtil;

    import java.lang.ProcessBuilder;
    import java.util.Vector ;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.FileWriter;
    import java.io.BufferedWriter;
    import java.util.Collections ;

    public class NC50StartUtil
    {

    public static final String logFileNamePrefix = "ncconsolelogs";

    public static void main(String[] args)
    {
    ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/C", args[0]+"/startup.bat");
    processBuilder.directory(new File(args[0]));
    Process process = null;
    try
    {
    process = processBuilder.start();
    BufferedReader datais =
    new BufferedReader(
    new InputStreamReader( process.getInputStream()));


    // 服务器日志目录
    String serverLogDirName = args[0] + "/nclogs/server";
    File serverLogDir = new File (serverLogDirName);
    if (!serverLogDir.exists())
    {
    serverLogDir.mkdirs();
    }

    int maxFileIndex = getMaxFileIndex(serverLogDirName).intValue();
    File logFile = new File(serverLogDirName+"/ncconsolelogs.log");
    if (!logFile.exists())
    {
    logFile.createNewFile();
    }
    else
    {
    // 如果已经存在日志文件,则先把原来的文件归档,然后新创建一个日志文件
    StringBuffer oldFileName = new StringBuffer();
    oldFileName.append(serverLogDirName);
    oldFileName.append("/");
    oldFileName.append(logFileNamePrefix).append("[").append(maxFileIndex).append("].log");
    logFile.renameTo(new File(oldFileName.toString()));
    maxFileIndex++;
    //创建新的日志文件
    if (!logFile.exists())
    {
    logFile.createNewFile();
    }

    }

    BufferedWriter writer = new BufferedWriter(new FileWriter(logFile));

    // 文件的最大大小是2M
    int maxlength = 1024*1024*2;

    String c;
    while ((c = datais.readLine()) != null)
    {

    writer.write(c);
    writer.newLine();
    writer.flush();

    // 超过日志文件规定的大小了,则把日志文件归档,然后新创建一个日志文件
    if (logFile.length() > maxlength)
    {
    writer.close();
    StringBuffer oldFileName = new StringBuffer();
    oldFileName.append(serverLogDirName);
    oldFileName.append("/");
    oldFileName.append(logFileNamePrefix).append("[").append(maxFileIndex).append("].log");
    logFile.renameTo(new File(oldFileName.toString()));
    maxFileIndex++;

    // 创建新的日志文件
    if (!logFile.exists())
    {
    logFile.createNewFile();
    }
    writer =   new BufferedWriter(new FileWriter(logFile));
    }

    }
    }
    catch(IOException e)
    {
    e.printStackTrace ();
    }
    }

    public static Integer getMaxFileIndex(String ncconsolelogdirname)
    {
    File ncconsolelogdir = new File(ncconsolelogdirname);
    File[] ncconsolelogs = ncconsolelogdir.listFiles(new NcLogFileNameFilter(logFileNamePrefix));

    if (ncconsolelogs != null && ncconsolelogs.length > 0)
    {
    Vector v = new Vector();
    for (int i=0, len=ncconsolelogs.length; i startIndex)
    {
    String index = logFileName.substring (startIndex+1, endIndex);
    int ind = -1;
    try
    {
    ind = Integer.parseInt(index);
    }
    catch(Exception e)
    {

    }

    if (ind > 0)
    {
    v.add(ind);
    }
    }
    }
    if (v.size() > 0)
    {
    return Collections.max(v) + 1;
    }
    else
    {
    return 1;
    }
    }

    return 1;
    }
    }
    package nc.client.StartupUtil;

    import java.io.File;
    import java.io.FilenameFilter;

    // 一个简单的文件名过滤类
    public class NcLogFileNameFilter implements FilenameFilter {

    private String fileNamePrefix = null;

    public NcLogFileNameFilter(String fileNamePrefix)
    {
    this.fileNamePrefix = fileNamePrefix;
    }

    public boolean accept(File dir, String name)
    {
    if (name.toLowerCase().startsWith(fileNamePrefix))
    {
    return true;
    }
    return false;
    }
    }
    之后,为了运行方便,我们把这两个类编译后打成可执行的jar包,例如ncstartuputil.jar。并修改vbs脚本为:
    dim ws
    Set ws = CreateObject("Wscript.Shell")
    ws.run "cmd /c java -jar ncstartuputil.jar E:/nchome_zhengshi" ,vbhide
    如果换做swing界面,其实仅仅需要写另外一个Thread,thread的主体也正式上面static main方法主体,然后通过多线程,可以获得原始start.bat批处理文件的输出,并且把输出的信息放到一个textarea里面显示出来。:-)....

    你可能感兴趣的:(隐藏DOS窗口,并转储DOS窗口的输出信息)