Wix 安装部署教程(十二) -- 自动更新WXS文件
2015-08-06 22:08 stoneniqiu 阅读(2660) 评论(2) 编辑 收藏 举报上一篇分享了一个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就可以自动打包了。以下是源码,比较部分替换元素的代码没有删除,先留着。希望对你有帮助。
书山有路群:452450927
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义