在C#中使用方法Application.Restart()应该重新启动当前应用程序:但是看来这并不总是有效。
有人可以告诉我,为什么这个问题一直不起作用吗?
可能有很多原因。这并不是说该方法无效;而是,很多时候程序员忘记了自己在代码中放了一些东西,这些东西会阻止应用程序自动关闭或启动。两个例子:
-
表单上的关闭事件可以停止应用程序的关闭
-
如果要检查已经运行的进程,则旧进程可能关闭得不够快,无法启动新进程。
检查您的代码是否有这样的陷阱。如果您在空白应用程序中看到此行为,则实际功能比代码更有可能是问题。
检查Microsoft的应用程序重新启动源代码。
就我而言(没有单实例),
没用
1 2
| System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit(); |
做好了!
我唯一遇到这种问题的时间是在我的主要表单中有一个自定义的FormClosing事件处理程序时,该处理程序执行逻辑并取消了该事件。
编辑:
我现在遇到另一个实例,根据您的评论,它可能反映了您所遇到的情况。
使用Mutex运行单个实例应用程序时,我是从相当嵌入式的位置调用Application.Restart(),该位置需要进行大量清理工作。因此,似乎重新启动是在先前实例完成之前启动新实例,因此Mutex阻止了新实例启动。
在我的程序中,我有一个互斥体以确保仅在计算机上运行该应用程序的一个实例。这导致新启动的应用程序无法启动,因为互斥锁没有及时发布。结果,我在Properties.Settings中输入了一个值,指示应用程序正在重新启动。在调用Application.Restart()之前,将Properties.Settings值设置为true。在Program.Main()中,我还添加了对该特定property.settings值的检查,以便将其设置为true时将其重置为false并存在一个Thread.Sleep(3000);
在您的程序中,您可能具有以下逻辑:
1 2 3 4 5 6
| if (ShouldRestartApp)
{
Properties.Settings.Default.IsRestarting = true;
Properties.Settings.Default.Save();
Application.Restart();
} |
在Program.Main()中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| [STAThread]
static void Main()
{
Mutex runOnce = null;
if (Properties.Settings.Default.IsRestarting)
{
Properties.Settings.Default.IsRestarting = false;
Properties.Settings.Default.Save();
Thread.Sleep(3000);
}
try
{
runOnce = new Mutex(true,"SOME_MUTEX_NAME");
if (runOnce.WaitOne(TimeSpan.Zero))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
finally
{
if (null != runOnce)
runOnce.Close();
}
} |
而已。
在转储之前尝试锁定。这是我启动完整应用转储的方式。可能会为您工作,可能不会。
1 2 3 4 5
| Context.Application.Lock();
Context.Session.Abandon();
Context.Application.RemoveAll();
Context.Application.Restart();
Context.Application.UnLock(); |
1 2
| Application.Restart();
Application.ExitThread(); |
这对我有用,谢谢。
试试这个代码:
1
| bool appNotRestarted = true; |
此代码也必须在函数中:
1 2 3 4 5 6
| if (appNotRestarted == true)
{
appNotRestarted = false;
Application.Restart();
Application.ExitThread();
} |
如果该应用程序是首先从网络位置启动的并且未签名(您首先会看到警告对话框),它将不会重新启动,只会退出。
我对.Net 4.7框架有同样的问题。接受的答案是我成功的关键。
我确实在FormClosing事件中包含代码,该事件花费一些时间并停止了重新启动过程。
我要做的是放一个这样的哨兵:
1 2 3
| If JustCloseIT = False Then
'all closing code, like logging the session log-out to a database and all those goodies we all do.
End If |
只有这样Application.Restart()才起作用!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public static void ApplicationRestart(params string[] commandLine)
{
lock (SynchObj)
{
if (Assembly.GetEntryAssembly() == null)
{
throw new NotSupportedException("RestartNotSupported");
}
if (_exiting)
return;
_exiting = true;
if (Environment.OSVersion.Version.Major < 6) return;
bool cancelExit = true;
try
{
foreach (Form f in Application.OpenForms.OfType<Form>().ToList())
{
f.InvokeIfRequired(frm =>
{
frm.FormClosing += (sender, args) => cancelExit = args.Cancel;
frm.Close();
});
if (cancelExit) break;
}
if (cancelExit) return;
Process.Start(new ProcessStartInfo
{
UseShellExecute = true,
WorkingDirectory = Environment.CurrentDirectory,
FileName = Application.ExecutablePath,
Arguments = commandLine.Length > 0 ? string.Join("", commandLine) : string.Empty
});
Application.Exit();
}
finally
{
_exiting = false;
}
}
} |
我知道这是一个旧线程,但是我找到了一种解决方法。希望这会帮助需要帮助的其他人。
我需要一种解决方案,该解决方案在从代码启动ClickOnce Application的过程中触发更新序列。 Applicatoin.Restart没有这样做。我想要一种能够检查更新,然后调用内置的更新管理器的方法,这样我就不必编写自定义的更新。
1 2 3 4 5 6 7 8
| 'VB Code Sample
Dim strStart As String = System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) &"\\Programs\\Folder\\YourApplication.appref-ms"
Application.Exit()
Try
Process.Start(strStart)
Catch ex As Exception
'Do something with the exception
End Try |
我看到的唯一解决方法是用户可以从开始菜单中删除快捷方式。如果这是一个问题,您可以编写一些代码以将"开始"菜单链接复制到您选择的某个文件夹中,最好在ClickOnce应用程序文件夹中。这很重要,因为应用程序的开始菜单图标不是.lnk或.exe,它实际上是.appref-ms链接。请参阅ClickOnce .appref-ms,而不是指向.application文件的链接?此链接对此进行了更详细的说明。
该代码将与ClickOnce SingleInstance应用程序一起使用。