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

相关文章
相关标签/搜索