[英]How do I know if my app was opened from console or windows in C#
我有一个既是gui又是控制台的应用程序。
控制台:它从Windows时间表执行以执行一些自动化任务,因此使用参数进行调用
GUI:用于输入配置参数,这是用户比控制台更好的方法。
所有这些都很好。 它主要是一个控制台应用程序,如果不带任何参数打开控制台并显示配置表单,则该控制台将被隐藏。
问题:如果我从控制台使用NO参数将其打开,则该控制台将被隐藏并显示该表单。 我如何检测从其中打开应用程序的内容或位置,如果它是从Windows打开的,则隐藏控制台,如果它是从控制台打开的,则保持控制台显示。
如果您真的想知道应用程序已在“何处”启动,则必须知道您的父进程是什么。 为了了解您的父进程,您可以阅读如何以托管方式在.NET中获取父进程的解决方案。
然后,您可以例如检查您的父进程名称是否为explorer
(windows),以将您的应用程序作为GUI打开。
基于如何以托管方式在.NET中获取父进程中提供的解决方案的示例代码
namespace ConsoleApp1
{
public static class ProcessExtensions
{
private static string FindIndexedProcessName(int pid)
{
var processName = Process.GetProcessById(pid).ProcessName;
var processesByName = Process.GetProcessesByName(processName);
string processIndexdName = null;
for (var index = 0; index < processesByName.Length; index++)
{
processIndexdName = index == 0 ? processName : processName + "#" + index;
var processId = new PerformanceCounter("Process", "ID Process", processIndexdName);
if ((int)processId.NextValue() == pid)
{
return processIndexdName;
}
}
return processIndexdName;
}
private static Process FindPidFromIndexedProcessName(string indexedProcessName)
{
var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName);
return Process.GetProcessById((int)parentId.NextValue());
}
public static Process Parent(this Process process)
{
return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Process.GetCurrentProcess().Parent().ProcessName);
Console.ReadKey();
}
}
}
此代码将输出:
devenv
explorer
cmd
powershell
一种方法是将cli版本和gui版本分成2个可执行文件(例如7z使用命令行工具7z.exe和7zG Gui版本)
您可以在Visual Studio中拥有3个项目:
Console和WindowsGui引用了您的Logic项目
这将为您提供更简洁的代码,因为每个“前端”项目将仅处理其用途(处理GUI或控制台内容),并且两个前端均可调用您的逻辑
对于您要实现的目标,我还不清楚。 据我了解,无论是否有参数,该应用程序都将作为控制台应用程序启动。 为防止其消失,可以使用Boolean
来防止在用户输入配置时关闭窗口。 例如(语法可能不是DialogResult
100%):
using System;
using System.Windows.Forms;
// Allows you to access the static objects of Console
// without having to repeatedly type Console.Something.
using static System.Console;
static bool configured = false;
static bool showForm = false;
static void Main(string[] args) {
showForm = args.Length < 1;
if (showForm) {
WriteLine("The application needs to be configured.");
using (ConfigForm config = new ConfigForm()) {
if (config.ShowDialog() == DialogResult.OK) {
showForm = false;
configured = true;
// Set your configured arguments here.
}
}
}
// Prevents the console from closing.
while (showForm)
ReadKey();
// Do your processing in this condition.
if (!showForm && configured)
WriteLine("Thanks for playing. Press any key to exit.");
else // Retry or exit in this one.
WriteLine("An error occurred. Press any key to exit.");
ReadKey();
}
如果您的应用程序设置为控制台应用程序,则默认情况下它将启动控制台窗口。 现在,如果您需要在不同时间显示和隐藏控制台,则可以查看这篇文章 ,其中已接受的答案提供了一种适当的方法来利用Windows API来实现此目的,而不必执行一些可疑的逻辑来按标题或标题查找窗口身份。
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
var handle = GetConsoleWindow();
// Hide
ShowWindow(handle, SW_HIDE);
// Show
ShowWindow(handle, SW_SHOW);
如果这不能解决您的需要,请随时在帖子中进行更全面的介绍,并添加一些代码以对问题进行更多定义。 我无法发表评论并提出问题,因此我给出了基本解决方案。 如果你有任何问题随时问。
这可能会有所帮助:
using System;
using System.Diagnostics;
static class IsRanFromConsole
{
private static readonly string[] consoleNames = {
"cmd", "bash", "ash", "dash", "ksh", "zsh", "csh",
"tcsh", "ch", "eshell", "fish", "psh", "pwsh", "rc",
"sash", "scsh", "powershell", "tcc"
};
private static bool isCache = false;
private static bool isConsole;
public static bool IsConsole()
{
if (!isCache)
{
string parentProc = Process.GetCurrentProcess().Parent().ProcessName;
isConsole = Array.IndexOf(consoleNames, parentProc) > -1;
}
return isConsole;
}
}
用法:
Console.WriteLine(IsRanFromConsole.IsConsole());
对于.Parent()
函数,您需要添加以下代码 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.