Я пытаюсь адаптировать пример Host03, найденный здесь (http://msdn.microsoft.com/en-us/library/windows/desktop/ee706577(v=vs.85).aspx), для использования интерфейса WPF. Я попытался завершить это, создав пользовательские StringWriter и StringReader и установив Console.Out и Console.In для моего пользовательские классы. Вот как выглядит код прототипа:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ConsoleWriter _consoleWriter;
private TextWriter _textWriter;
private ConsoleReader _consoleReader;
private TextReader _textReader;
public MainWindow()
{
InitializeComponent();
_textWriter = Console.Out;
_textReader = Console.In;
_consoleWriter = new ConsoleWriter(ref tb);
Console.SetOut(_consoleWriter);
tb.KeyUp += OnTextInputKeyUp;
}
private void OnTextInputKeyUp(object sender, KeyEventArgs e)
{
if(e.Key == Key.Enter)
{
_consoleReader = new ConsoleReader(tb.Text);
Console.SetIn(_consoleReader);
var input = Console.ReadLine();
// I'm creating a thread here, because otherwise the following exception occurs:
// "The calling thread cannot access this object because a different thread owns it"
var t = new Thread(new ThreadStart(
delegate
{
// PSListenerConsoleSample is the class used in the Host03 sample which I am trying to adapt
// The execute method in PShellListener has been made public for prototype purposes,
// in the sample it is private
var listener = new PSListenerConsoleSample();
listener.Execute(input);
}));
t.Start();
}
}
~MainWindow()
{
Console.SetOut(_textWriter); // Redirect Console back to original TextWriter.
Console.SetIn(_textReader);
_consoleWriter.Close(); // Close our ConsoleWriter TextWriter.
}
}
public class ConsoleWriter : StringWriter
{
private TextBox _textBox;
public ConsoleWriter(ref TextBox textBox)
{
_textBox = textBox;
}
public override void WriteLine(string value)
{
if (_textBox.Dispatcher.CheckAccess())
{
_textBox.Text += value + "\n";
}
else
{
_textBox.Dispatcher.Invoke(DispatcherPriority.Normal,
(Action)(() => { _textBox.Text += "\n" + value + "\n"; }));
}
}
}
public class ConsoleReader : StringReader
{
private string _s;
public ConsoleReader(string s) : base(s)
{
_s = s;
}
public override string ReadLine()
{
return _s;
}
}
}
В настоящее время класс ConsoleReader возвращает весь отображаемый текст, поэтому он предназначен для работы только с первой введенной командой. Например, если я ввожу «ls» и нажимаю ввод, отображается содержимое моего каталога bin \ debug. Проблема в том, что я пытаюсь поддерживать программы, требующие ввода-вывода. Например, рассмотрим следующее консольное приложение:
namespace DemoQuestion
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, I am the program you just called. Please enter something:");
var input = Console.ReadLine();
Console.WriteLine("I received the following input from you: {0}", input);
}
}
}
Эта простая программа прекрасно работает в образце Host03, запрашивая у пользователя ввод, а затем считывая и отображая его. В моем адаптированном примере, если я ввожу «T: \ DemoQuestion.exe», происходит первоначальный Console.WriteLine, отображающий «Привет, я и т. Д.», Но я не могу понять, как вернуть ввод пользователя в программу.
Я прошу прощения за сложность вопроса, я старался изо всех сил, чтобы упростить его. Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.