如何通过编程方式卸载Python开发的MSIX应用并捕获卸载事件?
问题1:捕获MSIX卸载事件并运行自定义代码的可行性
MSIX原生设计追求无残留干净卸载,官方并未提供onuninstall类的卸载前回调接口,不存在100%兼容稳定的实现方案。目前仅有的变通方案均存在明显局限性:
- 可在应用首次运行时注册WMI事件监听,监测系统AppX安装卸载相关的系统日志事件触发自定义逻辑,但如果用户卸载前从未启动过应用、或者提前终止了应用的监听进程,逻辑就无法触发
- 若应用走微软应用商店分发,可接入商店内置的卸载反馈弹窗能力,无需自己实现回调逻辑
问题2:MSIX应用自卸载的实现方案
你之前调用msiexec的逻辑仅适用于MSI安装包,MSIX包的卸载完全不依赖msiexec,需要使用系统提供的AppX卸载接口,具体实现步骤如下:
步骤1:获取当前MSIX应用的唯一标识
MSIX应用运行时,系统会自动给进程注入PACKAGE_FULL_NAME环境变量,直接读取该变量即可拿到当前包的完整标识,无需调用复杂的WinRT或者.NET API。
如果需要.NET实现的参考代码如下:
using Windows.ApplicationModel; // 直接获取当前包的FullName string packageFullName = Package.Current.Id.FullName;
Python实现更简单,直接读环境变量即可:
import os package_full_name = os.environ.get("PACKAGE_FULL_NAME")
注意:如果读取返回空值,说明当前进程不是运行在MSIX沙箱环境中,可以走原来的MSI卸载逻辑。
步骤2:执行卸载命令
MSIX的标准卸载命令是PowerShell的Remove-AppxPackage指令,直接传入上一步拿到的Package Full Name即可触发卸载:
C#参考代码:
using System.Diagnostics; public void TriggerUninstall(string packageFullName) { var processInfo = new ProcessStartInfo() { FileName = "powershell.exe", Arguments = $"-Command \"Remove-AppxPackage -Package {packageFullName}\"", UseShellExecute = true, // 如果是全设备部署的MSIX,需要加管理员权限,普通用户安装的包不需要 Verb = "runas" }; Process.Start(processInfo); }
对应Python代码参考:
import subprocess import os package_full_name = os.environ.get("PACKAGE_FULL_NAME") if package_full_name: # MSIX环境卸载逻辑 subprocess.run( ["powershell.exe", "-Command", f"Remove-AppxPackage -Package {package_full_name}"], shell=True, # 需要管理员权限的话加参数capture_output=True, check=True, creationflags=subprocess.CREATE_NO_WINDOW, verb="runas" ) else: # 原来的MSI卸载逻辑 myguid = "你的MSI产品GUID" subprocess.call(f'msiexec.exe /x {{{myguid}}}', shell=True)
注意:触发卸载后当前应用进程会被系统强制终止,所以要确保用户提交卸载原因的逻辑已经执行完成再调用卸载指令。
内容的提问来源于stack exchange,提问作者gcdev
相关产品推荐
相关产品推荐

