diff --git "a/1.1.5\347\211\210\346\234\254\344\271\213\345\211\215\347\232\204\345\206\205\345\255\230\351\227\256\351\242\230\350\247\243\345\206\263\346\226\271\346\241\210.md" "b/1.1.5\347\211\210\346\234\254\344\271\213\345\211\215\347\232\204\345\206\205\345\255\230\351\227\256\351\242\230\350\247\243\345\206\263\346\226\271\346\241\210.md"
new file mode 100644
index 00000000..55f62e8b
--- /dev/null
+++ "b/1.1.5\347\211\210\346\234\254\344\271\213\345\211\215\347\232\204\345\206\205\345\255\230\351\227\256\351\242\230\350\247\243\345\206\263\346\226\271\346\241\210.md"
@@ -0,0 +1,207 @@
+## step 1 导入jna包
+```xml
+
+ net.java.dev.jna
+ jna
+ 5.13.0
+
+```
+## step 2 创建内部接口
+```java
+public interface Kernel32 extends StdCallLibrary {
+ Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class);
+ long GetProcessId(Long hProcess);
+}
+```
+
+## step 3 写获取进程id的方法
+
+````java
+ /**
+ * 获取进程id
+ * @param process chrome进程 可以通过{@link com.ruiyun.jvppeteer.core.browser.Browser#process()} 获取}
+ * @return 进程id
+ */
+public static String getProcessId(Process process) {
+ long pid = -1;
+ Field field;
+ if (Platform.isWindows()) {
+ try {
+ field = process.getClass().getDeclaredField("handle");
+ field.setAccessible(true);
+ pid = BrowserRunner.Kernel32.INSTANCE.GetProcessId((Long) field.get(process));
+ } catch (Exception e) {
+ LOGGER.error("Failed to get processId on Windows platform.",e);
+ }
+ } else if (Platform.isLinux() || Platform.isAIX()) {
+ try {
+ String version = System.getProperty("java.version");
+ double jdkversion = Double.parseDouble(version.substring(0, 3));
+ Class> clazz;
+ //如果生产环境是jdk8,就不用if判断了
+ if (jdkversion <= 1.8) {
+ clazz = Class.forName("java.lang.UNIXProcess");
+ } else {
+ clazz = Class.forName("java.lang.ProcessImpl");
+ }
+ field = clazz.getDeclaredField("pid");
+ field.setAccessible(true);
+ pid = (Integer) field.get(process);
+ } catch (Throwable e) {
+ LOGGER.error("Failed to get processId on Linux or Aix platform.",e);
+ }
+ }
+ return String.valueOf(pid);
+}
+````
+## step 4 通过kill 命令杀死进程
+
+````java
+/**
+ * kill 掉浏览器进程
+ */
+public boolean kill() {
+ try {
+ String pid = pidMap.get(this.process);
+ if("-1".equals(pid)){
+ LOGGER.warn("Chrome process pid is -1,will not use kill cmd");
+ return false;
+ }
+ if(StringUtil.isEmpty(pid) ){
+ LOGGER.warn("Chrome process pid is empty,will not use kill cmd");
+ return false;
+ }
+ Process exec = null;
+ String command = "";
+ if (Platform.isWindows()) {
+ command = "cmd.exe /c taskkill /PID " + pid + " /F /T ";
+ } else if (Platform.isLinux() || Platform.isAIX()) {
+ command = "kill -9 " + pid;
+ }
+ LOGGER.info("kill chrome process by pid,command: kill -9 {}", pid);
+ exec = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",command});
+ return exec.waitFor(Constant.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ LOGGER.error("kill chrome process error ", e);
+ return false;
+ }
+}
+````
+## 完整代码示例
+````java
+
+package com.ruiyun.example;
+
+import com.ruiyun.jvppeteer.core.Constant;
+import com.ruiyun.jvppeteer.core.Puppeteer;
+import com.ruiyun.jvppeteer.core.browser.Browser;
+import com.ruiyun.jvppeteer.core.browser.BrowserRunner;
+import com.ruiyun.jvppeteer.core.page.Page;
+import com.ruiyun.jvppeteer.options.LaunchOptions;
+import com.ruiyun.jvppeteer.options.LaunchOptionsBuilder;
+import com.ruiyun.jvppeteer.util.StringUtil;
+import com.sun.jna.Native;
+import com.sun.jna.Platform;
+import com.sun.jna.win32.StdCallLibrary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class KillExample {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BrowserRunner.class);
+ /**
+ * 多个browser的时候用pids储存pid
+ */
+ private static Map pids = new HashMap<>();
+ public static void main(String[] args) throws IOException, InterruptedException {
+ LaunchOptions launchOptions = new LaunchOptionsBuilder().withExecutablePath("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe").withIgnoreDefaultArgs(Collections.singletonList("--enable-automation")).withHeadless(false).build();
+ Browser browser = Puppeteer.launch(launchOptions);
+ Page page = browser.newPage();
+ page.goTo("https://www.baidu.com/?tn=98012088_10_dg&ch=3");
+ Process process = browser.process();
+ String processId = getProcessId(process);
+ KillExample.LOGGER.info("process pid {}",processId);
+ // 做一些其他操作
+
+
+ browser.close(); //可以关闭websocket连接
+ kill(processId);
+ }
+
+ public interface Kernel32 extends StdCallLibrary {
+ Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class);
+ long GetProcessId(Long hProcess);
+ }
+
+ public static String getProcessId(Process process) {
+ long pid = -1;
+ Field field;
+ if (Platform.isWindows()) {
+ try {
+ field = process.getClass().getDeclaredField("handle");
+ field.setAccessible(true);
+ pid = KillExample.Kernel32.INSTANCE.GetProcessId((Long) field.get(process));
+ } catch (Exception e) {
+ KillExample.LOGGER.error("Failed to get processId on Windows platform.",e);
+ }
+ } else if (Platform.isLinux() || Platform.isAIX()) {
+ try {
+ String version = System.getProperty("java.version");
+ double jdkversion = Double.parseDouble(version.substring(0, 3));
+ Class> clazz;
+ //如果生产环境是jdk8,就不用if判断了
+ if (jdkversion <= 1.8) {
+ clazz = Class.forName("java.lang.UNIXProcess");
+ } else {
+ clazz = Class.forName("java.lang.ProcessImpl");
+ }
+ field = clazz.getDeclaredField("pid");
+ field.setAccessible(true);
+ pid = (Integer) field.get(process);
+ } catch (Throwable e) {
+ KillExample.LOGGER.error("Failed to get processId on Linux or Aix platform.",e);
+ }
+ }
+ return String.valueOf(pid);
+ }
+
+ public static boolean kill(String pid) {
+ try {
+ if("-1".equals(pid)){
+ LOGGER.warn("Chrome process pid is -1,will not use kill cmd");
+ return false;
+ }
+ if(StringUtil.isEmpty(pid) ){
+ LOGGER.warn("Chrome process pid is empty,will not use kill cmd");
+ return false;
+ }
+ Process exec = null;
+ String command = "";
+ if (Platform.isWindows()) {
+ command = "cmd.exe /c taskkill /PID " + pid + " /F /T ";
+ exec = Runtime.getRuntime().exec(command);
+ } else if (Platform.isLinux() || Platform.isAIX()) {
+ command = "kill -9 " + pid;
+ exec = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",command});
+ }
+ if (exec != null) {
+ return exec.waitFor(Constant.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+ } catch (Exception e) {
+ LOGGER.error("kill chrome process error ", e);
+ return false;
+ }
+ return false;
+ }
+}
+
+````
+
+
diff --git a/example/src/main/java/com/ruiyun/example/KillExample.java b/example/src/main/java/com/ruiyun/example/KillExample.java
new file mode 100644
index 00000000..bcd307e7
--- /dev/null
+++ b/example/src/main/java/com/ruiyun/example/KillExample.java
@@ -0,0 +1,109 @@
+package com.ruiyun.example;
+
+import com.ruiyun.jvppeteer.core.Constant;
+import com.ruiyun.jvppeteer.core.Puppeteer;
+import com.ruiyun.jvppeteer.core.browser.Browser;
+import com.ruiyun.jvppeteer.core.browser.BrowserRunner;
+import com.ruiyun.jvppeteer.core.page.Page;
+import com.ruiyun.jvppeteer.options.LaunchOptions;
+import com.ruiyun.jvppeteer.options.LaunchOptionsBuilder;
+import com.ruiyun.jvppeteer.util.StringUtil;
+import com.sun.jna.Native;
+import com.sun.jna.Platform;
+import com.sun.jna.win32.StdCallLibrary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class KillExample {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BrowserRunner.class);
+ /**
+ * 多个browser的时候用pids储存pid
+ */
+ private static Map pids = new HashMap<>();
+ public static void main(String[] args) throws IOException, InterruptedException {
+ LaunchOptions launchOptions = new LaunchOptionsBuilder().withExecutablePath("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe").withIgnoreDefaultArgs(Collections.singletonList("--enable-automation")).withHeadless(false).build();
+ Browser browser = Puppeteer.launch(launchOptions);
+ Page page = browser.newPage();
+ page.goTo("https://www.baidu.com/?tn=98012088_10_dg&ch=3");
+ Process process = browser.process();
+ String processId = getProcessId(process);
+ KillExample.LOGGER.info("process pid {}",processId);
+ kill(processId);
+ // 做一些其他操作
+ browser.close();
+ }
+
+ public interface Kernel32 extends StdCallLibrary {
+ Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class);
+ long GetProcessId(Long hProcess);
+ }
+
+ public static String getProcessId(Process process) {
+ long pid = -1;
+ Field field;
+ if (Platform.isWindows()) {
+ try {
+ field = process.getClass().getDeclaredField("handle");
+ field.setAccessible(true);
+ pid = KillExample.Kernel32.INSTANCE.GetProcessId((Long) field.get(process));
+ } catch (Exception e) {
+ KillExample.LOGGER.error("Failed to get processId on Windows platform.",e);
+ }
+ } else if (Platform.isLinux() || Platform.isAIX()) {
+ try {
+ String version = System.getProperty("java.version");
+ double jdkversion = Double.parseDouble(version.substring(0, 3));
+ Class> clazz;
+ //如果生产环境是jdk8,就不用if判断了
+ if (jdkversion <= 1.8) {
+ clazz = Class.forName("java.lang.UNIXProcess");
+ } else {
+ clazz = Class.forName("java.lang.ProcessImpl");
+ }
+ field = clazz.getDeclaredField("pid");
+ field.setAccessible(true);
+ pid = (Integer) field.get(process);
+ } catch (Throwable e) {
+ KillExample.LOGGER.error("Failed to get processId on Linux or Aix platform.",e);
+ }
+ }
+ return String.valueOf(pid);
+ }
+
+ public static boolean kill(String pid) {
+ try {
+ if("-1".equals(pid)){
+ LOGGER.warn("Chrome process pid is -1,will not use kill cmd");
+ return false;
+ }
+ if(StringUtil.isEmpty(pid) ){
+ LOGGER.warn("Chrome process pid is empty,will not use kill cmd");
+ return false;
+ }
+ Process exec = null;
+ String command = "";
+ if (Platform.isWindows()) {
+ command = "cmd.exe /c taskkill /PID " + pid + " /F /T ";
+ exec = Runtime.getRuntime().exec(command);
+ } else if (Platform.isLinux() || Platform.isAIX()) {
+ command = "kill -9 " + pid;
+ exec = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",command});
+ }
+ if (exec != null) {
+ return exec.waitFor(Constant.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+ } catch (Exception e) {
+ LOGGER.error("kill chrome process error ", e);
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/ruiyun/jvppeteer/core/Puppeteer.java b/src/main/java/com/ruiyun/jvppeteer/core/Puppeteer.java
index 52a2a679..60a6beee 100644
--- a/src/main/java/com/ruiyun/jvppeteer/core/Puppeteer.java
+++ b/src/main/java/com/ruiyun/jvppeteer/core/Puppeteer.java
@@ -5,16 +5,11 @@
import com.ruiyun.jvppeteer.launch.ChromeLauncher;
import com.ruiyun.jvppeteer.launch.FirefoxLauncher;
import com.ruiyun.jvppeteer.launch.Launcher;
-import com.ruiyun.jvppeteer.options.BrowserOptions;
-import com.ruiyun.jvppeteer.options.ChromeArgOptions;
-import com.ruiyun.jvppeteer.options.FetcherOptions;
-import com.ruiyun.jvppeteer.options.LaunchOptions;
-import com.ruiyun.jvppeteer.options.LaunchOptionsBuilder;
+import com.ruiyun.jvppeteer.options.*;
import com.ruiyun.jvppeteer.transport.ConnectionTransport;
import com.ruiyun.jvppeteer.util.StringUtil;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
import static com.ruiyun.jvppeteer.core.Constant.PRODUCT_ENV;
diff --git a/src/main/java/com/ruiyun/jvppeteer/core/browser/BrowserRunner.java b/src/main/java/com/ruiyun/jvppeteer/core/browser/BrowserRunner.java
index d9536895..cedbf2e6 100644
--- a/src/main/java/com/ruiyun/jvppeteer/core/browser/BrowserRunner.java
+++ b/src/main/java/com/ruiyun/jvppeteer/core/browser/BrowserRunner.java
@@ -217,6 +217,9 @@ public void onBrowserEvent(Object event) {
* kill 掉浏览器进程
*/
public boolean kill() {
+ if(this.closed){
+ return true;
+ }
try {
String pid = pidMap.get(this.process);
if("-1".equals(pid)){
@@ -231,13 +234,16 @@ public boolean kill() {
String command = "";
if (Platform.isWindows()) {
command = "cmd.exe /c taskkill /PID " + pid + " /F /T ";
+ exec = Runtime.getRuntime().exec(command);
} else if (Platform.isLinux() || Platform.isAIX()) {
command = "kill -9 " + pid;
+ exec = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",command});
}
try {
- LOGGER.info("kill chrome process by pid,command: kill -9 {}", pid);
- exec = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",command});
- return exec.waitFor(Constant.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ if (exec != null) {
+ LOGGER.info("kill chrome process by pid,command: {}", command);
+ return exec.waitFor(Constant.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
} finally {
this.destroyCmdProcess(exec,command);
if (StringUtil.isNotEmpty(this.tempDirectory)) {
@@ -248,6 +254,7 @@ public boolean kill() {
LOGGER.error("kill chrome process error ", e);
return false;
}
+ return false;
}
diff --git a/src/main/java/com/ruiyun/jvppeteer/util/Helper.java b/src/main/java/com/ruiyun/jvppeteer/util/Helper.java
index 5fa72c14..2147c66e 100644
--- a/src/main/java/com/ruiyun/jvppeteer/util/Helper.java
+++ b/src/main/java/com/ruiyun/jvppeteer/util/Helper.java
@@ -534,7 +534,6 @@ public static String getProcessId(Process process) {
try {
String version = System.getProperty("java.version");
double jdkversion = Double.parseDouble(version.substring(0, 3));
- System.out.println("jdkversion = " +jdkversion);
Class> clazz;
if (jdkversion <= 1.8) {
clazz = Class.forName("java.lang.UNIXProcess");