最常用的是ant(java工程中流行),maven,及通用的exec(只要有shell脚本如.sh,.bat,.exe,.cmd等).而其实前两者不容易出错,后者却遇到了以下问题:
Caused by: java.io.IOException: Cannot run program "DailyBuild.bat"...java.io.IOException: CreateProcess error=2

而现在的问题是觉得<exec>节点的workingdir属性设置正确,而command 属性也是指向了要执行的批处理文件"DailyBuild.bat",为什么还要报错呢?于是先把相对路径全改成了绝对,发现不行;又试了把workingdir属性去掉,把command属性写全路径(因为工作目录去掉了,所以一定得写全),发现能运行了,只是报错,因为引用不对了. 这样一来,问题明了了,补回workingdir属性,运行成功! 
得出这样的结论,workingdir属性会让人产生错觉使你在command属性中不再写这个所谓重复的工作目录部分了,而实际上恰恰要写全路径.效果可能类似这样的:)
<exec
             workingdir="projects/${project.name}/deploy/build/"
            command="projects/${project.name}/deploy/build/DailyBuild.bat"
            errorstr="build failed"/>

http://www.verydemo.com/demo_c128_i15102.html

在执行bat时如果将commnd 改为 cmd /c DailyBuild.bat也可以。

Runtime.getRuntime().exec()方法执行bat时,如果bat没有按预期执行,可以使用如下形式:

Process p = Runtime.getRuntime().exec("cmd /c start D:\\catalina.bat start", null, new File("D:\\apache-tomcat-6.0.35"));
http://www.oschina.net/question/927474_84637

java中用Runtime.getRuntime().exec() 调用外部程序, 获取"标准输出流", 老是阻塞.
在网上找了找, 觉得应该是"错误输出流"的问题. 果然, 为"错误输出流"单开一个线程读取之, "标准输出流"就不再阻塞了.
源码如下:

/**执行外部程序,并获取标准输出*/
public static String excuteCmd_multiThread(String[] cmd,String encoding)
{
BufferedReader bReader=null;
InputStreamReader sReader=null;
try
{
Process p = Runtime.getRuntime().exec(cmd);
/*为"错误输出流"单独开一个线程读取之,否则会造成标准输出流的阻塞*/
Thread t=new Thread(new InputStreamRunnable(p.getErrorStream(),"ErrorStream"));
t.start(); /*"标准输出流"就在当前方法中读取*/
BufferedInputStream bis = new BufferedInputStream(p.getInputStream()); if(encoding!=null && encoding.length()!=0)
{
sReader = new InputStreamReader(bis,encoding);//设置编码方式
}
else
{
sReader = new InputStreamReader(bis,"GBK");
}
bReader=new BufferedReader(sReader); StringBuilder sb=new StringBuilder();
String line; while((line=bReader.readLine())!=null)
{
sb.append(line);
sb.append("/n");
} bReader.close();
p.destroy();
return sb.toString();
}
catch(Exception e)
{
e.printStackTrace();
return ErrorString;
}
finally
{
}
} /**读取InputStream的线程*/
class InputStreamRunnable implements Runnable
{
BufferedReader bReader=null;
String type=null;
public InputStreamRunnable(InputStream is, String _type)
{
try
{
bReader=new BufferedReader(new InputStreamReader(new BufferedInputStream(is),"UTF-8"));
type=_type;
}
catch(Exception ex)
{
}
}
public void run()
{
String line;
int lineNum=0; try
{
while((line=bReader.readLine())!=null)
{
lineNum++;
//Thread.sleep(200);
}
bReader.close();
}
catch(Exception ex)
{
}
}
}

另外, Runtime.getRuntime().exec() 还有一些局限性, 就是无法像cmd那样执行较为复杂的命令. 比如, 输出流的重定向, 如:
他会立即返回, 不会去执行. 但是我们可以这样做, 能够完成于cmd中一样的工作:
其中 /c 就是"执行后面字符串的命令". 这样就OK了,但同时还是要注意"错误输出流"的问题,依然要单开一个线程读取.否则一样会阻塞的.

http://www.xuebuyuan.com/695058.html

3、Runtime.getRuntime().exec() 路基中含有空格,如下:

Runtime.getRuntime().exec("cmd.exe /c D:\\Program  Files\\tece2.1\\tececode\\updateprogram\\updateProgram.exe");

这样讲无法执行,需要在空格的前后加上双引号,而不是在整个路径的前后加双引号,如下:

Runtime.getRuntime().exec("cmd.exe /c D:\\Program\" \"Files\\tece2.1\\tececode\\updateprogram\\updateProgram.exe");

或者使用替换方式:

String  commandStr="cmd.exe /c"+" " +realPath.realTomcatPath.replace(" ", "\" \"");
Runtime.getRuntime().exec(commandStr);

http://flyeagle.iteye.com/blog/406487

cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭.hi://apps;c dir 是执行完dir命令后关闭命令窗口,原窗口不会关闭;k start dir 会打开一个新窗口后执行dir指令://apps:

还可以设置工作目录,对执行与工作目录相关的批处理文件是有用的。
File dir = new File("E:\\Product");
Process process = Runtime.getRuntime().exec("E:\\Product\\copy.bat",null,dir);
http://blog.sina.com.cn/s/blog_3d731e9001000ajm.html

今天使用nio编写一个类似ssh的网络客户端,在执行process的时候,出现了一个让人很头疼的bug,废话不说,上代码:

public static void main(String[] args)throws Exception {
Process process=Runtime.getRuntime().exec("cmd /c tree");
int status=process.exitValue();
System.out.println(status);
BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream()));
String line=null;
while((line=reader.readLine())!=null) {
System.out.println(line);
} BufferedReader error=new BufferedReader(new InputStreamReader(process.getErrorStream()));
while((line=error.readLine())!=null) {
System.out.println(line);
}
}

在process后面立即调用后

 int status=process.exitValue();

出现了
java.lang.IllegalThreadStateException: process has not exited
at java.lang.Win32Process.exitValue(Native Method)

异常,后来一百度发现,jdk实现process时,调用外部命令不是同步的调用,而是异步执行。所以tree命令还没有执行成功就返回,jdk抛出异常

后来想了一招,就是不管执行如何,先去读取process的InputStream和ErrorInputStream,也就是说

不管外部命令执行的正确与否,都先去执行一次。

//读取正确执行的返回流
BufferedReader info=new BufferedReader(new InputStreamReader(executor.getInputStream()));
while((line=info.readLine())!=null) {
infoMsg.append(line).append("\n");
} //读取错误执行的返回流
BufferedReader error=new BufferedReader(new InputStreamReader(executor.getErrorStream()));
while((line=error.readLine())!=null) {
errorMsg.append(line).append("\n");
} //调用exitValue返回值
responseCode=executor.exitValue();

这个时候,再调用exitValue()方法就不会出错了

这是一个具体的实例

        int responseCode=0;
StringBuilder infoMsg=new StringBuilder();
StringBuilder errorMsg=new StringBuilder();
String line=null; String cmd=Util.isWindows()?("cmd /c "+command):(command);
System.err.println("command is "+cmd);
Process executor=Runtime.getRuntime().exec(cmd); BufferedReader info=new BufferedReader(new InputStreamReader(executor.getInputStream()));
BufferedReader error=new BufferedReader(new InputStreamReader(executor.getErrorStream()));
while((line=info.readLine())!=null) {
infoMsg.append(line).append("\n");
} while((line=error.readLine())!=null) {
errorMsg.append(line).append("\n");
}
responseCode=executor.exitValue();

http://kingj.iteye.com/blog/1420586

java Process在windows的使用汇总(转)的更多相关文章

  1. 【JavaService】使用Java编写部署windows服务

    如果你玩windows系统,你对服务这个东西并不会陌生,服务可以帮我们做很多事情,在不影响用户正常工作的情况下,可以完成很多我们需要的需求. 众所周知,微软的visio studio内置的Servic ...

  2. Memory usage of a Java process java Xms Xmx Xmn

    http://www.oracle.com/technetwork/java/javase/memleaks-137499.html 3.1 Meaning of OutOfMemoryError O ...

  3. 玩转Windows服务系列汇总

    玩转Windows服务系列汇总 创建Windows服务 Debug.Release版本的注册和卸载及其原理 无COM接口Windows服务启动失败原因及解决方案 服务运行.停止流程浅析 Windows ...

  4. java Process的waitFor()

    java Process的waitFor() 在编写Java程序时,有时候我们需要调用其他的诸如exe,shell这样的程序或脚本.在Java中提供了两种方法来启动其他程序: (1) 使用Runtim ...

  5. Java ssh 访问windows/Linux

     Java ssh 访问windows/Linux 工作中遇到的问题: Java code运行在一台机器上,需要远程到linux的机器同时执行多种命令.原来采用的方法是直接调用ssh命令或者调用pli ...

  6. 玩转Windows服务系列汇总(9篇文章)

    玩转Windows服务系列汇总 创建Windows服务Debug.Release版本的注册和卸载及其原理无COM接口Windows服务启动失败原因及解决方案服务运行.停止流程浅析Windows服务小技 ...

  7. Windows 10 快捷键汇总表格

    Windows 10 快捷键汇总表格 Windows 10 快捷键汇总 Win键 + Tab 激活任务视图 Win键 + A 激活操作中心 Win键 + C 通过语音激活Cortana Win键 + ...

  8. 如何注册java程序为windows服务

    如何注册java 程序为windows 服务 最近想找个软件来控制电脑的关机时间,在网上找了几个,都是可视化界面的可以设置具体的关机时间的软件.由于我想编写的关机程序是运行在别人机器上,只能让该机器在 ...

  9. Java基础知识常见面试题汇总第一篇

    [Java面试题系列]:Java基础知识常见面试题汇总 第一篇 文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 ​ 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后 ...

随机推荐

  1. VPN指定某个程序,其实是改路由表(赛风支持VPN和SSH和SSH+模式)

    其实就是使用IE代理的意思,方法有很多.最简单的就是读取注册表中的代理信息.具体找;\Software\Microsoft\Windows\CurrentVersion\Internet Settin ...

  2. HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)

    HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...

  3. Java获取随机数的几种方法

    Java获取随机数的几种方法 .使用org.apache.commons.lang.RandomStringUtils.randomAlphanumeric()取数字字母随机10位; //取得一个3位 ...

  4. CSS3实现时间轴效果

    原文:CSS3实现时间轴效果 最近打开电脑就能看到极客学院什么新用户vip免费一个月,就进去看看咯,这里就不说它的课程怎么滴了,里面实战路径图页面看到了这个效果: 有点像时间轴的赶脚,而且每一块鼠标悬 ...

  5. Swift - 使用Auto Layout和Size Classes实现页面自适应弹性布局

    在过去只有iphone4的时候,可以在代码里将一个可视单元的位置写死,这样是没问题的,但随着iPhone5,6的发布,屏幕尺寸有了越来越多种可能.这就要求App的UI控件具有在不同屏幕尺寸的设备上具有 ...

  6. C++学习之路—继承与派生(二):派生类的构造函数与析构函数

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 由于基类的构造函数和析构函数是不能被继承的,所以 ...

  7. 通过cl_dd_document来实现在ALV中输出标题头

    *&---------------------------------------------------------------------* *& Report ZTEST_LIN ...

  8. 用js实现插入排序

    话不多说,直接上代码 html源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  9. [积累]C++复习 海大2014硕士生面试题微信系统总结

    好久没用C++了,正好同学有个面试题,于是就帮忙看了一下.尽管对C++的知识了解不少, 可是长期被Java浸淫, 发现这个简单的程序却也写着也不是那么顺手.好在最后还是搞定了,以下分析一下,题目例如以 ...

  10. 编译android-4.3.1_r源代码并刷到自己的Galaxy Nexus I9250真机上

    编译android-4.3.1_r源代码并刷到自己的Galaxy Nexus I9250真机上 作者:雨水  日期:2014-04-30 编译源码的目的还是为了自己改动源码,然后还可以执行在相应的手机 ...