[英]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);
}
}
}
老实说,我也需要这个,并且正在寻找答案,并发现了这一点
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.