java Process在windows的使用汇总(转)

最常用的是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

 

时间: 2024-11-02 23:50:09

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

工程中Java Code Review发现的问题汇总

工程中Java Code Review发现的问题汇总 概述 最近对团队内近期开发的一些Java web工程进行了Code Review,这些Code主要是需要在多个工程中复用的基础组件,Java代码为主.审核中发现了一些编码问题(暂时不考虑设计模式.架构层面的),这里进行一下汇总总结. 问题列表 注释 普通的程序员最痛恨接手或使用没有文档的代码,而程序员一般又不喜欢些文档,代码注释是文档的一种,在Code Review中发现工具扫描时注释率很高,但是真正进去去看,注释率极低. 接口一定要有详细的

java代码读取windows的系统日志

问题描述 java代码读取windows的系统日志 比如安全日志,事件日志 ,都是以.evtx,不要用Logpaser等工具什么的,只用java代码 解决方案 http://technet.microsoft.com/zh-cn/scriptcenter/dd919274 http://www.codeforge.com/article/222452

Java Process.getInputstream的问题

问题描述 Java Process.getInputstream的问题 RT,调用这个方法获取了子进程的输出.我想问一下,这个方法对于子进程的输出流大小有限制吗?http://bbs.csdn.net/topics/320123911,这个帖子里说是有限制的,我实际遇到的情况也是有限制但是我去查了Java API,里面并没有提到输出流大小限制啊,http://docs.oracle.com/javase/8/docs/api/ 所以想请教一下大神,到底这个方法对于输出流的大小有木有限制吖!!!

求高手相助:Java写的windows服务,在windows2003上......

问题描述 Java写的windows服务,使用本地系统身份登录,在windows2003上:代码pro=Runtime.getRuntime().exec("cmd/ctime14:20:20");pro.waitFor();可以运行成功代码pro=Runtime.getRuntime().exec("cmd/cdate2011-02-23");pro.waitFor();运行起来,进程就死在这,不往下执行了. 解决方案 解决方案二:顶楼,坐等高人回复解决方案三:有

Java发送邮件遇到的常见需求汇总_java

基于SMTP发送一个简单的邮件 首先,需要一个认证器: package No001_基于SMTP的文本邮件; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; public class SimpleAuthenticator extends Authenticator { private String username; private String password; public Simple

Java实现的Windows资源管理器实例_java

本文实例讲述了Java实现的Windows资源管理器.分享给大家供大家参考.具体如下: FileTree.java文件如下: // FileTree.java /*********************************************************** * Author: Jason * email: tl21cen@hotmail.com * CSDN blog: http://blog.csdn.net/UnAgain/ *********************

java怎么调用windows系统的msmq?

问题描述 java怎么调用windows系统的msmq?进行收发消息,创建删除消息? 解决方案 解决方案二:msmq是什么东西?解决方案三:需要JavaMicrosoftMessageQueuingLibrary解决方案四:楼上正解....

XP升级到Windows 7问题汇总

跳过Vista而直接从XP升级至Windows 7,可能是绝大部分用户系统升级的必然选择.针对这种情况,本文列出常见的XP升级至Win 7问题汇总,以供读者参考: 1.我能否从Windows XP直接升级至Windows 7? 可以,无需通过Vista中转. 2.XP可否就地升级(in-place)至Windows 7? 不能.只有Vista用户可以选择"就地升级".微软表示,在硬件支持和驱动模式等方面存在诸多变化,因此从XP"就地升级"至Windows 7并非最佳

管理Java类路径(Windows)

类路径可以连接 Java 运行库和文件系统.它定义编译器和解释器应该在何处查找要加载的 .class 文件.它的基本思想是:文件系统的层次结构反映了 Java 包的层次结构,而类路径则定义了文件系统中的哪个目录可以作为 Java 包层次结构的根. 遗憾的是,通常文件系统非常复杂并依赖于平台,而且和 Java 包也不能很好地匹配.尤其是在 Windows 环境中更是如此.Java 是一些 Unix 高手设计的,因而从很多方面来说,这也就意味着它无法很好地与 Windows 约定同步.这样一来,不论