小白入门笔记——APKTool自动化打包的实现

在做一个项目,需要实现一个APK自动打包的功能。

系统背景:移动教学平台,使学生熟练使用apk及电子商务网站。系统中包含不同班级,教师可以为不同班级分配不同的实验,每个实验都有对应的APK。每次分配实验时要进行实验的部署,主要完成数据库、文件系统及IIS的自动化部署。因此整个系统中,不同班级对应的IIS站点是不同的,不同班级的APK所要连接的后台服务器也是不同的,故需要对apk进行自动化反编译,修改相应字段后,重新打包。

反编译打包工具使用的是APKTool,流程图如下:

 

废话不说,上代码:

main()  代码:

        string strFilePath = ConfigurationSettings.AppSettings["APKTool"];    //G:\开发\移动平台\Tools\ApkTool
        string strBatPath = strFilePath + "/apk.bat";   //bat文件存储目录
        string apkpath = Server.MapPath("../FileUpload/ExpApk");
        string[] apknames = Directory.GetFiles(apkpath);
        string str = classinfo.cid.ToString() + ".apk";
        string apkname = "ChenniaoB2C"+"_"+str;
        string[] name = { "ChenniaoB2C", "ChenniaoMap", "TravelhubMobile" };
        bool tag = true;     //标记是否存在同名文件存在
        foreach (string item in apknames)
        {
            string [] s=item.Split('\\');
            int index=s.Count();
            if (apkname == s[index-1])
            {
                tag = false;
                break;
            }
        }
        if (tag)
        {
            #region 自动打包apk
            CreateBAT(name[0], 0, str);     //0:生成反编译bat
            ExecuteBAT(strBatPath);         //反编译apk
            System.Threading.Thread.Sleep(13000);
            UpdateConnectStr();             //修改链接字符串
            CreateBAT(name[0], 1, str);     //1:生成打包bat
            ExecuteBAT(strBatPath);         //打包apk
            System.Threading.Thread.Sleep(30000);
            CreateBAT(name[0], 2, str);     //3:拷贝打包好的apk至FileUpload\ExpApk,并删除遗留文件
            ExecuteBAT(strBatPath);
            System.Threading.Thread.Sleep(5000);
            #endregion
            
        }

生成bat文件函数:

  protected void CreateBAT(string apkname, int tag, string str)
    {
        string strFilePath = ConfigurationSettings.AppSettings["APKTool"];
        string strBatPath = strFilePath + "/apk.bat";//bat文件存储目录
        string strAPKPath = ConfigurationSettings.AppSettings["Client"];    //客户端目录
        string apkpath = Server.MapPath("../FileUpload/ExpApk");
        if (true)
        {
            string[] disknames = strFilePath.Split(':');
            string diskname = "c";
            if (disknames != null)
            {
                diskname = disknames[0];                    //获取盘符
            }
            StringBuilder sBuilder = new StringBuilder();
            //sBuilder.AppendLine(string.Format("@echo off"));
            if (tag == 0)
            {
                sBuilder.AppendLine(string.Format("{0}", diskname + ":"));
                sBuilder.AppendLine(string.Format("cd {0}", strFilePath));
                sBuilder.AppendLine(string.Format("copy {0} 123.apk", strAPKPath + "\\" + apkname + ".apk"));  //从客户端拷贝文件至APKTool
                sBuilder.AppendLine(string.Format("decompile.vbs"));
                //sBuilder.AppendLine(string.Format("pause"));
            }
            else if (tag == 1)
            {
                sBuilder.AppendLine(string.Format("{0}", diskname + ":"));
                sBuilder.AppendLine(string.Format("cd {0}", strFilePath));
                sBuilder.AppendLine(string.Format("build.vbs"));
            }
            else if (tag == 2)
            {
                sBuilder.AppendLine(string.Format("{0}", diskname + ":"));
                sBuilder.AppendLine(string.Format("cd {0}", strFilePath + "\\APK\\build"));
                sBuilder.AppendLine(string.Format("copy 已编译(已签名).apk {0}", apkpath + "\\" + apkname + "_" + str));
                sBuilder.AppendLine(string.Format("cd ../.."));
                sBuilder.AppendLine(string.Format("del 123.apk"));
                sBuilder.AppendLine(string.Format("delete.vbs"));
            }
            Stream st = new FileStream(strBatPath.Replace("\\", "/"), FileMode.Create, FileAccess.Write);

            using (StreamWriter sw = new StreamWriter(st, Encoding.GetEncoding("gb2312")))
            {
                sw.Write(sBuilder.ToString());
                sw.Close();
                st.Dispose();
                st.Close();
            }
        }
    }
执行bat文件函数:

 protected string ExecuteBAT(string strBatPath) //文件路径;要执行bat文件的进程,返回执行结果
    {
        string mess = "";
        Process pro = new Process();
        try
        {
            pro.StartInfo.UseShellExecute = true;
            pro.StartInfo.FileName = strBatPath.Replace("\\","/");  //strBatPath是bat文件路径
            pro.StartInfo.CreateNoWindow = true;
            if (pro.Start())
            {
                mess ="执行bat成功.";
            }
            else
            {
                mess ="生成失败.";
            }
        }
        catch (Exception ex)
        {
            mess = ex.Message;
        }
        finally
        {
            pro.Close();
        }
        return mess;
    }
对反编译好的apk文件进行修改,修改strings.xml中的连接字符串:

protected void UpdateConnectStr()
    {
        string FilePath= ConfigurationSettings.AppSettings["APKTool"]+"\\APK\\res\\values\\strings.xml";
        string oldValue="www.chenniao.com";
        string newValue=ConfigurationSettings.AppSettings["apkService"];
        //string newValue = oldValue;          //测试
        ReplaceText(FilePath,oldValue,newValue);
    }
    public static void ReplaceText(string path, string oldValue, string newValue)
    {
        string text = string.Empty;
        using (StreamReader reader = new StreamReader(path, Encoding.UTF8))//注意编码形式,xml为UTF8
        {
            text = reader.ReadToEnd();
            reader.Close();
        }
        using (StreamWriter writer = new StreamWriter(path,false,Encoding.UTF8))
        {
            writer.Write(text.Replace(oldValue, newValue));
            writer.Close();
        }
    }
bat批处理中使用到三个vbs文件,这三个文件用于模拟键盘输入,在目录APKTool下。

decompile.vbs:

set s = WScript.CreateObject("WScript.Shell") 

app=s.Run ("APKTool.cmd")

WScript.Sleep 1000 

s.AppActivate app

s.SendKeys "1"

s.SendKeys "{ENTER}"

WScript.Sleep 10000 

s.SendKeys "{ENTER}"

s.SendKeys "0"

s.SendKeys "{ENTER}"

build.vbs:

set s = WScript.CreateObject("WScript.Shell") 

app=s.Run ("APKTool.cmd")

WScript.Sleep 1000 

s.AppActivate app

s.SendKeys "3"

s.SendKeys "{ENTER}"

WScript.Sleep 25000 

s.SendKeys "{ENTER}"

WScript.Sleep 5000 

s.SendKeys "0"

s.SendKeys "{ENTER}"
delete.vbs:

set s = WScript.CreateObject("WScript.Shell") 

app=s.Run ("APKTool.cmd")

WScript.Sleep 1000 

s.AppActivate app

s.SendKeys "7"

s.SendKeys "{ENTER}"

WScript.Sleep 2000 

s.SendKeys "{ENTER}"

WScript.Sleep 2000 

s.SendKeys "0"

s.SendKeys "{ENTER}"

模块完成中遇到的问题及解决:

Dos 命令不熟练,在文件的路径上反斜杠( \ )与斜杠 (/) 混淆,在 dos 命令中使用反斜杠,在 C# 路径中使用斜杠,同时还要注意转义字符的使用;
C# 文件流操作中,要注意编码格式,创建 bat 文件时,由于路径中包含中文字,所以要使用 gb2312 编码;而在修改 strings.xml 时,注意到代码头部标出使用 UTF8 编码,故文件读写时需要使用 UTF8 编码;
v bs 模拟键盘时需要让程序延迟发生,否则会产生错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值