Wix 安裝部署教程(十二) -- 自動更新WXS文件

        上一篇分享了一個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就能夠自動打包了。如下是源碼,比較部分替換元素的代碼沒有刪除,先留着。但願對你有幫助。 遞歸

 http://pan.baidu.com/s/1hUtkielement

相關文章
相關標籤/搜索