// AndroidChannelPackage.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
//
|
|
#include <iostream>
|
#include <direct.h>
|
#include <string>
|
#include <stdio.h>
|
#include <io.h>
|
#include <list>
|
#include "tinyxml2.h"
|
#include <filesystem>
|
using namespace std;
|
using namespace tinyxml2;
|
namespace fs = std::filesystem;
|
|
void delete_dir(const std::string& path) {
|
if (fs::exists(path)) {
|
fs::directory_iterator end;
|
for (fs::directory_iterator it(path); it != end; ++it) {
|
if (fs::is_directory(it->status())) {
|
delete_dir(it->path().string()); // 递归删除子目录
|
}
|
else {
|
fs::remove(it->path()); // 删除文件
|
}
|
}
|
fs::remove(path); // 删除空目录本身
|
}
|
}
|
|
void create_dir(string path) {
|
if (_access(path.c_str(), 0) < 0) {
|
_mkdir(path.c_str());
|
}
|
}
|
|
// 创建新的AndroidManifest文件
|
void createChannelManifest(string sourcePath,string newPath,string channel) {
|
XMLDocument xmlDoc;
|
XMLError eResult = xmlDoc.LoadFile(sourcePath.c_str());
|
if (eResult != XML_SUCCESS)
|
{
|
cout << "打开源配置文件失败\n";
|
return;
|
}
|
XMLElement* pRoot = xmlDoc.FirstChildElement();
|
XMLElement* pElement = pRoot->FirstChildElement("application");
|
for (XMLElement* elemobj = pElement->FirstChildElement("meta-data");
|
elemobj != NULL; elemobj = elemobj->NextSiblingElement("meta-data")) {
|
string meta_name = elemobj->Attribute("android:name");
|
if (meta_name == "UMENG_CHANNEL") {
|
// cout << elemobj->Attribute("android:value") << endl;
|
elemobj->SetAttribute("android:value", channel.c_str());
|
//cout << elemobj->Attribute("android:value") << endl;
|
break;
|
}
|
}
|
|
eResult = xmlDoc.SaveFile(newPath.c_str());
|
|
if (eResult != XML_SUCCESS)
|
cout << "保存新配置文件失败\n";
|
}
|
|
void exec_cmd(string cmd) {
|
cout << cmd << endl;
|
system(cmd.c_str());
|
}
|
|
void package(string apk_path,string channel_str,string key_path,string key_pwd,string key_alias,string key_alias_pwd) {
|
cout << "---开始---" << endl;
|
//删除缓存文件夹
|
delete_dir("./workspace/cache");
|
delete_dir("./workspace/dist");
|
|
//创建缓存文件夹
|
create_dir("./workspace");
|
create_dir("./workspace/cache");
|
create_dir("./workspace/dist");
|
|
cout << "---删除缓存目录---" << endl;
|
|
|
// 解压AndroidManifest
|
string cmd = "";
|
cmd.append("unzip ").append(apk_path).append(" AndroidManifest.xml -d ./workspace/cache/");
|
exec_cmd(cmd);
|
cout << "---解压AndroidManifest.xml---" << endl;
|
// 解码AndroidManifest
|
cmd = "java -jar xml2axml.jar d";
|
cmd.append(" ./workspace/cache/AndroidManifest.xml").append(" ./workspace/cache/AndroidManifest-readable-out.xml");
|
exec_cmd(cmd);
|
cout << "---解码AndroidManifest.xml---" << endl;
|
// 修改内容
|
std::list<string> channels;
|
int start_index = 0;
|
for (int i = 0; i < channel_str.size(); i++) {
|
if (channel_str[i] == ',') {
|
channels.push_back(channel_str.substr(start_index,i-start_index));
|
start_index = i + 1;
|
}
|
}
|
if (start_index > 0) {
|
channels.push_back(channel_str.substr(start_index, channel_str.size() - start_index));
|
}
|
else if (channel_str.size() > 0) {
|
channels.push_back(channel_str);
|
}
|
|
string apk_name = apk_path;
|
if (apk_path.find("/") != string::npos) {
|
apk_name = apk_path.substr(apk_path.find_last_of("/") + 1, apk_path.size() - apk_path.find_last_of("/"));
|
}
|
else if (apk_path.find("\\") != string::npos) {
|
apk_name = apk_path.substr(apk_path.find_last_of("\\") + 1, apk_path.size() - apk_path.find_last_of("\\"));
|
}
|
|
for (std::list<string>::iterator ele = channels.begin(); ele != channels.end(); ++ele) {
|
cout << "---渠道打包开始:"<<*ele<<"---" << endl;
|
string cache_dir_path = string("./workspace/cache/").append(*ele);
|
string new_apk_path = string(cache_dir_path).append("/").append(apk_name);
|
//创建文件夹
|
create_dir(cache_dir_path);
|
|
//将apk文件复制进缓存目录
|
cmd = string("copy \"").append(apk_path).append("\" \"").append(cache_dir_path).append("\\\"");
|
exec_cmd(cmd);
|
cout << "创建临时文件夹完成" << endl;
|
|
//修改渠道名称
|
createChannelManifest("./workspace/cache/AndroidManifest-readable-out.xml", string(cache_dir_path).append("/AndroidManifest-readable.xml"), *ele);
|
cout << "修改渠道名称完成" << endl;
|
//编码AndroidManifest
|
cmd = "java -jar xml2axml.jar e";
|
cmd.append(" ").append(string(cache_dir_path).append("/AndroidManifest-readable.xml")).append(" ").append(cache_dir_path).append("/AndroidManifest.xml");
|
exec_cmd(cmd);
|
cout << "AndroidManifest编码完成" << endl;
|
|
// 切换到缓存目录
|
_chdir(cache_dir_path.c_str());
|
|
//将编码后的AndroidManifest打包进apk(调用上级目录的zip命令)
|
cmd= string("..\\..\\..\\zip -u ").append(apk_name).append(" ").append("AndroidManifest.xml");
|
exec_cmd(cmd);
|
|
cout << "AndroidManifest打入新包完成" << endl;
|
|
_chdir("..\\..\\..\\");
|
//签名apk
|
string signed_new_apk_path =string("./workspace/dist/").append( string(apk_name.substr(0, apk_name.size()-4))).append("_").append(*ele).append("_signed.apk");
|
cmd = string("echo ").append(key_pwd) .append( string("|apksigner sign --ks ")).append(key_path).append(" --ks-key-alias ").append(key_alias).append(" --zipalign --v1-signing-enabled true --v2-signing-enabled true ").append("--in ").append(new_apk_path).append(" --out ").append(signed_new_apk_path);
|
exec_cmd(cmd);
|
cout << "重新签名完成" << endl;
|
cout << "---渠道打包结束:" << *ele << "---" << endl;
|
//echo "weikou2015" | jarsigner -verbose -keystore D:\项目\影音\签名\doudouvideo.jks -signedjar ./workspace/dist/影视大全-3.10.23-已加固_xiaomi_signed.apk ./workspace/cache/xiaomi/影视大全-3.10.23-已加固.apk 豆豆 | echo "weikou2015"
|
//apksigner sign --ks D:\\项目\\影音\\签名\\doudouvideo.jks --ks-key-alias 豆豆 --v1-signing-enabled true --v2-signing-enabled true --in 影视大全布丸_3.10.24_release_31024_jiagu.apk --out output.apk
|
}
|
|
|
|
}
|
|
int main(int argc, char* argv[])
|
{
|
//apk文件地址 渠道英文逗号分隔 签名文件地址 密码 别名 别名密码
|
//
|
for (int i = 1; i < argc; i++) {
|
std::cout << i << ":" << string(argv[i]) << std::endl;
|
}
|
if (argc > 1) {
|
std::cout << "参数个数:" << argc << std::endl;
|
package(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
|
}
|
else {
|
//测试
|
package("E:\\WXWork\\1688855861247320\\Cache\\File\\2023-11\\影视大全布丸_3.10.25_release_64位_31025_jiagu.apk", "meizu", "D:\\项目\\影音\\签名\\doudouvideo.jks", "weikou2015", "豆豆", "weikou2015");
|
|
}
|
}
|