Как определить, запущен ли я в консоли - PullRequest
16 голосов
/ 13 апреля 2009

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

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

Ответы [ 4 ]

8 голосов
/ 13 апреля 2009

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

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

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

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

7 голосов
/ 07 марта 2013

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

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

1 голос
/ 13 апреля 2009

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

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

...

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

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

1 голос
/ 13 апреля 2009

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

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

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

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

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

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

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

...