mvn 依赖
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
原理很简单,获取 Chrome 浏览器插件默认存储位置,遍历出插件信息并批量复制插件到 下载 目录,可以在其它 Chrome 浏览器中以 加载已解压拓展程序 安装插件,适用于在 chrome 插件商城下载某插件,但 edge 或 360 等浏览器商城里没该插件,互联网第三方网站也没有,此时这种直接提取方式最方便,代码
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class Main {public static void main(String[] args) throws IOException {
// 获取 Windows 用户名
String username = System.getenv("USERNAME");
// 构建 Chrome 插件数据目录路径
String chromeExtensionsDir = "C:\\Users\\" + username + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions";
System.out.println(chromeExtensionsDir);
File extensionsDir = new File(chromeExtensionsDir);
if (extensionsDir.exists() && extensionsDir.isDirectory()) {File[] extensionFolders = extensionsDir.listFiles((dir, name) -> name.length() == 32);
if (extensionFolders != null) {for (File extensionFolder : extensionFolders) {String extensionId = extensionFolder.getName();
System.out.println("Processing extension with ID: " + extensionId);
// 寻找最新修改的子文件夹
File latestSubFolder = findLatestSubFolder(extensionFolder);
if (latestSubFolder != null) {String version = latestSubFolder.getName();
// 解析 manifest.json 文件
String pluginName = parseManifestForName(latestSubFolder);
// 构建下载目录路径
String downloadDir = System.getenv("USERPROFILE") + "\\Downloads";
File downloadDirectory = new File(downloadDir);
// 复制文件夹到下载目录
// copyFolder(latestSubFolder, downloadDirectory, pluginName + "_" + version);
CopyOption[] options = new CopyOption[]{
StandardCopyOption.REPLACE_EXISTING, // 替换已存在的文件
StandardCopyOption.COPY_ATTRIBUTES // 复制文件属性
};
String pluginFullName = pluginName.replace(" ", "") + "_" + version;
System.out.println("pluginFullName: " + pluginFullName);
FileUtils.copyDirectory(latestSubFolder, new File(downloadDirectory + "\\" + pluginFullName)
, null, false, options);
}
}
}
}
}
private static File findLatestSubFolder(File folder) {File[] subFolders = folder.listFiles((dir, name) -> dir.isDirectory());
List<File> subFoldersList = Arrays.stream(subFolders)
.filter(File::isDirectory)
.collect(Collectors.toList());
for (File subFolder : subFoldersList) {System.out.println("version: " + subFolder.getName());
}
if (!subFoldersList.isEmpty()) {return subFoldersList.stream()
.max(Comparator.comparingLong(File::lastModified))
.orElse(null);
}
return null;
}
private static String parseManifestForName(File folder) {File manifestFile = new File(folder, "manifest.json");
JSONParser parser = new JSONParser();
try (FileReader reader = new FileReader(manifestFile)) {JSONObject jsonObject = (JSONObject) parser.parse(reader);
String name = (String) jsonObject.get("name");
if (name.contains("MSG_")) {
// 假设 action 是一个 JSONObject
JSONObject actionObject = (JSONObject) jsonObject.get("action");
if (actionObject != null) {
// 获取 default_title 字段值
String defaultTitle = (String) actionObject.get("default_title");
if (defaultTitle != null) {name = defaultTitle;}
}
}
return name;
} catch (IOException | org.json.simple.parser.ParseException e) {e.printStackTrace();
return null;
}
}
private static void copyFolder(File sourceFolder, File targetDirectory, String newFolderName) {File newFolder = new File(targetDirectory, newFolderName);
try {if (!newFolder.exists()) {boolean created = newFolder.mkdir();
if (!created) {System.out.println("Failed to create new folder: " + newFolderName);
return;
}
}
Files.walk(sourceFolder.toPath())
.sorted(Comparator.reverseOrder())
.forEach(path -> {try {Path targetPath = Paths.get(targetDirectory.getPath(), newFolderName,
path.toString().substring(sourceFolder.getPath().length()));
Files.copy(path, targetPath);
} catch (IOException e) {e.printStackTrace();
}
});
} catch (IOException e) {e.printStackTrace();
}
}
}