/// <summary> /// 获取路径path下的所有apk文件,或apk解包根目录信息 /// </summary> public static Dictionary <string, string> getApk_FileOrDir(String path) { Dictionary <string, string> FileDir = new Dictionary <string, string>(); // 若载入的为apk文件 if (Apktool.isApkDir(path) || Apktool.isApkFile(path)) { string name = System.IO.Path.GetFileName(path); FileDir.Add(name, path); } else { Dictionary <string, string> apks = getFileNameByExt(path, ".apk"); // 获取所有apk文件信息 Dictionary <string, string> apkDirs = getApkDir(path); // 获取所有apk解包路径信息 // 优先添加apk文件的解包目录 foreach (string dir in apkDirs.Keys) { FileDir.Add(dir, apkDirs[dir]); } // 再添加没有解包目录的apk文件 foreach (string apk in apks.Keys) { String dir = apk.Replace(".apk", "").TrimEnd('.'); if (!apkDirs.Keys.Contains(dir)) { FileDir.Add(apk, apks[apk]); } } } return(FileDir); }
private void UnPack_Logic() { OutPut("【I】"); if (Apktool.isApkFile(file.Text)) // 解包 { OutPut("【I】apk解包开始..."); String result = Apktool.unPackage(file.Text, OutPut, false, false); // 使用apktool进行apk的解包 if (result.Contains("【E】")) { return; } OutPut("【I】apk解包结束!\r\n"); } else if (Apktool.isApkDir(file.Text)) // 打包 { OutPut("【I】apk打包开始..."); String result = Apktool.package(file.Text, OutPut); // 使用apktool进行打包 if (result.Contains("【E】")) { return; } OutPut("【I】apk未签名文件已生成!\r\n"); // 若有签名文件,则进行签名 if (!comboBox_sign.Text.Equals("")) { OutPut("【I】apk签名中..."); String apkName = file.Text + "..apk"; String pem = SinPath() + "\\" + comboBox_sign.Text + ".x509.pem"; String pk8 = SinPath() + "\\" + comboBox_sign.Text + ".pk8"; String psw = "letang123"; result = Apktool.Sign(apkName, pem, pk8, psw, OutPut); if (result.Contains("【E】")) { return; } OutPut("【I】apk签名、对齐 完成!\r\n"); // 删除打包生成的未签名文件 if (System.IO.File.Exists(apkName)) { System.IO.File.Delete(apkName); } } OutPut("【I】apk打包结束!\r\n"); } else { Cmd.Run(file.Text, OutPut); // 执行cmd命令 } }
private bool isApkDir(String paths) { String[] A = paths.Split(';'); foreach (String path in A) { if (Apktool.isApkDir(path) || Apktool.isApkFile(path)) { return(true); } } return(false); }
/// <summary> /// 判定执行对应逻辑 /// </summary> private void file_TextChanged(object sender, EventArgs e) { if (Apktool.isApkFile(file.Text)) { unPack.Text = "apk解包"; // 若为apk文件则,可解包 } else if (Apktool.isApkDir(file.Text)) { unPack.Text = "apk打包"; // 若为apk解包文件夹,则可打包 } else { unPack.Text = "执行cmd"; } comboBox_sign.Visible = Apktool.isApkDir(file.Text); // 若为打包操作,可选择签名 }
/// <summary> /// 获取path目录下的所有apk解包目录信息 /// </summary> public static Dictionary <string, string> getApkDir(string path) { Dictionary <string, string> dic = new Dictionary <string, string>(); if (Directory.Exists(path)) { DirectoryInfo directoryInfo = new DirectoryInfo(path); DirectoryInfo[] dirs = directoryInfo.GetDirectories(); foreach (DirectoryInfo dir in dirs) { if (dir.Name.Equals("附加资源")) { continue; // 忽略附加资源目录 } // 若为apk解包目录或文件,则直接添加 if (Apktool.isApkDir(dir.FullName)) { dic.Add(dir.Name, dir.FullName); } // 若非apk解包目录,则检索其目录下的apk文件和子文件夹 else { Dictionary <string, string> listInner = getApk_FileOrDir(dir.FullName); foreach (String subApk in listInner.Keys) { if (!dic.Keys.Contains(subApk)) { dic.Add(subApk, listInner[subApk]); } } } } } return(dic); }
static bool showCopyInfo = false; // 是否显示复制信息 /// <summary> /// 对两个apk解包后的文件进行混合,复制目录dirSource下的文件到dirDest中 /// </summary> public static void Combine(String dirSource, String dirDest, Cmd.Callback call) { if (Apktool.isApkDir(dirDest) && Apktool.isApkDir(dirSource)) { Cmd.Callback tmp = Settings.call; // 记录call Settings.call = call; Settings setting = Settings.Load(dirSource, dirDest); //setting.GetPackageName_GAMEPRE_CHANNEL(dirSource, dirDest); // 更新渠道参数信息 // 若设置为使用所有渠道通用基础配置,则拷贝混合基础配置信息到游戏包 if (setting.useAllChannelCommon) { ToolSetting toolSet = ToolSetting.Instance(); // 载入配置信息 //String AllChannelCommon = toolSet.chargeAPK_dir + "\\所有渠道\\附加资源"; // 获取所有渠道配置目录 //ToolSetting.confirmDir(AllChannelCommon); //// 混合所有渠道公用配置 //if (!ApkCombine.isEmptyDirectorty(AllChannelCommon)) //{ // if (call != null) call("【L】拷贝所有渠道附加资源:"); // Combine(AllChannelCommon, dirDest, call); // if (call != null) call("【I】拷贝所有渠道附加资源完成!"); //} String commonDir = toolSet.chargeAPK_dir + "\\所有渠道"; // 获取所有渠道配置目录 Dictionary <String, String> apk_dirs = Form3.getApk_FileOrDir(commonDir); // 获取目录下的apk文件或解压目录 if (apk_dirs.Count > 0) { String apk_dir = apk_dirs.Values.ToArray <String>()[0]; if (call != null) { call("【I】"); } if (call != null) { call("【I】---------------------------------"); } if (call != null) { call("【L】混合,所有渠道,通用基础包资源:\r\n" + apk_dir); } // 所有渠道通用apk解包 String AllChannelCommon = Form2.apkUnpack(apk_dir, call); // 获取所有渠道配置目录 if (AllChannelCommon.Contains("【E】")) { return; } // 混合所有渠道公用配置 if (!ApkCombine.isEmptyDirectorty(AllChannelCommon)) { if (call != null) { call("【L】拷贝所有渠道附加资源:"); } Combine(AllChannelCommon, dirDest, call); if (call != null) { call("【I】拷贝所有渠道附加资源完成!"); } } if (call != null) { call("【I】---------------------------------\r\n"); } // 拷贝所有渠道配置中的【其他渠道参数替换文件列表】 string str = FileProcess.fileToString(AllChannelCommon + ".txt"); Settings allChannel = Settings.Parse(str); setting.addSettings(allChannel, 5); setting.ReplaceLateParams(); // 替换设置的关键字信息为在线获取的参数 // 清除所有渠道通用配置缓存 Apktool.DeletDir(AllChannelCommon); Apktool.DeletFile(AllChannelCommon + ".txt"); // 清除配置文件信息 } } if (call != null) { call("【L】1、拷贝文件前,清除游戏包中指定的文件:"); } RemoveDirFile(dirDest, call, setting); if (call != null) { call("【L】2、复制所有文件,并忽略忽略列表中的文件和目录:"); } CopyFolderTo_Ignore(dirSource, dirDest, call, setting); // 复制所有文件,并忽略忽略列表中的文件和目录 if (call != null) { call("【L】3、附加拷贝,附加列表中的文件和目录:"); } CopyFolderTo_addCopyDir(dirSource, dirDest, call, setting); // 附加拷贝,附加列表中的文件和目录 RemoveDirFile(dirDest, call, setting); // 清除复制时,原有目录 String ManifestPath = dirDest + "\\" + "AndroidManifest.xml"; if (File.Exists(ManifestPath)) { if (call != null) { call("【L】4、修改Manifest.xml文件:"); } Manifest manifest = new Manifest(ManifestPath); // 创建Manifest对象 Settings.gameLabel = manifest.label; // 获取游戏显示名称,如: @string/app_name manifest.runCMD(setting.ManifestCMD); // 执行manifest修改逻辑 manifest.save(); // 保存manifest Settings.gameIcon = manifest.icon; // 获取游戏图标名称,如: @drawable/icon } setting.ReplaceFiles_ChannelParams(dirDest); // 替换其他文件中配置的渠道参数变量 setting.ProcessIcon(dirDest); // 处理icon Settings.call = tmp; //还原call } }