Как передать консоль на несколько потоков сразу в С#?
У меня есть программа, которая выводит Консоль и записывает ее в файл журнала, однако она больше не отображается в окне консоли. Есть ли способ сохранить его в окне, но также записать его в файл журнала?
Update:
appLogStream = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.Read);
TextWriter logtxtWriter = Console.Out;
logstrmWriter = new StreamWriter(appLogStream);
if(!console) Console.SetOut(logstrmWriter);
logstrmWriter.AutoFlush = true;
Console.WriteLine("Started at " + DateTime.Now);
Консоль
- это постоянный набор в классе. В основном он говорит, использует ли он консольное окно или нет (readline не вызывается и т.д., Если не в консоли).
Итак, есть ли способ написать как консоль, так и файл?
Ответы
Ответ 1
Вы можете просто прочитать, что этот поток зарегистрировал его и распечатал.
Это немного зависит от вашего кода, если вы назначаете выходной поток во входной поток outfile, это может быть немного сложнее, если вы читаете содержимое в буфер, который должен быть немного проще.
О вашем обновлении я бы предложил вам обменять все Console
на пользовательскую функцию ведения журнала, например. экземпляр MyLogger (код ниже). Который записывает ваш вывод на консоль и в файл журнала.
class MyLogger {
private FileStream appLogStream;
public MyLogger() {
appLogStream = new FileStream(logFile, FileMode.Append, FileAccess.Write,
FileShare.Read);
appLogStream.WriteLine("Started at " + DateTime.Now);
}
public Write(string msg) {
Console.Write(msg);
appLogStream.Write(msg);
}
public WriteLine(string msg) {
Console.WriteLine(msg);
appLogStream.WriteLine(msg);
}
}
Ответ 2
Я думаю, вы можете сделать что-то вроде этого:
public class ConsoleDecorator : TextWriter
{
private TextWriter m_OriginalConsoleStream;
public ConsoleDecorator(TextWriter consoleTextWriter)
{
m_OriginalConsoleStream = consoleTextWriter;
}
public override void WriteLine(string value)
{
m_OriginalConsoleStream.WriteLine(value);
// Fire event here with value
}
public static void SetToConsole()
{
Console.SetOut(new ConsoleDecorator(Console.Out));
}
}
Вам придется "зарегистрировать" оболочку с вызовом ConsoleDecorator.SetToConsole();
После этого каждый вызов Console.WriteLine перейдет к настраиваемому методу, и там вы можете запустить событие и получить текст, написанный в других местах (например, журнал).
если вы захотите использовать этот способ, вам нужно будет сделать класс одиночным, а затем вы можете получить доступ к четной регистрации из других классов (которые должны записываться в файл журнала, когда четный уволен)
Ответ 3
Когда вы вызываете Console.SetOut, вы указываете, куда должна писать Консоль. Если вы этого не сделаете (то есть, как обычно используется Консоль), и вы вызываете Console.Write, он проверяет, есть ли у него выходной редактор, а если нет, задает его с помощью
stream = OpenStandardOutput(256);
а затем
Encoding encoding = Encoding.GetEncoding((int) Win32Native.GetConsoleOutputCP());
writer = TextWriter.Synchronized(new StreamWriter(stream, encoding, 256, false) { HaveWrittenPreamble = true, AutoFlush = true });
Итак, вы должны иметь возможность делать то, что вы делаете сейчас, и если вы также хотите отбросить все до стандартных, как если бы вы не перенаправили консоль, вы можете создать свой собственный сценарий, используя поток, который вы открываете, используя Console.OpenStandardOutput
. Win32Native
, используемый в этом коде, является внутренним, поэтому у вас нет доступа к нему, но вы можете использовать Console.OutputEncoding
для получения кодировки, которую он использует.
Что-то, что вы также можете попробовать, это использовать свойство Console.Out
, чтобы получить и вставить на стандартный вывод TextWriter непосредственно перед вызовом SetOut. Затем вы можете просто использовать это для эха для стандартного вывода.