如何检测外部进程退出Java JNA

时间:2015-02-01 19:37:33

标签: java winapi jna waitforsingleobject

如何使用JNA检测Java中的外部进程退出? 我的programm exec外部aplication1,这个application1启动另一个application2并退出后。 Ant我的任务是从application2获取退出代码。我可以得到一个子进程的pid并尝试检测它。但是waitForSingleObject并不起作用。我想我做错了什么。帮助)

     ProcessBuilder processBuilder;
        int pid = 0;
        int pid2 = 0;
        String gpath = "path of application1";
        processBuilder = new ProcessBuilder(gpath);
        processBuilder.directory(new File(gpath.substring(0, gpath.lastIndexOf("\\") + 1)));
        Process process = processBuilder.start();

        if (process.getClass().getName().equals("java.lang.Win32Process") ||
                process.getClass().getName().equals("java.lang.ProcessImpl")) {
            try {
                Field f = process.getClass().getDeclaredField("handle");
                f.setAccessible(true);
                long handl = f.getLong(process);

                Kernel32 kernel = Kernel32.INSTANCE;
                WinNT.HANDLE handle = new WinNT.HANDLE();
                handle.setPointer(Pointer.createConstant(handl));
                pid = kernel.GetProcessId(handle);
                System.out.println("pid "+pid);
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
        Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
        Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();

        WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
        List<Tlhelp32.PROCESSENTRY32> processentry32List = new ArrayList<>();
        try {
            while (kernel32.Process32Next(snapshot, processEntry)) {
                processentry32List.add(processEntry);
            }

        } finally {
            kernel32.CloseHandle(snapshot);
        }


        for (Tlhelp32.PROCESSENTRY32 processentry32 : processentry32List) {
            if (processentry32.th32ParentProcessID.intValue() == pid) {
                pid2 = processentry32.th32ProcessID.intValue();
                System.out.println("pid2 "+pid2);
                break;
            }
        }

        WinNT.HANDLE gameHandle =    Kernel32.INSTANCE.OpenProcess(0x0400,false,pid2);
        Kernel32.INSTANCE.WaitForSingleObject(gameHandle,Kernel32.INFINITE);
if(Kernel32.INSTANCE.GetExitCodeProcess(gameHandle, exitCode)){
System.out.println("application closed without error");
}else{
System.out.println("application closed with error " + Kernel32.INSTANCE.GetLastError()););
}

0 个答案:

没有答案