越来越多的应用程序提供以命令行的方式来运行,通常的做法有两种:单独给应用程序写一个基于命令行运行的控制台程序,用户运行这个程序时它一定是以命令行的方式来运行;以GUI和Command Line共享一个应用或exe文件,但通过不同的arguments来判断,最终分别做不同的处理。
对于单独给应用程序写基于命令行运行的控制台程序,无非是通过判断传递的args数组来辨别并设置程序运行所需要的参数,最终设定各项参数而完成所需要的工作。在这里建议提供对于/?的帮助菜单,方便用户查询。
if (args.Length != 1) { Console.WriteLine("ERROR: Invalid Argument."); Console.WriteLine(@"Type 'MyConsole.exe /?' for usage."); return false; } else { if (args[0] == @"/?") { Console.WriteLine("The syntax for this program is:"); Console.WriteLine("MyConsole.exe [project file]"); Console.WriteLine(); Console.WriteLine("[project file] The path to the XML project file."); return false; } else { string strFilePath = args[0]; if (File.Exists(strFilePath)) { …… return true; } else { Console.WriteLine("Can not find the specified project file:'" + args[0] + "'"); Console.WriteLine("Please check the path of project file and try again."); return false; } } } |
在调试这样的程序时可以通过给项目属性中设置参数来调试,这样设置的参数在项目启动时会以参数的形式传入。
对于一套程序入口却分别接受GUI调用和Command Line方式运行,我们就必须判断当前是以什么方式来运行程序的,检测当前的运行宿主环境就可以帮助我们来判断出到底是否是运行在Console模式下。通过检测程序运行的进程我们可以判断出它的运行方式。
[DllImport("kernel32.dll", SetLastError = true)] static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] static extern bool FreeConsole(); [DllImport("kernel32", SetLastError = true)] static extern bool AttachConsole(int dwProcessId); [DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); IntPtr ptr = GetForegroundWindow(); int processId; GetWindowThreadProcessId(ptr, out processId); Process process = Process.GetProcessById(processId); if (process.ProcessName == "cmd") { AttachConsole(process.Id); Console.WriteLine("start from command line"); //return false; //isStartFromCommandLine = true; //TODO: Hide the GUI and perform the actions. //Release the console. FreeConsole(); return; } //GUI mode Page01StartUp form = new Page01StartUp(); form.Show(); form.Focus(); form.BringToFront(); Application.Run(); |
在这个Case中,程序除了以正常的GUI方式运行外就是命令行方式运行,所以只区别判断了命令行方式,其余时候正常的以GUI方式运行即可。
还有一种方式是这个程序可以在命令行方式里通过不同的参数来启动GUI模式运行,Console模式运行等。通过添加一个来表示是以GUI还是console运行的参数来的会更直接些。
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using Microsoft.Win32; using System.Windows.Forms; namespace ConsoleApplication1 { class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] static extern bool FreeConsole(); [DllImport("kernel32", SetLastError = true)] static extern bool AttachConsole(int dwProcessId); [DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); static void Main(string[] args) { string mode = args.Length > 0 ? args[0] : "gui"; //default to gui if (mode == "gui") { MessageBox.Show("Welcome to GUI mode"); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Page01StartUp()); } else if (mode == "console") { IntPtr ptr = GetForegroundWindow(); int processId; GetWindowThreadProcessId(ptr, out processId); Process process = Process.GetProcessById(processId); //process name if (process.ProcessName == "cmd" ) { //attach the session to the current console AttachConsole(process.Id); Console.WriteLine("Run within the console"); Console.Write("Press any key to continue..."); Console.Read(); } else { //no console AND we're in console mode ... create a new console. AllocConsole(); Console.WriteLine("Start within a new console"); Console.WriteLine("Press any key to continue ..."); Console.ReadLine(); } FreeConsole(); } } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端