0

我使用 Runtime.getRuntime().exec(String cmd) 函数打开办公文件(docx、xlsx)。同时,我将这些文件的元数据存储在数据库中。为了保持完整性,我在元数据中使用标志锁定文件,以便其他用户不能同时修改文件。这意味着必须在用户关闭文件(例如关闭外部进程)后自动重置标志。

这是打开文件的片段:

File file = new File("c:/test.docx");
Process process = null;
if(file.getName().endsWith("docx")) {
    process = Runtime.getRuntime().exec("c:/msoffice/WINWORD.EXE "+file.getAbsolutePath());
} else if(file.getName().endsWith("xlsx")) {
    process = Runtime.getRuntime().exec("c:/msoffice/EXCEL.EXE "+file.getAbsolutePath());
}
if(process!=null) {
    new ProcessExitListener(file, process);
}

这是我的监听器,它一直等到用户关闭文件(最后通过在元数据中设置标志来解锁文件):

private class ProcessExitListener extends Thread {

    private File file;
    private Process process;

    public ProcessExitListener(File file, Process process) throws IOException {
        this.setName("File-Thread ["+process.toString()+"]");
        this.file = file;
        this.process = process;
        this.start();
    }

    @Override
    public void run() {
        try {
            process.waitFor();
            database.unlock(file);
        } catch (InterruptedException ex) {
            // print exception
        }
    }
}

这适用于不同的文件类型,例如,如果我同时打开 1 个 docx 和 1 个 xlsx 文件。但是当打开 2 个 docx 文件时,其中一个进程在初始化后立即退出。

任何想法为什么?

提前感谢您的帮助!

4

1 回答 1

1

但是当打开 2 个 docx 文件时,其中一个进程在初始化后就存在。

可能是因为winword.exe进程发现它已经有一个实例在运行,所以它没有在内存中保留两个实例,而是要求第一个实例打开第二个文档。不知道从 GUI 角度看它的外观如何,但是查看任务管理器,尝试从 Windows 资源管理器中打开两个 Word 文档。第二个文件不会导致第二个winword.exe进程启动。

我可以在 Ubuntu Linux 上重现完全相同的行为。当我跑的时候:

$ geany foo.txt

并且geany编辑器尚未运行,控制台挂起,直到我关闭编辑器。但是,如果我打开另一个终端并调用:

$ geany bar.txt

这会立即返回,并且bar.txt只是作为现有进程中的另一个选项卡打开。

于 2012-10-31T19:45:44.467 回答