繁体   English   中英

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

[英]C# application that can be run from console but does not create a window

我想创建一个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 + "\"";
}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM