想实现这样的功能,程序自身运行完后删除自己这个EXE文件。
通过写一个BAT文件来删除,不知道哪出了问题,请教各位大牛指点迷津。
BAT文件是这样的内容:
:pp
del d:\TestRun.exe
if exist d:\TestRun.exe goto pp
del %0
java文件:
import java.io.*;
import java.io.IOException;public class TestRun{
public static void main(String[] args){
FileWriter fw = null;
String batcode = ":pp\ndel d:\\TestRun.exe\nif exist d:\\TestRun.exe goto pp\ndel %0"; try{
fw = new FileWriter("d:/te.bat");
fw.write(batcode,0,batcode.length());
fw.close();
String cmd = "cmd.exe /c d:\\te.bat";
Runtime.getRuntime( ).exec( cmd );
}catch(IOException e){
e.printStackTrace();
System.out.println("文件写入错误");
System.exit(-1);
}
}
}java文件编译后做成TestRun.exe,存在D盘根目录下。
功能实现不了,请各位指点迷津,这个测试程序该怎么写。100分在线等。
通过写一个BAT文件来删除,不知道哪出了问题,请教各位大牛指点迷津。
BAT文件是这样的内容:
:pp
del d:\TestRun.exe
if exist d:\TestRun.exe goto pp
del %0
java文件:
import java.io.*;
import java.io.IOException;public class TestRun{
public static void main(String[] args){
FileWriter fw = null;
String batcode = ":pp\ndel d:\\TestRun.exe\nif exist d:\\TestRun.exe goto pp\ndel %0"; try{
fw = new FileWriter("d:/te.bat");
fw.write(batcode,0,batcode.length());
fw.close();
String cmd = "cmd.exe /c d:\\te.bat";
Runtime.getRuntime( ).exec( cmd );
}catch(IOException e){
e.printStackTrace();
System.out.println("文件写入错误");
System.exit(-1);
}
}
}java文件编译后做成TestRun.exe,存在D盘根目录下。
功能实现不了,请各位指点迷津,这个测试程序该怎么写。100分在线等。
1、在bat中启动该exe程序;
2、在同一个bat中检查exe退出码是否正常(为了避免如果失败了,用户还要重复运行);
3、在同一个bat中删除该exe程序(这时exe程序已经运行完毕退出了)。
1、另一个独立进程(而非子进程)中执行删除命令;
2、exe程序结束(退出)。尝试用 start 而非 cmd 命令来启动bat脚本吧。
1、另一个独立进程(而非子进程)中执行删除命令;
2、exe程序结束(退出)。尝试用 start 而非 cmd 命令来启动bat脚本吧。
public static void main(String[] args){
Runtime.getRuntime().addShutdownHook(new Thread() { //追加程序结束hook,也就是说程序结束时会调用这个hook处理
public void run() {
Runtime.getRuntime().exec("cmd d:/te.bat"); //在hook处理中调用bat删除程序
}
}); //以下是LZ生成bat文件的代码
FileWriter fw = null;
String batcode = ":pp\ndel d:\\TestRun.exe\nif exist d:\\TestRun.exe goto pp\ndel %0";try{
fw = new FileWriter("d:/te.bat");
fw.write(batcode,0,batcode.length());
fw.close();
String cmd = "cmd.exe /c d:\\te.bat";
Runtime.getRuntime( ).exec( cmd );}catch(IOException e){
e.printStackTrace();
System.out.println("文件写入错误");
System.exit(-1);
}}
}
不错:
del /Q /F %0
尝试了我4楼说的:用start代替cmd么?
做了个测试,可以成功删除编译后的class文件和临时bat文件import java.io.*;
import java.lang.management.*;
public class DelTest {
public static void main(String[] args){
//在删除程序之前,强制杀掉当前进程,所以程序启动时先获取程序进程ID
final String pid = ManagementFactory.getRuntimeMXBean().getName().replaceAll("(\\d+).*", "$1");
Runtime.getRuntime().addShutdownHook(new Thread() { //添加程序结束hook
public void run() {
try {
Runtime.getRuntime().exec("taskkill /F /PID " + pid); //先强制杀死进程
Runtime.getRuntime().exec("e:\\Test\\del.bat");//再调用bat删除文件,这里直接调用bat,不需要使用cmd或start } catch (Exception e) {
e.printStackTrace();
}
}
}); //注意bat文件是\r\n换行
String batcode = ":pp\r\ndel /F /Q e:\\Test\\DelTest*.class\r\nif exist e:\\Test\\DelTest*.class goto pp\r\ndel /F /Q %0\r\n"; try{
PrintStream ps = new PrintStream("e:\\Test\\del.bat");
ps.print(batcode); //其实为了保证\r\n换行,可以用ps.println(cmdstr)来输出每一行bat指令
ps.close(); } catch (IOException e){
e.printStackTrace();
} }
}
還有class文件看來可以在程序執行時被刪除
Runtime.getRuntime().exec("taskkill /F /PID " + pid); //这里会杀死父进程,但是子进程未必马上执行
Runtime.getRuntime().exec("e:\\Test\\del.bat");//所以父进程有可能能执行到这里才被杀死其次,Runtime的exec启动的进程是独立的,即使父进程死亡了,子进程依然进行,可以通过以下的例子来验证import java.io.*;
import java.lang.management.*;
import javax.swing.*;public class DelTest {
public static void main(String[] args) throws Throwable {
final String pid = ManagementFactory.getRuntimeMXBean().getName().replaceAll("(\\d+).*", "$1");
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
//Runtime.getRuntime().exec("taskkill /F /PID " + pid);
//Runtime.getRuntime().exec("e:\\Test\\del.bat");
//启动一个子进程打开一个窗口,看看父进程死亡后子进程是否死亡
Runtime.getRuntime().exec("java.exe TestFrame");
sleep(1000); //为了保证后续代码延迟,主线程稍微休眠一会 System.out.println("杀死父进程前...");
//启动一个子进程杀死父进程
Runtime.getRuntime().exec("taskkill /F /PID " + pid);
sleep(2000); //为了保证后续代码的延迟,主线程稍微休眠一会,注释掉这行再试试看
System.out.println("杀死父进程后..."); //这里没有被打印,
//说明父进程死亡后,父进程后续代码不会被执行
//但是窗口没有关闭,说明子进程没有因为父进程死亡而结束
} catch (Exception e) {
e.printStackTrace();
}
}
}); String batcode = ":pp\r\ndel /F /Q e:\\Test\\DelTest*.class\r\nif exist e:\\Test\\DelTest*.class goto pp\r\ndel /F /Q %0\r\n"; try{
PrintStream ps = new PrintStream("e:\\Test\\del.bat");
ps.print(batcode);
ps.close(); } catch (IOException e){
e.printStackTrace();
}
}
}class TestFrame extends JFrame {
public TestFrame() {
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
} public static void main(String[] args) {
new TestFrame();
}
}所以,最初9L的代码应该是可以的,只是由于子进程可能还没来得及被执行,父进程就退出了,所以可以在启动子进程以后稍微延迟一会就好了,因为LZ原来的bat本身是带有循环删除的import java.io.*;
import java.lang.management.*;public class DelTest {
public static void main(String[] args) throws Throwable {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
Runtime.getRuntime().exec("e:\\Test\\del.bat"); //不用杀死父进程了
sleep(2000); //延迟父进程结束时间,让子进程有机会启动后父进程再退出就可以了 } catch (Exception e) {
e.printStackTrace();
}
}
}); String batcode = ":pp\r\ndel /F /Q e:\\Test\\DelTest*.class\r\nif exist e:\\Test\\DelTest*.class goto pp\r\ndel /F /Q %0\r\n"; try{
PrintStream ps = new PrintStream("e:\\Test\\del.bat");
ps.print(batcode);
ps.close(); } catch (IOException e){
e.printStackTrace();
}
}
}
另外,还有一种思路,可以考虑用File的deleteOnExit()
比如
File f = new File("xxx\\yyy.exe");
f.deleteOnExit();
不知道效果如何,删除程序本身测试过,删除其他文件应该是没问题的
Runtime.getRuntime().exec("taskkill /F /PID " + pid); //这里会杀死父进程,但是子进程未必马上执行
Runtime.getRuntime().exec("e:\\Test\\del.bat");//所以父进程有可能能执行到这里才被杀死其次,Runtime的exec启动的进程是独立的,即使父进程死亡了,子进程依然进行,可以通过以下的例子来验证import java.io.*;
import java.lang.management.*;
import javax.swing.*;public class DelTest {
public static void main(String[] args) throws Throwable {
final String pid = ManagementFactory.getRuntimeMXBean().getName().replaceAll("(\\d+).*", "$1");
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
//Runtime.getRuntime().exec("taskkill /F /PID " + pid);
//Runtime.getRuntime().exec("e:\\Test\\del.bat");
//启动一个子进程打开一个窗口,看看父进程死亡后子进程是否死亡
Runtime.getRuntime().exec("java.exe TestFrame");
sleep(1000); //为了保证后续代码延迟,主线程稍微休眠一会 System.out.println("杀死父进程前...");
//启动一个子进程杀死父进程
Runtime.getRuntime().exec("taskkill /F /PID " + pid);
sleep(2000); //为了保证后续代码的延迟,主线程稍微休眠一会,注释掉这行再试试看
System.out.println("杀死父进程后..."); //这里没有被打印,
//说明父进程死亡后,父进程后续代码不会被执行
//但是窗口没有关闭,说明子进程没有因为父进程死亡而结束
} catch (Exception e) {
e.printStackTrace();
}
}
}); String batcode = ":pp\r\ndel /F /Q e:\\Test\\DelTest*.class\r\nif exist e:\\Test\\DelTest*.class goto pp\r\ndel /F /Q %0\r\n"; try{
PrintStream ps = new PrintStream("e:\\Test\\del.bat");
ps.print(batcode);
ps.close(); } catch (IOException e){
e.printStackTrace();
}
}
}class TestFrame extends JFrame {
public TestFrame() {
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
} public static void main(String[] args) {
new TestFrame();
}
}所以,最初9L的代码应该是可以的,只是由于子进程可能还没来得及被执行,父进程就退出了,所以可以在启动子进程以后稍微延迟一会就好了,因为LZ原来的bat本身是带有循环删除的import java.io.*;
import java.lang.management.*;public class DelTest {
public static void main(String[] args) throws Throwable {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
Runtime.getRuntime().exec("e:\\Test\\del.bat"); //不用杀死父进程了
sleep(2000); //延迟父进程结束时间,让子进程有机会启动后父进程再退出就可以了 } catch (Exception e) {
e.printStackTrace();
}
}
}); String batcode = ":pp\r\ndel /F /Q e:\\Test\\DelTest*.class\r\nif exist e:\\Test\\DelTest*.class goto pp\r\ndel /F /Q %0\r\n"; try{
PrintStream ps = new PrintStream("e:\\Test\\del.bat");
ps.print(batcode);
ps.close(); } catch (IOException e){
e.printStackTrace();
}
}
}
另外,还有一种思路,可以考虑用File的deleteOnExit()
比如
File f = new File("xxx\\yyy.exe");
f.deleteOnExit();
不知道效果如何,删除程序本身测试过,删除其他文件应该是没问题的
删除程序本身没测试过,因为不知道LZ怎么编译成exe的
不知道是怎么回事,第一遍生成的exe文件,达到了预想的效果。但是后来exe文件运行的几遍测试后都没有达到预想的效果,不是留有bat文件就是连exe文件也没删除掉!
我用的win7操作系统加360安全卫士,不知道和这个有没有关系。