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

时间:2013-10-19 21:46:36

标签: c# console

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

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

3 个答案:

答案 0 :(得分:2)

  

所以在提示

之后,所有控制台输出都显示奇怪

使用AttachConsole()在实践中效果不佳。命令处理器会查看您的.exe文件并执行两项不同的操作,具体取决于它是控制台模式应用程序还是GUI应用程序。如果是控制台模式应用程序,则等待程序退出,然后显示提示。如果它是一个GUI应用程序,那么它等待,它假定程序将显示自己的窗口。

发生了什么,它在启动程序后显示提示并等待输入。您的Console.Write()输出 intermingles 与命令处理器输出。您还会遇到Console.ReadLine()的问题,用户输入的第一行是命令处理器,而不是您。非常困扰用户。

解决方法是以不同方式启动您的程序。你有类型

  start /wait yourapp.exe args...

这使命令处理器等待程序退出,就像控制台模式应用程序一样。

这不太实际,您的应用的用户不会考虑使用start /wait。没有简单的解决方法,你需要使用AllocConsole()。如果这是一个交易破坏者,那么你只需要创建一个控制台应用程序的另一个小EXE项目。通过命令行启动GUI应用程序。如果您为它提供与GUI exe相同的名称但是提供.com文件扩展名,那么它将始终首先被找到。它看起来像这样,适用于任何gui app:

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);
        }
    }
}

答案 1 :(得分:0)

老实说,我也需要这个,并且正在寻找答案并在

中找到了

Show Console in Windows Application?

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;

对于本线程中建议的所有其他内容,这看起来很不错。

答案 2 :(得分:0)

作为参考,这是我的所作所为。我做了一个简单的“无窗口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 + "\"";
}

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

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