WixSharp无法识别ProgramData等环境变量,卸载删除文件夹失效
WixSharp自定义动作路径不生效问题解决方案
问题根因
- 错误1:
CommonAppDataFolder是Wix/MSI的内置属性,不是系统可识别的路径字符串,直接传入DirectoryInfo会被识别为当前执行目录的子文件夹,自然无法匹配实际路径。 - 错误2:路径拼接语法错误,
Path.Combine的第二个参数如果以反斜杠开头,会直接丢弃前面的基础路径,返回第二个参数的绝对路径。你本地直接运行时当前驱动器默认为C盘,所以刚好生效,在MSI自定义动作的执行上下文下工作目录变化就会失效。 - 错误3:Wix自定义动作默认运行在32位执行上下文,64位安装包场景下调用
Environment.SpecialFolder.ProgramFiles或展开%ProgramFiles%环境变量时,会被系统自动重定向到C:\Program Files (x86),和实际文件存放的64位C:\Program Files路径不匹配。
修复代码
场景1:删除CommonAppData下的目标文件夹
直接从SetupEventArgs的Session中读取MSI内置属性的实际值即可:
public void OnAfterInstall(SetupEventArgs e) { if (e.IsUninstalling) { string commonAppDataPath = e.Session["CommonAppDataFolder"]; string targetFolder = Path.Combine(commonAppDataPath, "myFolder"); if (Directory.Exists(targetFolder)) { Directory.Delete(targetFolder, true); } } }
场景2:读取Program Files下的清单文件
首先修正路径拼接错误,再给WixSharp打包逻辑加64位执行标记:
- 业务逻辑代码修正:
var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); // 路径拼接时第二个参数不要加开头的反斜杠 var manifestFile = Path.Combine(programFiles, @"My Company\myFile.man"); FileInfo fInfo = new FileInfo(manifestFile); if (fInfo.Exists) { FileSecurity security = fInfo.GetAccessControl(); security.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), FileSystemRights.ReadAndExecute, AccessControlType.Allow)); fInfo.SetAccessControl(security); } // 路径加引号避免空格导致参数识别错误 var CMDCommand = $@"/C wevtutil im ""{manifestFile}"""; Process.Start("CMD.exe", CMDCommand);
- 打包逻辑新增64位配置:
var project = new Project("你的产品名", new Dir(@"%ProgramFiles%\My Company", new File("myFile.man")), new ManagedAction(CustomActions.OnAfterInstall, Return.check, When.After, Step.InstallFinalize, Condition.Always) { // 禁用32位文件系统重定向 UsesWow64FSRedirection = false } ); // 标记安装包为64位 project.Platform = Platform.x64;
内容的提问来源于stack exchange,提问作者R.P
相关产品推荐
相关产品推荐

