Подтвердить что ты не робот

Как определить, запущен ли я в консоли

Есть ли простой способ, чтобы библиотека кода автоматически обнаруживала, вызвана ли она из консольного приложения или приложения Windows? Я хочу, чтобы моя библиотека не сообщала в журнал событий Windows, если она вызывается из окна консоли, но вместо этого отправляется в консольное окно. Если, однако, он не запускается из консольного окна, он должен отчитываться в Журнале событий Windows.

Я думал о том, что мой компонент протокола должен быть передан в целевой лог, но он был бы аккуратным, если бы он мог просто автоматически обрабатывать эти две цели изначально. Я еще не требую что-то столь же обширного, как log4net, действительно, если возникнет необходимость предоставить поддержку для входа в базу данных/файл и другие пока неизвестные цели ведения журнала, я могу порекомендовать такое решение. Пока же, только когда мой компонент автоматически обнаруживает среду и записывается в консоль, или журнал событий в соответствии с окружением будет много.

4b9b3361

Ответ 1

Архитектурно, передача контекста ведения журнала в компонент библиотеки является правильным выбором. Библиотека не знает и не должна знать этого контекста относительно среды, в которой она выполняется.

Поскольку вы хотите поддерживать эти два специальных случая изначально внутри библиотеки, я бы предложил единый подход.

  • Идем дальше и создаем более обобщенную точку входа/ручку регистрации, с которой управляет вызывающий.
  • Создайте отдельную точку входа/ручку, которая автоматически устанавливает обобщенную для случаев, которые вы хотите автоматически поддерживать.

Тем не менее, это кажется слишком сложным на основе вашего описания. Рассматривали ли вы просто использование соответствующих TraceListeners в вашей коллекции Diagnostics, где ваше консольное приложение добавляет соответствующий TraceListener для вывода на консоль, а приложение без консоли добавляет соответствующий EventLog TraceListener для вывода в журнал событий Windows? Это имеет дополнительное преимущество в том, чтобы хорошо работать со всей встроенной поддержкой ведения журнала .net, не предполагая каких-либо внешних зависимостей (например, log4net).

Ответ 2

Просто обнаружил, что "Console.Title" будет пустой строкой в ​​приложении Windows, и она будет автоматически установлена ​​в консольном приложении.

Тем не менее, взломать.

Ответ 3

Варианты этого вопроса заданы раньше. А именно здесь и здесь.

" Решения, похоже, сводятся к двум вариантам.

  • Использование размышлений, чтобы выяснить, что вызывает вас.
  • В случае консольного приложения поставить вызов на консоль в try-catch блокировать и посмотреть, не сбой или преуспевает.

Моя собственная рекомендация заключается в том, чтобы ваша библиотека экспортировала интерфейс. Интерфейс имеет функцию или свойство, которые возвращают тип вызывающего. Вызывающий объект имеет класс, который реализует интерфейс и возвращает тип. Поскольку сложность вызывает беспокойство, вы можете немного контролировать это, что вы размещаете в интерфейсе.

Если приложение не регистрируется в библиотеке, вы можете попробовать выбросить ошибку или попробовать какую-то схему автоматического обнаружения.

Используя интерфейс и выдавая ошибку, вы делаете это явным для программиста, используя библиотеку, что именно вы ожидаете. Взаимодействие между ними определяется интерфейсом.

Кроме того, взаимодействие более гибкое, чем автоматическая схема, потому что я, как пользователь, выбираю, как мой бинарный код взаимодействует с вашей библиотекой, а не какой-то таинственный набор правил.

Ответ 4

Я знаю, что это хак, но вызов Console.Read будет генерировать исключение, когда нет консоли.

bool isConsole = true;
try
{
    isconsole = Console.CursorLeft >= int.MinValue;
}
catch( IOException )
{
    // Try to attach to parent process console window
    isConsole = AttachConsole( 0xFFFFFFFF );
}   

...

[DllImport( "kernel32", SetLastError = true )]
private static extern bool AttachConsole( uint dwProcessId );

Это побочный эффект, поэтому он не может быть надежным методом обнаружения, но он работает пока.