可以从控制台运行但不创建窗口的 C# 应用程序

本文关键字:窗口 创建 应用程序 控制台 运行 | 更新日期: 2023-09-27 18:36:16

我想创建一个 C# 应用程序,当您从控制台窗口运行时,它的行为类似于控制台应用程序(并且可以将文本输出到控制台),但在外部运行时不会创建控制台窗口。我做了一些研究,通常的建议是创建一个 C# 控制台应用程序,然后将其项目类型更改为 Windows 应用程序。但是,这会阻止在从控制台运行时写入 Console.WriteLine 消息。

有没有办法运行这样的程序?我不需要它来接受任何控制台输入。也许我可以使用其他方法在从控制台运行时显示文本?

可以从控制台运行但不创建窗口的 C# 应用程序

所以所有控制台输出在提示后都奇怪地显示

使用 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 + "'"";
}

任何需要在没有窗口显示的情况下拨打电话的东西都会通过那里。这很好,因为我避免处理输出重定向和控制台恶作剧。

虽然从技术上讲这不是我问的,所以我不会接受这个答案。