如何以编程方式卸载我的MSIX python应用程序?

2024-09-29 07:29:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚刚用Python3编写了我的第一个MSIX应用程序。我使用pyinstaller生成一个EXE。然后我使用WiX Toolset生成一个MSI。然后我使用MSIX Packaging Tool创建MSIX。从代码到MSIX可能有一种更简单的方法,但这就是我迄今为止所做的工作

理想情况下,我希望捕获一个onuninstall事件并抛出一个GUI提示,询问用户为什么要卸载。我可以在微星上做这件事。然而,我的理解是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()获得了一个FullNamePython.Runtime的程序集,这肯定是我不想卸载的GetCallingAssembly()产生相同的结果GetEntryAssembly()生成一个null

我在AppDomain.CurrentDomain.GetAssemblies()中循环查看列出了什么,而我的应用程序没有列出,尽管我看到了它使用的许多库

那么,关于如何以编程方式卸载应用程序,有什么想法吗?如果这是问题的话,也许可以给我一个如何为MSIX应用程序获取正确GUID的建议?DotNet代码应该可以。我可能知道如何将其转换为python

或者更好的是,知道如何捕获MSIX卸载事件并运行一些自定义代码吗

提前谢谢


Tags: 方法代码用户from应用程序错误事件动态
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 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

免责声明:我负责团队建设高级安装程序

相关问题 更多 >