如何以编程方式卸载我的 MSIX python 应用程序?
Posted
技术标签:
【中文标题】如何以编程方式卸载我的 MSIX python 应用程序?【英文标题】:How can I programmatically uninstall my MSIX python app? 【发布时间】:2021-10-25 21:18:54 【问题描述】:我刚刚在 python 3 中编写了我的第一个 MSIX 应用程序。我使用 pyinstaller 生成一个 EXE。然后我使用WiX Toolset 生成一个MSI。然后我使用 MSIX Packaging Tool 创建 MSIX。从代码到 MSIX 可能有一种更简单的方法,但这就是我目前所做的工作。
理想情况下,我想捕获一个 onuninstall 事件并抛出一个 GUI 提示,询问用户为什么要卸载。我可以在 MSI 中做到这一点。但是,我的理解是MSIX offers no onuninstall event。如果您有不同的认识,请告诉我!
由于我显然无法捕捉 MSIX 卸载事件,我的下一个偏好是为用户提供一种从托盘图标卸载应用程序的方法。用户从我的应用程序图标中选择一个卸载托盘菜单按钮,该按钮会弹出一个窗口,然后应用程序会在其中询问他们为什么要卸载。他们输入答案,然后单击提交按钮。然后,该应用程序应完全自行卸载。这在 MSI 中也很有效。但是,我无法让它在 MSIX 中工作。
以下是安装了 MSI 的 python 中的工作原理:
subprocess.call('msiexec.exe /x ' + myguid + '', shell=True)
但是,从 MSI 构建的 MSIX 在该行运行时抛出此弹出错误消息,并且从未实际卸载应用程序:
This action is only valid for products that are currently installed.
我尝试使用硬编码的 WXS 文件的 <Product>
条目中的 GUID,只是为了看看它是否可以工作。那一个适用于卸载 MSI,但不适用于 MSIX。我还尝试动态获取 GUID,但这对 MSI 或 MSIX 都不起作用,两者都会产生与上述相同的错误。以下是我动态获取 GUID 的方法:
from System.Runtime.InteropServices import Marshal
from System import Reflection
myguid = str(Marshal.GetTypeLibGuidForAssembly(
Reflection.Assembly.GetExecutingAssembly()
)).upper()
在运行 MSI 时(我的日志记录比在 MSIX 中好得多),似乎GetExecutingAssembly()
获得了一个带有Python.Runtime
的FullName
的程序集,这当然是我不想要的卸载。 GetCallingAssembly()
产生相同的结果。 GetEntryAssembly()
产生一个 null
值。
我通过AppDomain.CurrentDomain.GetAssemblies()
循环查看列出的内容,但我的应用未列出,尽管我看到了它使用的许多库。
那么,对于如何让应用程序以编程方式卸载有什么想法吗?如果这是问题所在,也许是关于如何获得 MSIX 应用程序的正确 GUID 的建议? DotNet 代码应该没问题。我大概能弄清楚如何将它翻译成 python。
或者更好的是,知道如何捕获 MSIX 卸载事件并运行一些自定义代码吗?
提前致谢!
【问题讨论】:
【参考方案1】:据我所知,目前无法捕获卸载事件。我不建议实施您建议的方法(托盘图标),但要提出您的问题,您可以使用 MSIX PowerShell commandlets 以编程方式安装和卸载 MSIX 包。
另外,我注意到你真的在折磨自己来创建 MSIX 包。
MSIX 打包工具由 Microsoft 为无法访问源代码的 IT 专业人员创建。开发人员可以使用 Windows 应用程序打包项目项目模板(如果他们使用 Visual Studio)或其他第三方工具,例如 Advanced Installer 或 Wix(据我所知,有一个 Wix extension that can be used to build MSIX packages)。
这里有一个关于如何从头开始创建 MSIX 的快速教程,使用高级安装程序更容易: https://www.advancedinstaller.com/create-msi-python-executable.html
免责声明:我在团队建设 Advanced Installer 工作。
【讨论】:
谢谢!我之前尝试过 WiX MSIX 进程,但无法让它为我工作。如果我没记错的话,WiX MSIX 也只适用于 Visual Studio 项目,而我根本没有使用 Visual Studio。我怀疑 Advanced Installer 会让事情变得更容易,但我试图在不花费任何额外 $$ 的情况下完成此操作。不过我会检查命令行开关!【参考方案2】:我使用了 Bogdan 的 Powershell 建议,并提出了以下代码,似乎运行良好:
import subprocess
powershellLocation = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
try:
# Use the name of the app (which I found manually using Get-AppPackage)
# to get the full name of the app, which seems to have some random numbers
# on the end of it.
powershell_tuple = subprocess.Popen([
powershellLocation,
"Get-AppPackage",
"-name",
'"' + myAppPackageName + '"'
],shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()
appStrings = powershell_tuple[0].decode('utf-8').strip()
except Exception as e:
pass
for appStr in appStrings.splitlines():
# Find the full name of the app
if appStr.startswith('PackageFullName'):
colonIndex = appStr.index(':') + 1
fullName = appStr[colonIndex:].strip()
if fullName:
# The MSIX package was found, and I now have its full name
subprocess.call(powershellLocation + ' Remove-AppPackage -Package "' + fullName + '"', shell=True)
【讨论】:
以上是关于如何以编程方式卸载我的 MSIX python 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章