如何以编程方式更新始终运行并部署了msix的WinForms应用程序?

如何以编程方式更新始终运行并部署了msix的WinForms应用程序?,winforms,uwp,desktop-bridge,msix,appinstaller,Winforms,Uwp,Desktop Bridge,Msix,Appinstaller,我有一个配置为在启动时运行的应用程序。它没有UI,当用户登录时,它会进入系统托盘,整天做自己的事情 该应用程序应自动更新,用户甚至没有通知,我不想打扰用户。如何使用msix执行此操作 我对AppInstaller的自动更新有问题,因为应用程序总是在运行,而且有很多bug。这段代码在一定程度上起作用。它关闭应用程序,进行更新,但在更新后不会启动应用程序。我需要应用程序在更新后立即运行,无需用户干预。我该怎么做 var result = await Package.C

我有一个配置为在启动时运行的应用程序。它没有UI,当用户登录时,它会进入系统托盘,整天做自己的事情

该应用程序应自动更新,用户甚至没有通知,我不想打扰用户。如何使用msix执行此操作

我对AppInstaller的自动更新有问题,因为应用程序总是在运行,而且有很多bug。这段代码在一定程度上起作用。它关闭应用程序,进行更新,但在更新后不会启动应用程序。我需要应用程序在更新后立即运行,无需用户干预。我该怎么做

                var result = await Package.Current.CheckUpdateAvailabilityAsync();
            switch (result.Availability)
            {
                case PackageUpdateAvailability.Available:
                case PackageUpdateAvailability.Required:
                    PackageManager packagemanager = new PackageManager();
                    await packagemanager.UpdatePackageAsync(new Uri("path-to-file.msix"), null, DeploymentOptions.ForceApplicationShutdown);
                    break;
                case PackageUpdateAvailability.NoUpdates:
                    // Close AppInstaller.
                    MessageBox.Show("Non-updates");
                    break;
                case PackageUpdateAvailability.Unknown:
                default:
                    MessageBox.Show($"No update information associated with app");
                    break;
            }

解决方案在此页面中:

在开始更新之前调用RegisterApplicationRestart()

       private async Task UpdatePackage()
    {
        try
        {
            // Register the active instance of an application for restart in your Update method
            uint res = RelaunchHelper.RegisterApplicationRestart(null, RelaunchHelper.RestartFlags.NONE);

            PackageManager packagemanager = new PackageManager();
            await packagemanager.UpdatePackageAsync(new Uri($"path-to.msix"), null, DeploymentOptions.ForceApplicationShutdown);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error in update: " + ex.ToString());
        }
    }




    class RelaunchHelper
{
    #region Restart Manager Methods
    /// <summary>
    /// Registers the active instance of an application for restart.
    /// </summary>
    /// <param name="pwzCommandLine">
    /// A pointer to a Unicode string that specifies the command-line arguments for the application when it is restarted.
    /// The maximum size of the command line that you can specify is RESTART_MAX_CMD_LINE characters. Do not include the name of the executable
    /// in the command line; this function adds it for you.
    /// If this parameter is NULL or an empty string, the previously registered command line is removed. If the argument contains spaces,
    /// use quotes around the argument.
    /// </param>
    /// <param name="dwFlags">One of the options specified in RestartFlags</param>
    /// <returns>
    /// This function returns S_OK on success or one of the following error codes:
    /// E_FAIL for internal error.
    /// E_INVALIDARG if rhe specified command line is too long.
    /// </returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    internal static extern uint RegisterApplicationRestart(string pwzCommandLine, RestartFlags dwFlags);
    #endregion Restart Manager Methods

    #region Restart Manager Enums
    /// <summary>
    /// Flags for the RegisterApplicationRestart function
    /// </summary>
    [Flags]
    internal enum RestartFlags
    {
        /// <summary>None of the options below.</summary>
        NONE = 0,

        /// <summary>Do not restart the process if it terminates due to an unhandled exception.</summary>
        RESTART_NO_CRASH = 1,
        /// <summary>Do not restart the process if it terminates due to the application not responding.</summary>
        RESTART_NO_HANG = 2,
        /// <summary>Do not restart the process if it terminates due to the installation of an update.</summary>
        RESTART_NO_PATCH = 4,
        /// <summary>Do not restart the process if the computer is restarted as the result of an update.</summary>
        RESTART_NO_REBOOT = 8
    }
    #endregion Restart Manager Enums

}
private async Task UpdatePackage()
{
尝试
{
//在更新方法中注册要重新启动的应用程序的活动实例
uint res=RelaunchHelper.RegisterApplicationRestart(null,RelaunchHelper.RestartFlags.NONE);
PackageManager PackageManager=新的PackageManager();
等待packagemanager.UpdatePackageAsync(新Uri($“path to.msix”)、null、DeploymentOptions.ForceApplicationShutton;
}
捕获(例外情况除外)
{
Show(“更新时出错:+ex.ToString());
}
}
类重新启动帮助程序
{
#区域重新启动管理器方法
/// 
///注册应用程序的活动实例以重新启动。
/// 
/// 
///指向Unicode字符串的指针,该字符串指定应用程序重新启动时的命令行参数。
///您可以指定的命令行的最大大小是RESTART\u MAX\u CMD\u行字符。不要包括可执行文件的名称
///在命令行中;此函数为您添加它。
///如果此参数为NULL或空字符串,则删除以前注册的命令行。如果参数包含空格,
///在参数周围使用引号。
/// 
///RestartFlags中指定的选项之一
/// 
///此函数在成功或出现以下错误代码之一时返回S_OK:
///E_因内部错误而失败。
///如果指定的命令行太长,则E_INVALIDARG。
/// 
[DllImport(“kernel32.dll”,CharSet=CharSet.Unicode)]
内部静态外部单元寄存器应用程序重启(字符串pwzCommandLine,RestartFlags-dwFlags);
#endregion重新启动管理器方法
#区域重新启动管理器枚举
/// 
///RegisterApplicationRestart函数的标志
/// 
[旗帜]
内部枚举重新启动标志
{
///下面没有选项。
无=0,
///如果进程因未处理的异常而终止,请不要重新启动进程。
重新启动\u无\u崩溃=1,
///如果进程因应用程序没有响应而终止,请不要重新启动进程。
重新启动\u NO\u HANG=2,
///如果进程因安装更新而终止,请不要重新启动进程。
重新启动\u无\u补丁=4,
///如果由于更新而重新启动计算机,请不要重新启动进程。
重新启动\u否\u重新启动=8
}
#endregion重新启动管理器枚举
}

这是否回答了您的问题?不,我用的是msix。那你的问题为什么包括标签?如果建议的副本没有解决您的问题,那么您的问题似乎与此无关,因此不应包括该标记。@JohnG我认为这会起作用,但在msix环境中,我必须部署两个包,一个用于“包装器”,另一个用于应用程序,否则安装将失败。我正在探索的另一个选择是向Windows任务调度程序添加一个任务,以便在更新后几分钟重新启动应用程序,但这太不规范了。我希望有一个更清洁的解决方案支持的msix。