我有一个既是gui又是控制台的应用程序。
控制台:它是根据Windows计划执行的,可以执行一些自动化任务,因此需要使用参数进行调用
GUI :用于输入配置参数,这是用户比控制台更好的方法。
所有这些都很好。它主要是一个控制台应用程序,如果不带任何参数打开控制台并显示配置表单,则该控制台将被隐藏。
问题: 如果我从控制台使用NO参数将其打开,则该控制台将被隐藏并显示该表单。 如果从Windows打开应用程序,然后隐藏控制台,如何隐藏从控制台打开的应用程序的位置或信息。
答案 0 :(得分:1)
一种方法是将cli版本和gui版本分成2个可执行文件(例如7z使用命令行工具7z.exe和7zG Gui版本)
您可以在Visual Studio中拥有3个项目:
控制台和WindowsGui引用了您的Logic项目
这将为您提供更简洁的代码,因为每个“前端”项目将仅处理其用途(处理GUI或控制台内容),并且两个前端均可调用您的逻辑
答案 1 :(得分:1)
如果您真的想知道应用程序的“启动位置”,则必须知道父进程是什么。为了了解您的父进程,您可以阅读How to get parent process in .NET in managed way
的解决方案然后,例如,您可以检查您的父进程名称是否为explorer
(Windows)以将您的应用程序作为GUI打开。
基于How to get parent process in .NET in managed way
中提供的解决方案的示例代码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
答案 2 :(得分:0)
我不清楚您要达到什么目标。据我了解,无论是否有参数,该应用程序都将作为控制台应用程序启动。为防止其消失,您可以使用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();
}
如果您的应用程序设置为控制台应用程序,则默认情况下它将启动控制台窗口。现在,如果您需要在不同时间显示和隐藏控制台,则可以查看this post,其中已接受的答案提供了一种适当的方法来利用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);
如果这不能解决您的需要,请随时在帖子中进行更详尽的介绍,并添加一些代码以对问题进行更多定义。我无法发表评论并提出问题,因此我给出了基本解决方案。如有任何疑问,请随时提问。
答案 3 :(得分:0)
这可能会有所帮助:
for
用法:
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());
功能,您需要添加this code。