using Ionic.Zip; using Microsoft.Build.Evaluation; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml; namespace Publisher.Models { public class Project { public enum Platforms { NET, NET_CORE } public string Name { get; set; } public string Path { get; set; } public Platforms Platform { get; set; } public bool VersionAutoIncrement { get; set; } public bool ShowConsole { get; set; } public delegate void StatusUpdateHandler(object sender, StatusUpdateArgs e); public event StatusUpdateHandler OnUpdateStatus; public string Publish(string dotnetExe, string publishDir, string outputZipPassword) { if(this.Platform == Platforms.NET_CORE) { return this.PublishNetCore(dotnetExe, publishDir, outputZipPassword); } else { return null; } } private string PublishNetCore(string dotnetExe, string publishDir, string outputZipPassword) { string result = null; try { if (!string.IsNullOrEmpty(dotnetExe) && File.Exists(dotnetExe) && !string.IsNullOrEmpty(this.Path) && File.Exists(this.Path)) { string version = this.GetVersion(true, true); if(!Directory.Exists(publishDir)) { Directory.CreateDirectory(publishDir); } string outputDir = System.IO.Path.Combine(publishDir, this.Name); if(!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } if (this.Clean(outputDir)) { Process p = new Process(); p.OutputDataReceived += P_OutputDataReceived; p.ErrorDataReceived += P_ErrorDataReceived; p.StartInfo.FileName = dotnetExe; p.StartInfo.Arguments = @"publish " + this.Path + @" -c Release -o " + outputDir + " --runtime win-x64 --self-contained false"; if (!this.ShowConsole) { p.StartInfo.UseShellExecute = false; p.StartInfo.CreateNoWindow = true; } p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.Start(); p.BeginErrorReadLine(); p.BeginOutputReadLine(); p.WaitForExit(); result = this.Zip(outputDir, version, outputZipPassword); } } } catch (Exception ex) { if (OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message)); } } return result; } private string Zip(string directory, string version, string outputZipPassword) { string result = null; try { if(!string.IsNullOrEmpty(directory) && Directory.Exists(directory)) { if (!string.IsNullOrEmpty(this.Name)) { result = this.Name; } else { result = Guid.NewGuid().ToString().ToLower().Replace("-", "").Replace(" ", ""); } if (!string.IsNullOrEmpty(version)) { result = result + "_" + version; } else { result = result + "_" + DateTime.Now.ToString("yyyyMMddHHmmss"); } result = result + ".zip"; using (ZipFile archive = new ZipFile()) { if (!string.IsNullOrEmpty(outputZipPassword)) { archive.Password = outputZipPassword; } archive.ExtractProgress += Archive_ExtractProgress; archive.AddDirectory(directory); result = System.IO.Path.Combine(directory, result); archive.Save(result); } } else if (OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("Error", "Publish directory not found (" + (!string.IsNullOrEmpty(directory) ? directory : "") + ")")); } } catch (Exception ex) { if (OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message)); } } return result; } private void Archive_ExtractProgress(object sender, ExtractProgressEventArgs e) { if (OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("ZIP (" + e.EventType.ToString() + ")", e.CurrentEntry.FileName)); } } private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e) { if (OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("Error", e.Data)); } } private void P_OutputDataReceived(object sender, DataReceivedEventArgs e) { if(OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("Log", e.Data)); } } private bool Clean(string publishDir) { bool result = false; try { if (!string.IsNullOrEmpty(publishDir)) { if(Directory.Exists(publishDir)) { Directory.Delete(publishDir, true); Thread.Sleep(200); } Directory.CreateDirectory(publishDir); result = Directory.Exists(publishDir); } } catch (Exception ex) { if (OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message)); } } return result; } public string GetVersion(bool save = false, bool autoIncrement = false) { string result = null; try { if (!string.IsNullOrEmpty(this.Path) && File.Exists(this.Path)) { XmlDocument doc = new XmlDocument(); doc.Load(this.Path); XmlNodeList node = doc.SelectNodes("/Project/PropertyGroup/AssemblyVersion"); if(node != null && node.Count > 0) { result = node[0].InnerText; if(!string.IsNullOrEmpty(result) && this.VersionAutoIncrement) { Version ver = new Version(result); int major = ver.Major; int minor = ver.Minor; int build = ver.Build; int revision = ver.Revision; if (autoIncrement) { revision = revision + 1; if (revision >= 9) { revision = 0; build = build + 1; if (build >= 9) { build = 0; minor = minor + 1; if (minor >= 9) { minor = 0; major = major + 1; } } } } result = major + "." + minor + "." + build + "." + revision; node[0].InnerText = result; } if(save) { doc.Save(this.Path); } } } } catch (Exception ex) { if (OnUpdateStatus != null) { OnUpdateStatus(this, new StatusUpdateArgs("Error", ex.Message)); } } return result; } } }