C# 为什么 Application.Restart() 不可靠?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/95098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is Application.Restart() not reliable?
提问by MADMap
Using the method Application.Restart()
in C# should restart the current application: but it seems that this is not always working.
使用Application.Restart()
C# 中的方法应该重新启动当前应用程序:但似乎这并不总是有效。
Is there a reason for this Issue, can somebody tell me, why it doesn't work all the time?
这个问题有没有原因,有人可以告诉我,为什么它一直不起作用?
采纳答案by TheSmurf
There could be a lot of reasons for this. It's not that the method doesn't work; rather, many times programmers forget that they've put something in their code that would stop the application from automatically shutting down, or starting up. Two examples:
这可能有很多原因。不是方法不行;相反,很多时候程序员忘记了他们在他们的代码中放置了一些可以阻止应用程序自动关闭或启动的东西。两个例子:
- The Closing event on a form can stop an app's shutdown
- If you're doing checking for an already-running process, the old one may not be closing fast enough to allow the new one to start up.
- 表单上的 Closing 事件可以停止应用程序的关闭
- 如果您正在检查一个已经在运行的进程,旧进程的关闭速度可能不足以让新进程启动。
Check your code for gotchas like that. If you're seeing this behaviour within a blank application, then that's more likely to be a problem with the actual function than your code.
检查您的代码是否有类似的问题。如果您在空白应用程序中看到这种行为,那么与您的代码相比,实际功能更有可能出现问题。
Check Microsoft's sourcecode of application restart.
检查微软的应用程序重启源代码。
回答by Oli
Try locking before dumping. Here's how I initiate a full app-dump. Might work for you, might not.
在倾倒之前尝试锁定。这是我启动完整应用程序转储的方式。可能对你有用,也可能不适合。
Context.Application.Lock();
Context.Session.Abandon();
Context.Application.RemoveAll();
Context.Application.Restart();
Context.Application.UnLock();
回答by Timothy Carter
The only time I've run into this kind of issue is when in my main form I had a custom FormClosing
event handler, that performed logic and canceled the event.
我遇到这种问题的唯一一次是在我的主表单中我有一个自定义FormClosing
事件处理程序,它执行逻辑并取消事件。
EDIT:
编辑:
I have now run into another instance and based on your comments it possibly mirrors what you were experiencing.
我现在遇到了另一个实例,根据您的评论,它可能反映了您的经历。
When running a single instance application, using a Mutex, I was calling Application.Restart()
from a fairly embedded location, that had a lot of cleanup to do. So it seems the restart was launching a new instance before the previous instance was complete, so the Mutex was keeping the new instance from starting.
在运行单实例应用程序时,使用互斥锁,我Application.Restart()
从一个相当嵌入的位置调用,有很多清理工作要做。所以看起来重启是在前一个实例完成之前启动一个新实例,所以互斥锁阻止了新实例的启动。
回答by Matt Hanson
If the application was first launched from a network location and is unsigned (you get the warning dialog first), it won't restart and will only exit.
如果应用程序首先从网络位置启动并且未签名(您首先看到警告对话框),则它不会重新启动,只会退出。
回答by cprcrack
In my case (NO single-instance), where
在我的情况下(没有单实例),其中
Application.Restart();
didn't work,
没用
System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit();
did the job!
做的工作!
回答by ferhatayhan
Try this code:
试试这个代码:
bool appNotRestarted = true;
This code must also be in the function:
此代码也必须在函数中:
if (appNotRestarted == true)
{
appNotRestarted = false;
Application.Restart();
Application.ExitThread();
}
回答by cmptrs4now
In my program I have a mutex to ensure only one instance of the application running on a computer. This was causing the newly started application to not start because the mutex had not been release in a timely fashion. As a result I put a value into Properties.Settings
that indicates that the application is restarting. Before calling Application.Restart()
the Properties.Settings
value is set to true. In Program.Main()
I also added a check for that specific property.settings
value so that when trueit is reset to falseand there is a Thread.Sleep(3000);
在我的程序中,我有一个互斥锁来确保只有一个应用程序实例在计算机上运行。这导致新启动的应用程序无法启动,因为互斥锁没有及时释放。因此,我将一个值放入其中Properties.Settings
,表明应用程序正在重新启动。在调用之前Application.Restart()
将该Properties.Settings
值设置为true。在Program.Main()
我还添加了对该特定property.settings
值的检查,以便在true 时将其重置为false并且有一个Thread.Sleep(3000);
In your program you may have the logic:
在您的程序中,您可能有以下逻辑:
if (ShouldRestartApp)
{
Properties.Settings.Default.IsRestarting = true;
Properties.Settings.Default.Save();
Application.Restart();
}
In Program.Main()
在 Program.Main()
[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();
}
}
That's it.
就是这样。
回答by shima lagzian
Application.Restart();
Application.ExitThread();
this worked for me thanks.
这对我有用,谢谢。
回答by Nathan
I know this is an old thread, but I found a workaround. Hopefully this will help someone else in need.
我知道这是一个旧线程,但我找到了一个解决方法。希望这会帮助其他有需要的人。
I needed a solution that would trigger the update sequence during a ClickOnce Application startup from code. Applicatoin.Restart
did not do this. I wanted a way of being able to check for an update and then invoking the built in update manager so that I didn't have to write a custom one.
我需要一个可以在 ClickOnce 应用程序从代码启动期间触发更新序列的解决方案。 Applicatoin.Restart
没有这样做。我想要一种能够检查更新然后调用内置更新管理器的方法,这样我就不必编写自定义的更新管理器。
'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
The only issue that I see with this workaround is that a user could delete the shortcut from the start menu. If that is a concern you could write some code to copy the start menu link to the some folder of your choosing, preferably in the ClickOnce application folder. This is important because the start menu icon for your application is not a .lnk or .exe, it is actually a .appref-ms link. See ClickOnce .appref-ms more than a link to .application file?This link explains this in more detail.
我在此解决方法中看到的唯一问题是用户可以从开始菜单中删除快捷方式。如果这是一个问题,您可以编写一些代码将开始菜单链接复制到您选择的某个文件夹,最好是在 ClickOnce 应用程序文件夹中。这很重要,因为应用程序的开始菜单图标不是 .lnk 或 .exe,它实际上是 .appref-ms 链接。看到ClickOnce .appref-ms 不仅仅是指向 .application 文件的链接?此链接更详细地解释了这一点。
This code will work with ClickOnce SingleInstance Applications.
此代码适用于 ClickOnce SingleInstance 应用程序。
回答by Martin.Martinsson
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;
}
}
}