可以从控制台运行但不创建窗口的 C# 应用程序
本文关键字:窗口 创建 应用程序 控制台 运行 | 更新日期: 2023-09-27 18:36:16
我想创建一个 C# 应用程序,当您从控制台窗口运行时,它的行为类似于控制台应用程序(并且可以将文本输出到控制台),但在外部运行时不会创建控制台窗口。我做了一些研究,通常的建议是创建一个 C# 控制台应用程序,然后将其项目类型更改为 Windows 应用程序。但是,这会阻止在从控制台运行时写入 Console.WriteLine 消息。
有没有办法运行这样的程序?我不需要它来接受任何控制台输入。也许我可以使用其他方法在从控制台运行时显示文本?
所以所有控制台输出在提示后都奇怪地显示
使用 AttachConsole() 在实践中效果不佳。 命令处理器会查看您的.exe文件并执行两种不同的操作,具体取决于它是控制台模式应用还是 GUI 应用。 如果是控制台模式应用程序,则等待程序退出,然后显示提示。 如果它是一个GUI应用程序,那么它不会等待,它假设程序将显示自己的窗口。
这就是发生的事情,它在启动程序后显示提示并等待输入。 您的 Console.Write() 输出现在与命令处理器输出混合在一起。 您还将遇到 Console.ReadLine() 问题,这是用户键入的第一行转到命令处理器,而不是您。 极大地迷惑了用户。
解决方法是以不同的方式启动程序。 你有类型
start /wait yourapp.exe args...
这会使命令处理器等待程序退出,就像控制台模式应用一样。
这不是很实用,您的应用程序的用户不会想到使用start /wait
。 没有简单的解决方法,您需要使用AllocConsole()。 如果这是一个交易破坏者,那么你只需要创建一个控制台应用程序的小 EXE 项目。 这将启动您的 GUI 应用程序,传递命令行。 如果您为其指定与GUI exe相同的名称,但提供.com
文件扩展名,则始终首先找到它。 它可以看起来像这样,适用于任何 gui 应用程序:
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
class Program {
static void Main(string[] args) {
try {
var path = Assembly.GetExecutingAssembly().Location;
var dir = Path.GetDirectoryName(path);
var file = Path.GetFileNameWithoutExtension(path);
path = Path.Combine(dir, file + ".exe");
var prc = Process.Start(path, Environment.CommandLine);
if (args.Length > 0) prc.WaitForExit();
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
Environment.Exit(1);
}
}
}
老实说,我也需要这个,正在寻找答案,并在
在 Windows 应用程序中显示控制台?
public static void ShowConsoleWindow()
{
var handle = GetConsoleWindow();
if (handle == IntPtr.Zero)
{
AllocConsole();
}
else
{
ShowWindow(handle, SW_SHOW);
}
}
public static void HideConsoleWindow()
{
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE);
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AllocConsole();
[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;
对于此线程中建议的所有其他解决方案,这似乎是一个很好的解决方案。
作为参考,这是我所做的。我做了一个简单的"无窗口CLI"可执行文件。我创建了一个新的控制台应用程序,将其更改为Windows应用程序并传递了参数:
static void Main(string[] args)
{
string programFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string passArguments = string.Join(" ", args.Select(WrapArgument));
Process.Start(new ProcessStartInfo(Path.Combine(programFolder, "VidCoderCLI.exe"))
{
Arguments = passArguments,
WindowStyle = ProcessWindowStyle.Hidden
});
}
private static string WrapArgument(string arg)
{
if (arg.EndsWith(@"'"))
{
return "'"" + arg + "'''"";
}
return "'"" + arg + "'"";
}
任何需要在没有窗口显示的情况下拨打电话的东西都会通过那里。这很好,因为我避免处理输出重定向和控制台恶作剧。
虽然从技术上讲这不是我问的,所以我不会接受这个答案。