Использование метода Application.Restart()
в С# должно перезапустить текущее приложение: но кажется, что это не всегда работает.
Есть ли причина для этой проблемы, может кто-нибудь сказать мне, почему она не работает все время?
Использование метода Application.Restart()
в С# должно перезапустить текущее приложение: но кажется, что это не всегда работает.
Есть ли причина для этой проблемы, может кто-нибудь сказать мне, почему она не работает все время?
Для этого может быть много причин. Это не значит, что метод не работает; скорее, много раз программисты забывают, что они поместили что-то в свой код, что остановит приложение от автоматического выключения или запуска. Два примера:
Проверьте свой код для таких ошибок. Если вы видите это поведение в пустом приложении, то это скорее будет проблемой с фактической функцией, чем ваш код.
В моем случае (NO single-instance), где
Application.Restart();
не работает,
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 оно reset false, и есть Thread.Sleep(3000);
В вашей программе у вас может быть логика:
if (ShouldRestartApp)
{
Properties.Settings.Default.IsRestarting = true;
Properties.Settings.Default.Save();
Application.Restart();
}
В 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();
}
}
Что это.
Попробуйте блокировку перед сбросом. Вот как я запускаю полный спуск приложений. Может работать для вас, может и нет.
Context.Application.Lock();
Context.Session.Abandon();
Context.Application.RemoveAll();
Context.Application.Restart();
Context.Application.UnLock();
Если приложение было сначала запущено из сетевого местоположения и не указано (вы сначала получите предупреждение), он не перезапустится и выйдет только.
Попробуйте этот код:
bool appNotRestarted = true;
Этот код также должен быть в функции:
if (appNotRestarted == true)
{
appNotRestarted = false;
Application.Restart();
Application.ExitThread();
}
Application.Restart();
Application.ExitThread();
это сработало для меня спасибо.
Я знаю, что это старый поток, но я нашел обходное решение. Надеюсь, это поможет кому-то еще в этом нуждается.
Мне понадобилось решение, которое инициировало бы последовательность обновления во время запуска приложения 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
Единственная проблема, с которой я сталкиваюсь с этим обходным путем, заключается в том, что пользователь может удалить ярлык из меню "Пуск". Если это вызывает беспокойство, вы можете написать какой-то код, чтобы скопировать ссылку меню "Пуск" в выбранную вами папку, желательно в папке приложения ClickOnce. Это важно, потому что значок меню запуска для вашего приложения не является .lnk или .exe, это фактически ссылка .appref-ms. См. ClickOnce.appref-ms больше, чем ссылка на файл .application? Эта ссылка объясняет это более подробно.
Этот код будет работать с приложениями ClickOnce SingleInstance.
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;
}
}
}