示例#1
0
        /// <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);
        }
示例#2
0
        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命令
            }
        }
示例#3
0
        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);
        }
示例#4
0
        //==========================
        // apk解包打包逻辑封装

        /// <summary>
        /// 若为apk文件,则先行解包
        /// </summary>
        public static String apkUnpack(String apkFile, Cmd.Callback call, bool deletPublicXML = false)
        {
            // 若输入的为apk文件,则自动进行解包
            if (Apktool.isApkFile(apkFile))
            {
                if (call != null)
                {
                    call("【I】" + Path.GetFileName(apkFile));
                }
                if (call != null)
                {
                    call("【I】apk解包开始...");
                }

                string dir = Apktool.unPackage(apkFile, call, deletPublicXML);   // 使用apktool进行apk的解包
                if (dir.Contains("【E】"))
                {
                    return(dir);
                }

                if (call != null)
                {
                    call("【I】apk解包结束!\r\n");
                }

                // 拷贝apk目录下的配置文件到解包文件所在目录
                String configTxt  = apkFile.Replace(".apk", ".txt");
                String configTxt2 = apkFile.Replace(".apk", "-" + Settings.gameId + ".txt");    // 可按游戏获取游戏id对应的配置文件
                if (File.Exists(configTxt2) && !File.Exists(dir + ".txt"))
                {
                    File.Copy(configTxt2, dir + ".txt", false);
                }
                else if (File.Exists(configTxt) && !File.Exists(dir + ".txt"))
                {
                    File.Copy(configTxt, dir + ".txt", false);
                }

                if (File.Exists(dir + ".txt"))
                {
                    // 添加游戏附加配置信息到渠道包,打包配置中
                    String gameAttachConfig = ToolSetting.Instance().serverRoot + "游戏附加配置\\" + Settings.gameId + ".txt";
                    Settings.AppendSettingsTo(gameAttachConfig, dir + ".txt");
                }

                return(dir);
            }
            else
            {
                return(apkFile);
            }
        }
示例#5
0
        /// <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);           // 若为打包操作,可选择签名
        }
示例#6
0
        /// <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);
        }
示例#7
0
        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
            }
        }
示例#8
0
 /// <summary>
 /// 此函数用于实时显示cmd输出信息,在richTextBox1中显示输出信息
 /// </summary>
 private void OutPut(String line)
 {
     Apktool.OutPut(line, richTextBox1, this);
 }
示例#9
0
        //从dirTarget目录下获取res资源,重新编译生成public.xml
        private static bool UpdatePublicXML(String dirTarget, Cmd.Callback call)
        {
            ToolSetting settting = ToolSetting.Instance();  // 载入设置信息

            if (call != null)
            {
                call("【I】- 2.解包Empty.apk");
            }
            String emptyApk = DependentFiles.curDir() + "\\tools\\Empty.apk";   // 空项目资源路径

            if (emptyApk.Contains("\\\\"))
            {
                emptyApk = emptyApk.Replace("\\\\", "\\");
            }
            String emptyDir = Apktool.unPackage(emptyApk, null, false);         // 解包空apk

            if (emptyDir.Contains("【E】") && call != null)
            {
                call("【E】  解包Empty.apk异常");
                return(false);
            }

            if (call != null)
            {
                call("【I】-   复制游戏res资源");
            }
            String Res = emptyDir + "\\res";

            ApkCombine.CopyFolderTo(dirTarget + "\\res", Res, true); // 复制Target目录到res目录,到空工程解包路径下

            Program.Delay(3000);                                     // 部分机器复制文件,存在异步延时,确保文件复制完成
            if (call != null)
            {
                call("【I】- 3.使用新的res资源,生成新的Empty.apk");
            }
            String apkFile = Apktool.package(emptyDir, null);                   // 使用apktool进行打包

            if (apkFile.Contains("【E】") && call != null)
            {
                call("【E】  打包Empty.apk异常");
                call("【E】  异常信息:" + apkFile);
                return(false);
            }

            if (call != null)
            {
                call("【I】- 4.解包Empty.apk");
            }
            string unpackDir = Apktool.unPackage(apkFile, null, false);         // 使用apktool进行apk的解包,生成新的public.xml

            if (unpackDir.Contains("【E】") || unpackDir.Trim().Equals(""))
            {
                if (call != null)
                {
                    call("【E】  解包Empty.apk异常");
                }
                return(false);
            }

            if (call != null)
            {
                call("【I】- 5.复制生成的public.xml文件,到游戏res目录中");
            }
            String relativePath = @"\res\values\public.xml";

            File.Copy(unpackDir + relativePath, dirTarget + relativePath, true);      // 替换原有public.xml

            relativePath = @"\res\drawable\empty_ic_launcher.png";
            File.Copy(unpackDir + relativePath, dirTarget + relativePath, true);
            relativePath = @"\res\layout\empty_activity_main.xml";
            File.Copy(unpackDir + relativePath, dirTarget + relativePath, true);

            if (call != null)
            {
                call("【I】-   清除Empty.apk相关缓存资源...");
            }

            // 清除缓存资源
            Directory.Delete(emptyDir, true);       // 删除空项目解包文件
            File.Delete(apkFile);                   // 删除生成的临时文件
            Directory.Delete(unpackDir, true);      // 删除空工程解包目录

            return(true);
        }
示例#10
0
 /// <summary>
 /// apk解包、打包
 /// </summary>
 private void unPack_Click(object sender, EventArgs e)
 {
     Apktool.clearDirInfo();
     Cmd.ThreadRun(UnPack_Logic, this, unPack, "执行中...");
 }
示例#11
0
        /// <summary>
        /// 执行apk解包文件混合逻辑
        /// </summary>
        public static void CombineApk(String dirSource, String dirTarget, String signFileName, Cmd.Callback call, bool deletTXT = true)
        {
            if (call != null)
            {
                call("【I】");
            }

            ToolSetting toolSet = ToolSetting.Instance();                                 // 载入配置信息
            String      Set_gameId = Settings.gameId, Set_channelId = Settings.channelId; // 获取游戏id、渠道id

            //-------------------------1
            // 游戏apk解包
            dirTarget = apkUnpack(dirTarget, call /*, true*/);       // 解包游戏包并删除res\values\public.xml文件
            if (dirTarget.Contains("【E】"))
            {
                return;
            }


            //-------------------------2
            // 渠道apk解包
            dirSource = apkUnpack(dirSource, call);
            //ReplaceValues.ReplaceFileContent(dirSource, "0x7f0", "0x7ff");
            //if (call != null) call("【I】替换渠道解包文件下,所有0x7f0 为 0x7ff");
            if (dirSource.Contains("【E】"))
            {
                return;
            }


            // 添加游戏Icon或Logo到游戏解包文件
            addGameAttachs(toolSet, call, dirTarget, "\\游戏Icon或Logo", Set_gameId, Set_channelId, "游戏解包目录");

            // 添加游戏Icon或Logo到渠道解包文件
            addGameAttachs(toolSet, call, dirSource, "\\游戏Icon或Logo", Set_gameId, Set_channelId, "渠道解包目录");

            //-------------------------3
            if (call != null)
            {
                call("【I】");
            }
            if (call != null)
            {
                call("【I】执行apk混合逻辑...");
            }
            if (call != null)
            {
                call("【I】添加" + dirSource + "\r\n到" + dirTarget + "中");
            }

            // 进行apk文件的混合
            ApkCombine.Combine(dirSource, dirTarget, call);
            if (call != null)
            {
                call("【I】apk混合完成!\r\n");
            }

            //-------------------------4
            // 添加渠道附加资源
            addChannelAttachs(toolSet, call, dirTarget, "\\附加资源", Set_channelId);

            // 添加游戏包附加资源
            addGameAttachs(toolSet, call, dirTarget, "\\附加资源", Set_gameId, Set_channelId);

            //-------------------------5
            // 执行R文件修改逻辑
            if (toolSet.R_Process)
            {
                bool R_result = R_process.Start(dirTarget, dirSource, call, toolSet.apktool_yml_Process, toolSet.R_Process_Game);
                if (!R_result)
                {
                    return;
                }
            }

            //String path = R_process.create_publicXML(dirTarget, call);
            //String package = Settings.channel_param["package"];                     // 获取包名信息
            //R_process.rebuidR_smali(path, dirTarget + "\\smali", package, call);    // 重新生成包名路径下的R文件
            //File.Copy(path, dirTarget + @"\res\values\public.xml");                 // 替换原有public.xml

            //-------------------------6
            // apk重新打包
            String result = apkPackage(dirTarget, signFileName, call);

            if (result.Contains("【E】"))
            {
                return;
            }

            // 打包完成后清除缓存中的解包文件
            if (call != null)
            {
                call("【I】清除缓存目录," + dirSource);
            }
            Apktool.DeletDir(dirSource);

            if (call != null)
            {
                call("【I】清除缓存目录," + dirTarget);
            }
            Apktool.DeletDir(dirTarget);

            if (deletTXT)
            {
                if (call != null)
                {
                    call("【I】清除缓存文件," + dirSource + ".txt");
                }
                Apktool.DeletFile(dirSource + ".txt");
            }
        }
示例#12
0
        /// <summary>
        /// 执行apk打包逻辑
        /// </summary>
        public static String apkPackage(String apkUnPackageDir, String signFileName, Cmd.Callback call)
        {
            // 重新打包apk,并签名
            if (call != null)
            {
                call("【I】apk打包开始...");
            }
            String result = Apktool.package(apkUnPackageDir, call);     // 使用apktool进行打包

            if (result.Contains("【E】"))
            {
                return(result);
            }

            if (call != null)
            {
                call("【I】apk未签名文件已生成!\r\n");
            }

            // 若有签名文件,则进行签名
            if (!signFileName.Equals(""))
            {
                if (call != null)
                {
                    call("【I】apk签名中...");
                }
                String apkName = apkUnPackageDir + "..apk";

                if (signFileName.EndsWith(".keystore"))
                {
                    String keysotreName = Form1.SinPath() + "\\" + signFileName;

                    String[] I        = getKestoreInfo(signFileName); // 获取对应的签名信息
                    String   alias    = I[0];
                    String   password = I[1];

                    result = Apktool.SignKeyStore(apkName, keysotreName, alias, password, call);
                }
                else
                {
                    String pem = Form1.SinPath() + "\\" + signFileName + ".x509.pem";
                    String pk8 = Form1.SinPath() + "\\" + signFileName + ".pk8";
                    String psw = "letang123";
                    result = Apktool.Sign(apkName, pem, pk8, psw, call);
                }
                if (result.Contains("【E】"))
                {
                    return(result);
                }

                if (call != null)
                {
                    call("【I】apk签名、对齐 完成!\r\n");
                }

                // 删除打包生成的未签名文件
                if (File.Exists(apkName))
                {
                    File.Delete(apkName);
                }
            }

            if (call != null)
            {
                call("【I】apk打包结束!\r\n");
            }

            return("");
        }
示例#13
0
 /// <summary>
 /// 执行apk解包文件混合逻辑
 /// </summary>
 private void Combine_Click(object sender, EventArgs e)
 {
     Apktool.clearDirInfo();
     Cmd.ThreadRun(Combine_Logic, this, Combine, "执行中...");
 }