Вызов консоли из WPF приложения. Неверный дескриптор
Хочу вызвать консоль из своего wpf приложения. Не отдельное приложение. А как часть моего приложения.
Гугл привел к такому коду
[DllImport("kernel32")]
private static extern bool AllocConsole(int processId);
[DllImport("kernel32.dll")]
private static extern bool FreeConsole();
Пробуем вызвать.
AllocConsole(-1);
for (int i = 0; i < 100; i++)
{
Thread.Sleep(30);
Console.WriteLine(i.ToString());
}
FreeConsole();
Все работает как нужно, но только 1 раз. При попытке вызвать еще раз это код получаем ошибку Неверный дескриптор.
Пробовал различные варианты вызова консоли. Почти все работают. Но опять же 1 раз.
Что не так? Спасибо.
Полный текст ошибки поймал через отладчик.
Но это мало что дает. Так как ошибка на Console.WriteLine. И понятно что ему некуда выводить текст.
System.IO.IOException
HResult=0x80070006
Message=Неверный дескриптор.
Source=System.Console
StackTrace:
at System.ConsolePal.WindowsConsoleStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.WriteLine(String value)
at System.IO.TextWriter.SyncTextWriter.WriteLine(String value)
at System.Console.WriteLine(String value)
at WpfAppConsol.MainWindow.Button_Click(Object sender, RoutedEventArgs e) in D:\VSProject\WpfAppConsol\WpfAppConsol\MainWindow.xaml.cs:line 46
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run()
at WpfAppConsol.App.Main()
Ответы (1 шт):
Полный текст ошибки поймал через отладчик. Но это мало что дает.
Это как раз и говорит о том, что вы забыли установить дескриптор (handle).
Текст ошибки на английском.
System.IO.IOException: 'The handle is invalid.'
Решение.
[DllImport("kernel32.dll")]
private static extern bool AllocConsole();
[DllImport("kernel32.dll")]
private static extern bool FreeConsole();
Полная настройка с вводом и выводом
AllocConsole();
TextWriter stdOutWriter = new StreamWriter(Console.OpenStandardOutput(), Console.OutputEncoding) { AutoFlush = true };
TextWriter stdErrWriter = new StreamWriter(Console.OpenStandardError(), Console.OutputEncoding) { AutoFlush = true };
TextReader strInReader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding);
Console.SetOut(stdOutWriter);
Console.SetError(stdErrWriter);
Console.SetIn(strInReader);
Console.Write("Введите текст: ");
string text = Console.ReadLine();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(30);
Console.WriteLine(text + " мир " + i);
}
Console.ReadKey();
FreeConsole();
Введите текст: привет
привет мир 0
привет мир 1
привет мир 2
привет мир 3
привет мир 4
привет мир 5
привет мир 6
привет мир 7
привет мир 8
привет мир 9