批处理文件进程在Java中被终止:xcopy未关闭

批处理文件进程在Java中被终止:xcopy未关闭,java,batch-file,xcopy,kill-process,Java,Batch File,Xcopy,Kill Process,这看起来应该很容易解决,但我对批处理文件的使用还不够熟悉,无法自己解决。我有一个Java方法,它创建一个process builder并在流程中运行一个批处理文件。批处理文件使用xcopy命令将一个目录复制到另一个目录。当批处理文件在后台运行时,一个包含JTextArea的Java窗口将显示进程的输出(正在复制的目录)。该窗口还有一个停止按钮,它调用以下代码: stopped = true; backgroundTask.cancel(true); backgroundTask.done();

这看起来应该很容易解决,但我对批处理文件的使用还不够熟悉,无法自己解决。我有一个Java方法,它创建一个process builder并在流程中运行一个批处理文件。批处理文件使用xcopy命令将一个目录复制到另一个目录。当批处理文件在后台运行时,一个包含JTextArea的Java窗口将显示进程的输出(正在复制的目录)。该窗口还有一个停止按钮,它调用以下代码:

stopped = true;
backgroundTask.cancel(true);
backgroundTask.done();
“完成”方法如下所示:

protected void done() {
    statusLabel.setText((this.getState()).toString() + " " + status);
    stopButton.setEnabled(false);
    bar.setIndeterminate(false);
    if(stopped == false){
        JOptionPane.showMessageDialog(null, "Backup Complete.");
        closeWindow();
    }
    else if (stopped == true){
        JOptionPane.showMessageDialog(null, "Backup Cancelled.");
        closeWindow();
    }
}
现在,为了在后台运行批处理文件,我使用以下代码(最初由垃圾神向我建议):

我遇到的问题是:当我运行程序时,除非我按下前台窗口上的停止按钮,否则文件复制得很好。当我这样做时,它告诉我备份被取消了(正如它应该做的那样),但它会让三个额外的进程运行,这三个进程在任务管理器中可见:

我的猜测是第一个--“扩展拷贝实用程序”是罪魁祸首。因为它没有关闭,所以它会让另外两个cmd进程继续运行。然而,这是一个相当缺乏教育的猜测

当我运行程序并停止它时,windows资源管理器变得非常不稳定,有时冻结,有时完全崩溃。在文件夹中导航(尤其是要复制到的目录)的速度非常慢,而且即使进程(据说)停止,目录仍会继续被复制。我相信这是因为这些线永远无法达到:

p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
p.destroy();
所以这个过程永远不会被扼杀。当按下停止按钮时,我仍在研究一种完全终止进程的方法,但如果有人有想法,我很乐意听到

编辑

我选择发布整个类,因为仅仅给出某些方法可能无法提供足够的信息。下面是全班同学:

package diana;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class Progress extends JFrame {
    public String[] commands;
    private final JLabel statusLabel = new JLabel("Status: ", JLabel.CENTER);
    private final JTextArea textArea = new JTextArea(20, 20);
    private JButton stopButton = new JButton("Stop");
    private JProgressBar bar = new JProgressBar();
    private BackgroundTask backgroundTask;
    private ProcessBuilder pb;
    private Process p;
    public boolean stopped = false;

    public void setCommands(String[] cmds) {
        commands = cmds;
    }
    private final ActionListener buttonActions = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            JButton source = (JButton) ae.getSource();
            if (source == stopButton) {
                stopped = true;
                backgroundTask.cancel(true);
                backgroundTask.done();
            } else {
                backgroundTask = new BackgroundTask(commands);
            }
        }
    };

    private void displayGUI(String[] cmds) {
        commands = cmds;
        JFrame frame = new JFrame("Backup Progress");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        panel.setLayout(new BorderLayout(5, 5));
        JScrollPane sp = new JScrollPane();
        sp.setBorder(BorderFactory.createTitledBorder("Output: "));
        sp.setViewportView(textArea);
        textArea.setText(null);
        stopButton.setEnabled(true);
        backgroundTask = new BackgroundTask(commands);
        backgroundTask.execute();
        bar.setIndeterminate(true);
        stopButton.addActionListener(buttonActions);
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(stopButton);
        buttonPanel.add(bar);
        panel.add(statusLabel, BorderLayout.PAGE_START);
        panel.add(sp, BorderLayout.CENTER);
        panel.add(buttonPanel, BorderLayout.PAGE_END);
        frame.setContentPane(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    /* Close current window */
    public void closeWindow() throws IOException {
        p.getInputStream().close();
        p.getOutputStream().close();
        p.getErrorStream().close();
        p.destroy();
        WindowEvent close = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);
        System.exit(0);
    }

    private class BackgroundTask extends SwingWorker<Integer, String> {
        private int status;
        public String[] commands;
        public BackgroundTask(String[] cmds) {
            commands = cmds;
            statusLabel.setText((this.getState()).toString());
        }

        @Override
        protected Integer doInBackground() throws IOException {
            try {
                pb = new ProcessBuilder(commands);
                pb.redirectErrorStream(true);
                p = pb.start();
                String s;
                BufferedReader stdout = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));
                while ((s = stdout.readLine()) != null && !isCancelled()) {
                    publish(s);
                }
                if (!isCancelled()) {
                    status = p.waitFor();
                }
                closeWindow();
            } catch (IOException | InterruptedException ex) {
                ex.printStackTrace(System.err);
            }
            return status;
        }

        @Override
        protected void process(List<String> messages) {
            statusLabel.setText((this.getState()).toString());
            for (String message : messages) {
                textArea.append(message + "\n");
            }
        }

        @Override
        protected void done() {
            statusLabel.setText((this.getState()).toString() + " " + status);
            stopButton.setEnabled(false);
            bar.setIndeterminate(false);
            if (stopped == false) {
                JOptionPane.showMessageDialog(null, "Backup Complete.");
                try {
                    closeWindow();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else if (stopped == true) {
                JOptionPane.showMessageDialog(null, "Backup Cancelled.");
                try {
                    closeWindow();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void run(String[] cmds) {
        commands = cmds;
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Progress().displayGUI(commands);
            }
        });
    }
}
package;
导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.Toolkit;
导入java.awt.event.*;
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.util.List;
导入javax.swing.*;
@抑制警告(“串行”)
公共类进程扩展JFrame{
公共字符串[]命令;
专用最终JLabel statusLabel=新JLabel(“状态:”,JLabel.CENTER);
私有最终JTextArea textArea=新JTextArea(20,20);
私有JButton stopButton=新JButton(“停止”);
私有JProgressBar=新JProgressBar();
私人背景任务背景任务;
私有进程生成器pb;
私有进程p;
公共布尔停止=false;
公共void setCommands(字符串[]cmds){
commands=cmds;
}
私有最终ActionListener按钮操作=新建ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
JButton source=(JButton)ae.getSource();
如果(源==停止按钮){
停止=真;
backgroundTask.cancel(true);
backgroundTask.done();
}否则{
backgroundTask=新的backgroundTask(命令);
}
}
};
私有void displayGUI(字符串[]cmds){
commands=cmds;
JFrame=新JFrame(“备份进度”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel面板=新的JPanel();
panel.setBorder(BorderFactory.createEmptyByOrder(5,5,5,5));
面板设置布局(新边框布局(5,5));
JScrollPane sp=新的JScrollPane();
sp.setboorder(BorderFactory.createTitledBorder(“输出:”);
sp.setViewportView(文本区域);
textArea.setText(空);
stopButton.setEnabled(真);
backgroundTask=新的backgroundTask(命令);
backgroundTask.execute();
bar.setUndeterminate(真);
stopButton.addActionListener(按钮操作);
JPanel buttonPanel=新的JPanel();
按钮面板。添加(停止按钮);
按钮面板。添加(条);
panel.add(状态标签、边框布局、页面开始);
面板.添加(sp,BorderLayout.CENTER);
面板。添加(按钮面板,边框布局。第页\结束);
frame.setContentPane(面板);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
/*关闭当前窗口*/
public void closeWindow()引发IOException{
p、 getInputStream().close();
p、 getOutputStream().close();
p、 getErrorStream().close();
p、 破坏();
WindowEvent close=新的WindowEvent(这是WindowEvent.WINDOW\u CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(关闭);
系统出口(0);
}
私有类BackgroundTask扩展SwingWorker{
私人身份;
公共字符串[]命令;
公共背景任务(字符串[]cmds){
commands=cmds;
statusLabel.setText((this.getState()).toString());
}
@凌驾
受保护的整数doInBackground()引发IOException{
试一试{
pb=新的ProcessBuilder(命令);
pb.重定向错误流(真);
p=pb.start();
字符串s;
BufferedReader标准输出=新的BufferedReader(
新的InputStreamReader(p.getInputStream());
而((s=stdout.readLine())!=null&&!isCancelled()){
出版;
}
如果(!isCancelled()){
状态=p.waitFor();
}
关闭窗口();
}捕获(IOException | InterruptedException ex){
例如printStackTrace(System.err);
}
返回状态;
}
@凌驾
受保护的无效进程(列出消息){
地位
package diana;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class Progress extends JFrame {
    public String[] commands;
    private final JLabel statusLabel = new JLabel("Status: ", JLabel.CENTER);
    private final JTextArea textArea = new JTextArea(20, 20);
    private JButton stopButton = new JButton("Stop");
    private JProgressBar bar = new JProgressBar();
    private BackgroundTask backgroundTask;
    private ProcessBuilder pb;
    private Process p;
    public boolean stopped = false;

    public void setCommands(String[] cmds) {
        commands = cmds;
    }
    private final ActionListener buttonActions = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            JButton source = (JButton) ae.getSource();
            if (source == stopButton) {
                stopped = true;
                backgroundTask.cancel(true);
                backgroundTask.done();
            } else {
                backgroundTask = new BackgroundTask(commands);
            }
        }
    };

    private void displayGUI(String[] cmds) {
        commands = cmds;
        JFrame frame = new JFrame("Backup Progress");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        panel.setLayout(new BorderLayout(5, 5));
        JScrollPane sp = new JScrollPane();
        sp.setBorder(BorderFactory.createTitledBorder("Output: "));
        sp.setViewportView(textArea);
        textArea.setText(null);
        stopButton.setEnabled(true);
        backgroundTask = new BackgroundTask(commands);
        backgroundTask.execute();
        bar.setIndeterminate(true);
        stopButton.addActionListener(buttonActions);
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(stopButton);
        buttonPanel.add(bar);
        panel.add(statusLabel, BorderLayout.PAGE_START);
        panel.add(sp, BorderLayout.CENTER);
        panel.add(buttonPanel, BorderLayout.PAGE_END);
        frame.setContentPane(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    /* Close current window */
    public void closeWindow() throws IOException {
        p.getInputStream().close();
        p.getOutputStream().close();
        p.getErrorStream().close();
        p.destroy();
        WindowEvent close = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);
        System.exit(0);
    }

    private class BackgroundTask extends SwingWorker<Integer, String> {
        private int status;
        public String[] commands;
        public BackgroundTask(String[] cmds) {
            commands = cmds;
            statusLabel.setText((this.getState()).toString());
        }

        @Override
        protected Integer doInBackground() throws IOException {
            try {
                pb = new ProcessBuilder(commands);
                pb.redirectErrorStream(true);
                p = pb.start();
                String s;
                BufferedReader stdout = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));
                while ((s = stdout.readLine()) != null && !isCancelled()) {
                    publish(s);
                }
                if (!isCancelled()) {
                    status = p.waitFor();
                }
                closeWindow();
            } catch (IOException | InterruptedException ex) {
                ex.printStackTrace(System.err);
            }
            return status;
        }

        @Override
        protected void process(List<String> messages) {
            statusLabel.setText((this.getState()).toString());
            for (String message : messages) {
                textArea.append(message + "\n");
            }
        }

        @Override
        protected void done() {
            statusLabel.setText((this.getState()).toString() + " " + status);
            stopButton.setEnabled(false);
            bar.setIndeterminate(false);
            if (stopped == false) {
                JOptionPane.showMessageDialog(null, "Backup Complete.");
                try {
                    closeWindow();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else if (stopped == true) {
                JOptionPane.showMessageDialog(null, "Backup Cancelled.");
                try {
                    closeWindow();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void run(String[] cmds) {
        commands = cmds;
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Progress().displayGUI(commands);
            }
        });
    }
}
InputStream is = null;
Process p = null;
try {
    ProcessBuilder pb = new ProcessBuilder(commands);
    pb.redirectErrorStream(true);
    p = pb.start();

    StringBuilder sb = new StringBuilder(128);
    is = p.getInputStream();
    int in = -1;
    while (!isCancelled() && (in = is.read()) != -1) {
        sb.append((char)in));
        if (((char)in) == '\n') {
            publish(sb.toString());
            sb.delete(0, sb.length());
        }
    }
    if (!isCancelled()) {
        status = p.waitFor();
    } else {
        p.destroy();
    }
} catch (IOException ex) {
    ex.printStackTrace(System.err);
} catch (InterruptedException ex) {
    ex.printStackTrace(System.err);
    try {
        p.destroy();
    } catch (Exception exp) {
    }
} finally {
    try {
        is.close();
    } catch (Exception exp) {
    }
    // Make sure you are re-syncing this to the EDT first...
    closeWindow();
}
static void copyTree(final Path source, final Path destination)
throws IOException {
    if (Files.isDirectory(source)) {
        Files.walkFileTree(source, new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult preVisitDirectory(Path dir,
                                         BasicFileAttributes attributes)
            throws IOException {
                if (Thread.interrupted()) {
                    throw new InterruptedIOException();
                }

                Path destinationDir =
                    destination.resolve(source.relativize(dir));
                Files.createDirectories(destinationDir);

                BasicFileAttributeView view =
                    Files.getFileAttributeView(destinationDir,
                        BasicFileAttributeView.class);
                view.setTimes(
                    attributes.lastModifiedTime(),
                    attributes.lastAccessTime(),
                    attributes.creationTime());

                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFile(Path file,
                                         BasicFileAttributes attributes)
            throws IOException {
                if (Thread.interrupted()) {
                    throw new InterruptedIOException();
                }

                Files.copy(file,
                    destination.resolve(source.relativize(file)),
                    StandardCopyOption.COPY_ATTRIBUTES,
                    LinkOption.NOFOLLOW_LINKS);

                return FileVisitResult.CONTINUE;
            }
        });
    } else {
        Files.copy(source, destination,
            StandardCopyOption.COPY_ATTRIBUTES,
            LinkOption.NOFOLLOW_LINKS);
    }
}