JNAを使用してJavaで外部プロセスの終了を検出する方法は? 私のプログラム実行外部アプリケーション1、このアプリケーション1は他のアプリケーション2を起動し、終了後に終了します。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()););
}