How do I detect if I'm running in the console

后端 未结 4 1592
误落风尘
误落风尘 2020-12-17 14:28

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 rep

相关标签:
4条回答
  • 2020-12-17 15:06

    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.

    0 讨论(0)
  • 2020-12-17 15:13

    Just discovered that "Console.Title" will be a blank string in a windows application and it will be automatically set in a console application.

    Still a hack though.

    0 讨论(0)
  • 2020-12-17 15:14

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

    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 );
    

    It's a side effect so it may not be a reliable method of detection, but it works for now.

    0 讨论(0)
  • 2020-12-17 15:21

    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).

    0 讨论(0)
提交回复
热议问题