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