Повторное открытие окна WPF из приложения консоли
Я хочу открыть окно WPF из приложения консоли. После ссылки на этот пост, он отлично работает.
Проблема заключается в следующем: когда пользователь закрыл окно WPF (вручную), он не может быть повторно открыт с консоли, бросая сообщение об ошибке: "Невозможно создать более одного экземпляра System.Windows.Application в том же AppDomain."
Вот код:
class Program
{
static void Main(string[] args)
{
string input=null;
while ((input = Console.ReadLine()) == "y")
{
//Works fine at the first iteration,
//But failed at the second iteration.
StartWpfThread();
}
}
private static void OpenWindow()
{
//Exception(Cannot create more than one System.Windows.Application instance in the same AppDomain.)
//is thrown at the second iteration.
var app = new System.Windows.Application();
var window = new System.Windows.Window();
app.Run(window);
//User closes the opened window manually.
}
private static void StartWpfThread()
{
var thread = new Thread(() =>
{
OpenWindow();
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
}
}
Как повторно открыть окно WPF?
Ответы
Ответ 1
Вам не следует создавать приложение вместе с окном, но только один раз отдельно, также убедитесь, что он не выходит после закрытия окна, установив ShutdownMode
соответственно, например
class Program
{
static Application app;
static void Main(string[] args)
{
var appthread = new Thread(new ThreadStart(() =>
{
app = new Application();
app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
app.Run();
}));
appthread.SetApartmentState(ApartmentState.STA);
appthread.Start();
while (true)
{
var key =Console.ReadKey().Key;
// Press 1 to create a window
if (key == ConsoleKey.D1)
{
// Use of dispatcher necessary as this is a cross-thread operation
DispatchToApp(() => new Window().Show());
}
// Press 2 to exit
if (key == ConsoleKey.D2)
{
DispatchToApp(() => app.Shutdown());
break;
}
}
}
static void DispatchToApp(Action action)
{
app.Dispatcher.Invoke(action);
}
}
Также, если вы хотите повторно открыть одно и то же окно, убедитесь, что он никогда не закрыт полностью, чтобы сделать это, вы можете обрабатывать событие Closing
и отменить его с помощью e.Cancel = true;
, а затем просто вызвать Hide
на окно "закрыть" и Show
"снова открыть" его позже.
Ответ 2
Когда вы добавляете окно в качестве параметра в app.Run, вы связываете время жизни своего приложения с вашим окном. Не делайте этого:
private static void OpenWindow()
{
//Exception(Cannot create more than one System.Windows.Application instance in the same AppDomain.)
//is thrown at the second iteration.
var app = new System.Windows.Application();
var window = new System.Windows.Window();
app.Run();
window.Show();
//User closes the opened window manually.
}
Ответ 3
У меня не было возможности проверить это самостоятельно, но после прочтения вашей ошибки я нашел некоторую информацию. В принципе, похоже, что AppDomain
, в котором вы работаете, может использоваться только один раз для каждого приложения - поэтому, возможно, вам нужно создать новый AppDomain
каждый раз, когда вы хотите повторно создать приложение. См. здесь для получения дополнительной информации об этом.
В качестве альтернативы вы можете использовать System.Diagnostics.Process.Start(...)
для правильного запуска приложения. Обратитесь здесь к документации для класса Process
.
Наконец, если вы просто хотите разрешить пользователю запускать приложение из командной строки, может быть проще написать команду script и выполнить это из командной строки.