如何在WiX安装程序中删除.exe.config中的Mex端点?
我太懂你卡了两天的崩溃感了——你遇到的核心问题其实是WiX的XML操作执行时机不对,再加上XPath定位的小细节没踩对。先给你拆解清楚根因,再给你能直接用的解决方案:
问题根源分析
你提到日志显示ExecXmlConfig在文件复制前执行,这就是关键!默认情况下,WiX的util:XmlFile和util:XmlConfig会在InstallInitialize阶段运行,但你的.exe.config文件是在InstallFiles阶段才被复制到目标目录的。这时候XML操作去操作一个还未到位的文件,自然找不到要删除的Mex节点,只会返回值1(没报错但没做任何实际操作)。
另外,你之前用地址定位Mex节点的方式不够可靠——生产环境地址大概率和开发环境不一样,不如用Mex端点独有的contract="IMetadataExchange"来定位,不管地址怎么变都能精准命中。
解决方案步骤
1. 强制XML操作在文件复制后执行
通过Schedule="afterInstallFiles"(针对util:XmlFile)或者After="InstallFiles"(针对util:XmlConfig)属性,把操作推迟到InstallFiles阶段之后,确保目标.exe.config已经存在于安装目录。
2. 用更可靠的XPath定位Mex端点
放弃依赖硬编码地址,改用Mex端点的标志性属性筛选:
//configuration/system.serviceModel/services/service[@behaviorConfiguration='MainServiceBehaviour']/endpoint[@contract='IMetadataExchange']
正确的WiX代码示例
方式一:使用util:XmlFile
<Component Id="RemoveMexEndpoint" Directory="INSTALLFOLDER" Guid="*" KeyPath="yes"> <!-- 明确指定操作在文件复制完成后执行 --> <util:XmlFile Id="DeleteMexEndpoint" Action="deleteValue" ElementPath="//configuration/system.serviceModel/services/service[@behaviorConfiguration='MainServiceBehaviour']" Name="endpoint" SelectionLanguage="XPath" File="[#MyExeConfig]" PreserveModifiedDate="yes" Schedule="afterInstallFiles" Value="//endpoint[@contract='IMetadataExchange']" /> </Component>
方式二:使用util:XmlConfig
<Component Id="RemoveMexEndpoint" Directory="INSTALLFOLDER" Guid="*" KeyPath="yes"> <util:XmlConfig Id="RemoveMexEndpoint" On="install" Action="delete" File="[#MyExeConfig]" Node="element" <!-- 验证Mex节点存在的路径 --> VerifyPath="//configuration/system.serviceModel/services/service[@behaviorConfiguration='MainServiceBehaviour']/endpoint[@contract='IMetadataExchange']" <!-- 父节点路径 --> ElementPath="//configuration/system.serviceModel/services/service[@behaviorConfiguration='MainServiceBehaviour']" PreserveModifiedDate="yes" <!-- 指定在InstallFiles阶段之后执行 --> After="InstallFiles" /> </Component>
验证方法
重新生成安装包后,开启详细日志执行安装:
msiexec /i YourInstaller.msi /l*v install.log
在日志里搜索DeleteMexEndpoint或者RemoveMexEndpoint,确认操作是在InstallFiles之后执行,并且能看到类似Successfully deleted element的成功日志。
内容的提问来源于stack exchange,提问作者Chris Watts

