上一篇分享了一個QuickWIX,用來對比兩個工程先後的差別,可是這樣仍是很繁瑣,並且昨天發現有Bug,目錄對比有問題。此次改變作法,徹底讓程序自動去更新WXS文件,而後再用CCNet去自動編譯,這樣的話,工程師更新文件,不再用我去編譯,發佈了。html
思路:在原來的基礎上,傳入工程路徑和目標文件夾,用模板的方式,更新變更的部分生成新的WXS文件覆蓋原來的文件,一開始我思路搞錯了,想在比較的基礎上去更新變更的部分,好比一個文件刪除了,就把這個File移除掉,同理對於組件和目錄,可是這樣比較費事,容易出Bug。ui
工程目錄,在原來的基礎上沒有增長對象。多了一個Templet文件,用於放模板文件。spa
界面:code
若是改爲控制檯程序,就三句: xml
static void Main(string[] args) { if (args.Length < 2) return; Console.WriteLine(args[0]); Console.WriteLine(args[1]); var wiXml = new GenerateWiXml(args[0], "$(var.Dev)", args[1]); wiXml.Generate(); wiXml.WixComparator.AfterWixProj.SaveAsLast(); Console.WriteLine("替換完成"); }
先建立GenrateWiXml對象,調用Generate方法來根據目錄來生成WIX元素。每一個元素都有ToWixString方法。 主要是SaveAsLast方法,更換了兩個WXS文件。Product.wxs和DevComponents.wxs。前者找Feature 和 Directory 標籤,後者分兩種狀況,根目錄和其餘目錄,由於我根目錄文件夾寫了些其餘的元素,不能所有替換Files,另外其餘的DirectoryRef 就直接添加了。htm
public void SaveAsLast() { #region DirAndCompDocument if (DirAndCompDocument == null) { DirAndCompDocument = XDocument.Load(GetWxsProductPath()); } var rawpath1 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"..\..\Templet\", WixConfig.WxsProductPath); var productTemp = XDocument.Load(rawpath1); // 組件 var comelement = WixFeature.NewXElement(); var feature = productTemp.Descendants() .First() .Elements() .First() .Elements() .FirstOrDefault(n => n.Name == WixConfig.Np + "Feature" && n.Attribute("Id").Value == "ProductFeature"); if (feature != null) { feature.Elements().Remove(); feature.Add(comelement.Elements()); } // 目錄 var direlement = WixDirectory.NewXElement(); var element = productTemp.Descendants() .First() .Elements() .First() .Elements() .FirstOrDefault(n => n.Name == WixConfig.Np + "Directory"); if (element != null) { var dir = element.Elements().First(); dir.Elements().Remove(); dir.Add(direlement.Elements()); } productTemp.Save(GetWxsProductPath()); #endregion #region files var rawpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"..\..\Templet\", WixConfig.WxsFilePath); var dirTemp = XDocument.Load(rawpath); var fragment = dirTemp.Descendants().First().Elements().First(); var installfolder = WixFragment.DirectoryRefs; //根目錄下面的dir 都要遞歸處理 要所有加到DirTemp中去 foreach (var wd in installfolder) { //最特別的一個 if (wd.Id == "INSTALLFOLDER") { //找到Install下面的comp 所有加進來 var firstcop = fragment.Elements().First().Elements().First(); foreach (var file in wd.Component.Files) { firstcop.Add(file.XElement); } } else { //所有添加 fragment.Add(wd.XElement); } } dirTemp.Save(GetWxsFilePath()); #endregion }
這個WXS模板,須要本身調整了。而每一個元素的XElement基本上是這樣生成的(WIXDirectoryRef):對象
if (_xElement == null) { XNamespace np = "http://schemas.microsoft.com/wix/2006/wi"; var str = ToWixString(); _xElement = XElement.Parse(str); _xElement.Name = np + "DirectoryRef"; // 確保後代的命名空間都對 var cops = _xElement.Elements(); foreach (var xe in cops) { xe.Name = np + "Component"; foreach (var x in xe.Elements()) { x.Name = np + "File"; } } }
調用XElement的Parse方法後,須要修改元素的命名空間,否則每一個元素都會出現一個xmlns=「」的標籤。blog
小結:將上面的工程改爲控制檯配合本身的WIX的SetUp工程,而後部署到CCNET就能夠自動打包了。如下是源碼,比較部分替換元素的代碼沒有刪除,先留着。但願對你有幫助。 遞歸