问题
Ive some library code that is used by both console and wpf apps. In the library code, there are some Console.Read()
calls. I only want to do those input reads if the app is a console app not if its a GUI app - how to tell in dll if the app has a console?
回答1:
Work for me (using native method)
First, declare:
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
After, check with elegance... hahaha...:
if (GetConsoleWindow() != IntPtr.Zero)
{
Console.Write("has console");
}
回答2:
In the end I did as follows:
// Property:
private bool? _console_present;
public bool console_present {
get {
if (_console_present == null) {
_console_present = true;
try { int window_height = Console.WindowHeight; }
catch { _console_present = false; }
}
return _console_present.Value;
}
}
//Usage
if (console_present)
Console.Read();
Following thekips advice I added a delegate member to library class to get user validation - and set this to a default implimentation that uses above to check if theres a console and if present uses that to get user validation or does nothing if not (action goes ahead without user validation). This means:
- All existing clients (command line apps, windows services (no user interaction), wpf apps) all work with out change.
- Any non console app that needs input can just replace the default delegate with someother (GUI - msg box etc) validation.
Thanks to all who replied.
回答3:
if (Environment.UserInteractive)
{
// A console is opened
}
See: http://msdn.microsoft.com/en-us/library/system.environment.userinteractive(v=vs.110).aspx
Gets a value indicating whether the current process is running in user interactive mode.
回答4:
You can use this code:
public static bool HasMainWindow()
{
return (Process.GetCurrentProcess().MainWindowHandle != IntPtr.Zero);
}
Worked fine with quick test on Console vs. WinForms application.
回答5:
You should fix this in your design. This is a nice example of a place in which inversion of control would be very handy. As the calling code is aware of which UI is available this code should specify an instance of a IInputReader
interface for example. This way you can use the same code for multiple scenarios for getting input from the user.
回答6:
You can pass argument on initialize.
for example:
In your library class, add constructor with 'IsConsole' parameter.
public YourLibrary(bool IsConsole)
{
if (IsConsole)
{
// Do console work
}
else
{
// Do wpf work
}
}
And from Console you can use:
YourLibrary lib = new YourLibrary(true);
Form wpf:
YourLibrary lib = new YourLibrary(false);
回答7:
This SO question may provide you some solution...
Another solution is:
Console.Read() returns -1 in windows form application without opening up a console window. In console app it returns the actual value. So you can write something like
int j = Console.Read();
if (j == -1)
MessageBox.Show("Its not a console app");
else
Console.WriteLine("It's a console app");
I tested this code on console and winform apps. In console app, if user inputs '-1', the value of j is 45. So it will work.
回答8:
if you want a good design, abstract the GUI dependences using an interface. Implements a concrete class for the console version, another for the WPF version, and inject the correct version using any way (dependency injection, inversion of control, etc).
回答9:
I rewrote @Ricibob's answer
public bool console_present {
get {
try { return Console.WindowHeight > 0; }
catch { return false; }
}
}
//Usage
if (console_present) { Console.Read(); }
It is simpler, but I prefer this native implementation:
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
//Usage
if (GetConsoleWindow()) { Console.Read(); }
回答10:
This is a modern (2018) answer to an old question.
var isReallyAConsoleWindow = Environment.UserInteractive && Console.Title.Length > 0;
The combination of Environment.UserInteractive and Console.Title.Length should give a proper answer to the question of a console window. It is a simple and straight forward solution.
来源:https://stackoverflow.com/questions/6408588/how-to-tell-if-there-is-a-console