Wix Toolset v5中Module下使用FileSearch失效问题求助
解决Wix Toolset v5 Module中FileSearch编译错误
问题场景
在Wix Toolset v5的Module中使用以下代码检测文件是否存在:
<Property Id="FILEEXISTS" > <DirectorySearch Id="CheckFileDir" Path="[SourceDir]" Depth="0" > <FileSearch Id="CheckFile" Name="Test.txt" /> </DirectorySearch> </Property>
编译时触发错误:
wix.exe : error WIX0001: System.InvalidOperationException: The value '' is not a legal identifier and therefore cannot be modularized. at WixToolset.Core.WindowsInstaller.Bind.ModularizeCommand.ModularizedRowFieldValue(Row row, Field field) in D:\a\wix\wix\src\wix\WixToolset.Core.WindowsInstaller\Bind\ModularizeCommand.cs:line 130 at WixToolset.Core.WindowsInstaller.Bind.ModularizeCommand.ModularizeTable(Table table) in D:\a\wix\wix\src\wix\WixToolset.Core.WindowsInstaller\Bind\ModularizeCommand.cs:line 68 at WixToolset.Core.WindowsInstaller.Bind.ModularizeCommand.Execute() in D:\a\wix\wix\src\wix\WixToolset.Core.WindowsInstaller\Bind\ModularizeCommand.cs:line 41 at WixToolset.Core.WindowsInstaller.Bind.BindDatabaseCommand.Execute() in D:\a\wix\wix\src\wix\WixToolset.Core.WindowsInstaller\Bind\BindDatabaseCommand.cs:line 399 at WixToolset.Core.WindowsInstaller.MsmBackend.Bind(IBindContext context) in D:\a\wix\wix\src\wix\WixToolset.Core.WindowsInstaller\MsmBackend.cs:line 27 at WixToolset.Core.Binder.BackendBind(IBindContext context) in D:\a\wix\wix\src\wix\WixToolset.Core\Binder.cs:line 74 at WixToolset.Core.Binder.Bind(IBindContext context) in D:\a\wix\wix\src\wix\WixToolset.Core\Binder.cs:line 40 at WixToolset.Core.CommandLine.BuildCommand.BindPhase(Intermediate output, IReadOnlyCollection`1 localizations, IReadOnlyCollection`1 filterCultures, String cabCachePath, Int32 cabbingThreadCount, IReadOnlyCollection`1 bindPaths, Dictionary`2 bindVariables, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken) in D:\a\wix\wix\src\wix\WixToolset.Core\CommandLine\BuildCommand.cs:line 324 at WixToolset.Core.CommandLine.BuildCommand.ExecuteAsync(CancellationToken cancellationToken) in D:\a\wix\wix\src\wix\WixToolset.Core\CommandLine\BuildCommand.cs:line 152 at WixToolset.Tools.Program.Run(IServiceProvider serviceProvider, IMessageListener listener, String[] args, CancellationToken cancellationToken) in D:\a\wix\wix\src\wix\wix\Program.cs:line 103 at WixToolset.Tools.Program.Main(String[] args) in D:\a\wix\wix\src\wix\wix\Program.cs:line 48
错误原因
Module编译为MSM时,要求所有目录相关的标识符必须是可模块化的合法值。[SourceDir]是安装时的运行时属性,在Module编译阶段无法被解析为有效的目录标识符,导致绑定过程中出现空值,触发非法标识符错误。
解决方案
方案1:使用Module自身的目录结构
在Module中定义目标目录,将DirectorySearch的Path指向该目录的属性,确保编译时能解析到合法的标识符:
<!-- 定义Module的根目录 --> <Directory Id="MODULETARGETDIR" Name="ModuleRoot"> <!-- 可添加子目录结构 --> </Directory> <Property Id="FILEEXISTS"> <DirectorySearch Id="CheckFileDir" Path="[MODULETARGETDIR]" Depth="0"> <FileSearch Id="CheckFile" Name="Test.txt" /> </DirectorySearch> </Property>
当Module被合并到主安装包时,MODULETARGETDIR会映射到主包中的目标目录,运行时即可检测该目录下的文件。
方案2:改用自定义动作检测文件
如果需要检测安装源目录([SourceDir])下的文件,可通过自定义动作在安装运行时执行检测,避免编译阶段的模块化问题:
- 编写C#自定义动作:
using Microsoft.Deployment.WindowsInstaller; public class CustomActions { [CustomAction] public static ActionResult CheckFileExists(Session session) { string sourceDir = session["SourceDir"]; string filePath = System.IO.Path.Combine(sourceDir, "Test.txt"); session["FILEEXISTS"] = System.IO.File.Exists(filePath) ? "1" : "0"; return ActionResult.Success; } }
- 在Module中引用自定义动作并设置执行时机:
<!-- 引用自定义动作DLL --> <Binary Id="CustomActionsDll" SourceFile="path/to/CustomActions.dll" /> <CustomAction Id="CA_CheckFileExists" BinaryKey="CustomActionsDll" DllEntry="CheckFileExists" Execute="immediate" /> <!-- 在安装序列中执行自定义动作 --> <InstallExecuteSequence> <Custom Action="CA_CheckFileExists" Before="LaunchConditions" /> </InstallExecuteSequence>
后续使用说明
无论采用哪种方案,FILEEXISTS属性都会在运行时被赋值(存在为路径或"1",不存在为空或"0"),可直接在Module的条件判断中使用,例如:
<Component Id="TestComponent" Guid="*"> <Condition>FILEEXISTS</Condition> <!-- 组件内容 --> </Component>
内容的提问来源于stack exchange,提问作者Prakash
相关产品推荐
相关产品推荐

