views:

246

answers:

3

Is there a simple way to have a code library automatically detect if it's being called from a console application or a windows application? I'd like my library not to report to the Windows Event log if it's being called from a console window, but instead report to the console window. If however, it's not being run from within a console window, it should report to the Windows Event Log.

I thought about requiring my the logging component to be passed the log target, but it would be neat if it could just automatically handle these two targets natively. I don't yet require something as extensive as log4net, indeed, if it becomes necessary to provide support to log to a database/file and other as yet unknown logging targets, then I may recommend such a solution. For now though, just having my component auto-detect the environment and log to the console or the event log according to the environment would be plenty.

+5  A: 

Architecturally, passing the logging context into the library component is the right choice. The library doesn't, and indeed shouldn't, know that much context about the environment it's being run in.

Because you want to support these two special cases natively within the library, I'd suggest a unified approach.

  1. Go ahead and create the more generalized logging entry point/knob that the caller controls.
  2. Create a separate entry point/knob that automatically sets the generalized one for the cases that you want to automatically support.

Even that seems too complicated based on your description, though. Have you considered simply using appropriate TraceListeners in your Diagnostics collection, where your console app adds the appropriate TraceListener to output to the console and the non-console app adds the appropriate EventLog TraceListener to output to the Windows event log? This has the added advantage of working well with all the built-in .net logging support without assuming any external dependencies (e.g., log4net).

Greg D
To be honest, I've not really done much experimentation in the way of logging prior to now. In fact, I've only ever needed to log to one of a few pre-determined places. Consequently I've never experimented with TraceListeners...which is about to change. Thanks, +1
BenAlabaster
Good deal, glad I could help! TraceListeners rule. :D
Greg D
A: 

Variants of this question have been asked before. Namely here and here.

' The solutions seem to boil down to two options

  • Using reflection to figure out what is calling you.
  • In the case of console application put a call to console in a try-catch block and see if it fails or succeeds.

My own recommendation is to have your library export an interface. The interface has a function or property that return the type of the caller. The calling object has a class that implements the interface and return what type it is. Because complexity is a concern you can control that somewhat by what you place in the interface.

If a application doesn't register itself with the library then you can try throwing an error or trying some scheme of automatic detection.

By using an interface and throwing an error you are making it explicit to the programmer using the library what exactly you expect. The interaction between the two is defined by the interface.

In addition the interaction is more flexible than a automatic scheme because I, as the user, get to choose how my calling binary interacts with your library rather than some mysterious set of rules.

RS Conley
A: 

I know it's kind of a hack, but calling Console.Read will throw an exception when there's no console.

bool isConsole = false;
try
{
    Console.Read();
}
catch( IOException )
{
    isConsole = true;
}

It's a side effect so it may not be a reliable method of detection, but it works for now. The only realy downside is that it swallows a character when it is run from the console which might cause issues with other code.

Paul Alexander
It would also require the user to enter a garbage character before running wouldn't it? I wonder if another static console method wouldn't have the same affect, without user interaction.
John MacIntyre
The whole thing is a hack (the question asked here to start with)
Andrei Rinea