贴一段自动编译java,并混淆编译的代码
刚写的一个自动编译、混淆、打包jar的代码,做个记录
用到的NuGet:
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="DotNetZip" version="1.10.1" targetFramework="net45" /> <package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" /> </packages>
using Ionic.Zip; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiCloudModulePackage { class Program { static string tempPath; static ToolConfig toolConfig; static void Main(string[] args) { tempPath = Path.GetTempPath() + Guid.NewGuid().ToString("N") + "\\"; if (Directory.Exists(tempPath) == false) { Directory.CreateDirectory(tempPath); } toolConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<ToolConfig>( File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "projects.json") ); try { foreach (ProjectConfig project in toolConfig.projects) { //compile jar jarProject(project); } Console.Write("需要现在生成模块的zip文件吗?[y/n]:"); while(true) { var keyResult = Console.ReadKey(); if (keyResult.Key == ConsoleKey.Y) { Console.WriteLine("\r\n"); //make zip file from module folder foreach (var moduleFolder in toolConfig.modules) { makeZip(getPathFromConfig(moduleFolder)); Console.WriteLine("打包输出:" + moduleFolder + ".zip"); } break; } else if (keyResult.Key == ConsoleKey.N) { Process.GetCurrentProcess().Kill(); } } Console.WriteLine("打包完成! 按任意键退出"); } catch(Exception ex) { Console.WriteLine(ex.Message); } try { Directory.Delete(tempPath, true); } catch { } Console.ReadKey(); } static void makeZip(string folder) { string zipfilepath = Path.GetDirectoryName(folder) + "\\" + Path.GetFileName(folder) + ".zip"; if (File.Exists(zipfilepath)) File.Delete(zipfilepath); using (ZipFile zip = new ZipFile(zipfilepath)) { string root = Path.GetFileName(folder); zip.AddDirectoryByName(root); zip.AddDirectory(folder , root); zip.Save(); } } static void jarProject(ProjectConfig project) { Console.WriteLine("正在编译" + project.sourceFolder); string srcPath = getPathFromConfig(project.sourceFolder); //create temp folder string tempFolder = tempPath + Guid.NewGuid().ToString("N") + "\\"; string classTempFolder = tempFolder + Guid.NewGuid().ToString("N") + "\\"; string jarDstFolder = tempFolder + "jar\\"; string proguardFolder = tempFolder + "jar\\"; if (Directory.Exists(jarDstFolder) == false) { Directory.CreateDirectory(jarDstFolder); } if (Directory.Exists(classTempFolder) == false) { Directory.CreateDirectory(classTempFolder); } List<string> javaFiles = new List<string>(); getFiles(javaFiles, srcPath , "*.java"); //copy java files to temp folder string encoding = null; foreach( string javafile in javaFiles ) { if(encoding == null) { var encode = GetFileEncodeType(javafile); if(encode == System.Text.Encoding.UTF8) { encoding = "utf-8"; } else { encoding = "GBK"; } } File.Copy(javafile, tempFolder + Path.GetFileName(javafile) , true); } StringBuilder libJars = new StringBuilder(); StringBuilder proguardJars = new StringBuilder(); if (!string.IsNullOrEmpty(project.libPath)) { List<string> jarList = new List<string>(); Program.getFiles(jarList, Program.getPathFromConfig(project.libPath), "*.jar"); if (jarList.Count > 0) { libJars.Append(" -cp "); foreach (string jarfile in jarList) { libJars.Append('"'); libJars.Append(jarfile); libJars.Append('"'); libJars.Append(';'); proguardJars.Append(" -libraryjars "); proguardJars.Append('"'); proguardJars.Append(jarfile); proguardJars.Append('"'); } } } ProcessStartInfo proStartInfo = new ProcessStartInfo("javac"); // -source 1.6 -target 1.6 表示按照jdk1.6标准编译,默认是1.8,太高了,eclipse使用时会出错,因为eclipse项目里面设置的是1.6 proStartInfo.Arguments = $"-Xlint:unchecked -Xlint:deprecation -source 1.6 -target 1.6 -encoding {encoding} -bootclasspath {AppDomain.CurrentDomain.BaseDirectory}android.jar {libJars} -d {classTempFolder} {tempFolder}*.java"; proStartInfo.UseShellExecute = false; Process process = Process.Start(proStartInfo); process.WaitForExit(); if(true) { //build jar, jar file actually is zip file using (ZipFile zip = new ZipFile($"{jarDstFolder}result.jar")) { zip.AddDirectory(classTempFolder); var content = @"Manifest-Version: 1.0 Created-By: 1.8.0_40 (Oracle Corporation) "; byte[] bs = System.Text.Encoding.UTF8.GetBytes(content); zip.AddEntry("META-INF/MANIFEST.MF", bs); zip.Save(); } } else { ////这里是利用jar程序生成jar文件 //List<string> classFiles = new List<string>(); //getFiles(classFiles, tempFolder, "*.class"); //foreach (string classfile in classFiles) //{ // File.Copy(classfile, jarDstFolder + Path.GetFileName(classfile), true); //} //proStartInfo = new ProcessStartInfo("jar"); //proStartInfo.Arguments = $"cvf {jarDstFolder}result.jar {jarDstFolder}*.class"; //proStartInfo.UseShellExecute = false; //process = Process.Start(proStartInfo); //process.WaitForExit(); } if(!string.IsNullOrEmpty(project.proguardConfigFile)) { Console.WriteLine("正在混淆代码..."); process = Process.Start(new ProcessStartInfo("java") { Arguments = $"-jar proguard.jar @{project.proguardConfigFile} -injars {proguardFolder}result.jar -outjars {proguardFolder}result2.jar -libraryjars android.jar {proguardJars}", UseShellExecute = false }); process.WaitForExit(); if (!File.Exists(string.Format("{0}result2.jar", proguardFolder))) { throw new Exception(project.sourceFolder + "代码混淆出错"); } File.Delete( $"{proguardFolder}result.jar"); File.Move($"{proguardFolder}result2.jar", $"{proguardFolder}result.jar"); } if (File.Exists($"{jarDstFolder}result.jar") == false) throw new Exception("编译"+ project.sourceFolder +"失败!"); //copy jar to destination foreach ( var dstpath in project.buildDestinations ) { string destination = getPathFromConfig(dstpath); File.Copy($"{jarDstFolder}result.jar", destination, true); Console.WriteLine($"Maked {destination}"); } } static System.Text.Encoding GetFileEncodeType(string filename) { using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { System.IO.BinaryReader br = new System.IO.BinaryReader(fs); Byte[] buffer = br.ReadBytes(2); if (buffer[0] >= 0xEF) { if (buffer[0] == 0xEF && buffer[1] == 0xBB) { return System.Text.Encoding.UTF8; } else if (buffer[0] == 0xFE && buffer[1] == 0xFF) { return System.Text.Encoding.BigEndianUnicode; } else if (buffer[0] == 0xFF && buffer[1] == 0xFE) { return System.Text.Encoding.Unicode; } else { return System.Text.Encoding.Default; } } else { return System.Text.Encoding.Default; } } } static string getPathFromConfig(string path) { if (path[1] == ':') return path.Replace("/", "\\"); else { return AppDomain.CurrentDomain.BaseDirectory + path.Replace("/", "\\"); } } static void getFiles(List<string> result, string folder , string pattern) { var files = Directory.GetFiles(folder, pattern); result.AddRange(files); var dirs = Directory.GetDirectories(folder); foreach( var dir in dirs ) { getFiles(result, dir , pattern); } } } }