使用WiX卸载时删除AppData\Roaming\my_app_folder目录的方法
卸载时删除AppData目录的最佳实践与实现方案
一、关于卸载删除用户数据的最佳实践
卸载时默认删除用户数据不是行业通用的最佳实践,原因如下:
- 用户可能希望保留配置文件、缓存数据或创建的内容,卸载后重新安装时可复用
- 强制删除可能导致用户数据丢失,引发负面体验
如果业务场景确实需要清理用户数据,建议:
- 在卸载界面添加可选删除的复选框,让用户自主选择是否清理
- 明确告知用户清理的内容(如配置、缓存等),避免误解
- 仅删除应用生成的专属目录,不要误删系统或其他应用的文件
二、现有配置问题分析
你的Wix模板中,util:RemoveFolderEx指向的是INSTALLPATH(程序安装目录),而非AppData\Roaming\my_app_folder,这是无法删除目标目录的核心原因。同时,当前配置未启用自定义Wix模板加载,修改后的模板无法生效。
三、修改方案
1. 启用Electron Forge的自定义Wix模板加载
修改你的forge配置,取消beforeCreate注释,确保加载自定义Wix模板:
const { resolve } = require("path"); const { readFileSync } = require("fs"); const { join } = require("path"); module.exports = { packagerConfig: { icon: "public/favicon.ico", protocols: [ { protocol: "po", name: "App Terminal", schemes: ["po"], }, ], ignore: (path) => { if (path === "") return false; const include = ["/.vite", "/package.json"]; const isIgnored = !include.some((i) => path.startsWith(i)) || path.includes(".bin"); return isIgnored; }, }, makers: [ { name: "@electron-forge/maker-wix", config: { language: 2057, manufacturer: "Test Ltd.", name: "App Terminal", shortName: "appTerminal", appIconPath: "public/favicon.ico", upgradeCode: "bb01f636-4476-43fd-83f6-668565131744", lightSwitches: ["-sval"], beforeCreate: async (msiCreator) => { const wixTemplate = readFileSync(join(__dirname, `/wixTemplate.xml`), "utf-8"); msiCreator.wixTemplate = wixTemplate; }, }, }, { name: "@electron-forge/maker-dmg", config: { mimeType: ["x-scheme-handler/po"], background: "./src/assets/images/homeBackgroundImg.png", format: "ULFO", additionalDMGOptions: { window: { size: { width: 642, height: 706, }, }, }, }, }, { name: "@electron-forge/maker-zip", platforms: ["darwin"], }, { name: "@electron-forge/maker-deb", config: { mimeType: ["x-scheme-handler/po"], }, }, { name: "@electron-forge/maker-rpm", config: { mimeType: ["x-scheme-handler/po"], }, }, ], plugins: [ { name: "@electron-forge/plugin-vite", config: { build: [ { entry: resolve(__dirname, "../src/electron/electron.ts"), config: resolve(__dirname, "./vite/vite.main.config.ts"), }, { entry: resolve(__dirname, "../src/electron/preload.ts"), config: resolve(__dirname, "./vite/vite.preload.config.ts"), }, ], renderer: [ { name: "app_terminal_window", config: resolve(__dirname, "./vite/vite.config.ts"), }, ], }, }, ], };
2. 修改Wix模板,添加AppData目录删除逻辑
步骤1:定义AppData目标文件夹属性
在<Product>标签内的<!-- Necessary registry search to find the install path... -->下方添加:
<!-- 定义AppData下的应用专属目录路径 --> <Property Id="APP_DATA_FOLDER" Value="[AppData]\my_app_folder" />
注:
[AppData]是Windows内置环境变量,指向当前用户的%AppData%\Roaming目录
步骤2:添加删除AppData目录的Component
在<DirectoryRef Id="APPLICATIONROOTDIRECTORY">的Component之后添加:
<!-- 卸载时删除AppData下的应用目录 --> <DirectoryRef Id="TARGETDIR"> <Component Id="RemoveAppDataFolder" Guid="生成一个新的GUID" Win64="{{Win64YesNo}}"> <!-- 注册表项作为Component的KeyPath(因为AppData目录不是MSI安装的) --> <RegistryValue Root="HKCU" Key="Software\{{Manufacturer}}\{{ShortName}}" Name="CleanupAppData" Type="integer" Value="1" KeyPath="yes" /> <!-- 卸载时删除指定目录 --> <util:RemoveFolderEx On="uninstall" Property="APP_DATA_FOLDER" /> </Component> </DirectoryRef>
提示:可通过在线工具生成新的GUID替换占位符
步骤3:将Component添加到Feature中
在<Feature Id="MainApplication">的<ComponentRef>列表中添加:
<ComponentRef Id="RemoveAppDataFolder" />
3. 处理文件夹占用问题
如果卸载时应用进程仍在运行,Wix无法删除被占用的目录,可添加以下处理:
- 在Wix模板中添加自定义动作,检测并关闭应用进程
- 或在卸载前提示用户关闭应用
示例:添加检测进程的自定义动作(需Wix Util Extension支持):
<Binary Id="CloseAppExe" SourceFile="path/to/close-app.exe" /> <CustomAction Id="CloseApp" BinaryKey="CloseAppExe" Execute="immediate" Return="check" /> <InstallExecuteSequence> <Custom Action="CloseApp" Before="RemoveFiles">Installed AND NOT UPGRADINGPRODUCTCODE</Custom> </InstallExecuteSequence>
注:
close-app.exe是自定义工具,用于检测并关闭你的应用进程,也可用VBScript或PowerShell替代
四、验证与测试
- 重新构建MSI安装包:
npm run make - 安装应用并生成用户数据到
AppData\Roaming\my_app_folder - 卸载应用,检查目标目录是否被删除
- 测试不同场景:应用运行时卸载、多用户环境下卸载等
内容的提问来源于stack exchange,提问作者Jitendra Kumar
相关产品推荐
相关产品推荐

