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


        上一篇分享了一個QuickWIX,用來對比兩個工程前后的差異,但是這樣還是很繁瑣,而且昨天發現有Bug,目錄對比有問題。這次改變做法,完全讓程序自動去更新WXS文件,然后再用CCNet去自動編譯,這樣的話,工程師更新文件,再也不用我去編譯,發布了。

         思路:在原來的基礎上,傳入工程路徑和目標文件夾,用模板的方式,更新變動的部分生成新的WXS文件覆蓋原來的文件,一開始我思路搞錯了,想在比較的基礎上去更新變動的部分,比如一個文件刪除了,就把這個File移除掉,同理對於組件和目錄,但是這樣比較費事,容易出Bug。

         工程目錄,在原來的基礎上沒有增加對象。多了一個Templet文件,用於放模板文件。

         

     界面:

     

          如果改成控制台程序,就三句:     

 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 就直接添加了。

 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=“”的標簽。

     小結:將上面的工程改成控制台配合自己的WIX的SetUp工程,然后部署到CCNET就可以自動打包了。以下是源碼,比較部分替換元素的代碼沒有刪除,先留着。希望對你有幫助。 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM