มีวิธีซ่อนหน้าต่างคอนโซลเมื่อเรียกใช้แอปพลิเคชันคอนโซลหรือไม่
ขณะนี้ฉันกำลังใช้แอปพลิเคชัน Windows Forms เพื่อเริ่มกระบวนการคอนโซล แต่ฉันไม่ต้องการให้หน้าต่างคอนโซลปรากฏขึ้นในขณะที่งานกำลังทำงานอยู่
มีวิธีซ่อนหน้าต่างคอนโซลเมื่อเรียกใช้แอปพลิเคชันคอนโซลหรือไม่
ขณะนี้ฉันกำลังใช้แอปพลิเคชัน Windows Forms เพื่อเริ่มกระบวนการคอนโซล แต่ฉันไม่ต้องการให้หน้าต่างคอนโซลปรากฏขึ้นในขณะที่งานกำลังทำงานอยู่
คำตอบ:
หากคุณใช้ProcessStartInfo
คลาสที่คุณสามารถตั้งค่าลักษณะหน้าต่างเป็นซ่อน - ในกรณีของแอปพลิเคชันคอนโซล (ไม่ใช่ GUI) คุณต้องตั้งค่า CreateNoWindow เป็นtrue
:
System.Diagnostics.ProcessStartInfo start =
new System.Diagnostics.ProcessStartInfo();
start.FileName = dir + @"\Myprocesstostart.exe";
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; //Hides GUI
start.CreateNoWindow = true; //Hides console
หากคุณเขียนแอปพลิเคชันคอนโซลคุณสามารถซ่อนมันเป็นค่าเริ่มต้น
สร้างแอปคอนโซลใหม่จากนั้นเปลี่ยนประเภท "ประเภทเอาท์พุท" เป็น "แอปพลิเคชัน Windows" (ทำในคุณสมบัติโครงการ)
หากคุณกำลังใช้คลาสประมวลผลคุณสามารถเขียนได้
yourprocess.StartInfo.UseShellExecute = false;
yourprocess.StartInfo.CreateNoWindow = true;
ก่อนyourprocess.start();
และกระบวนการจะถูกซ่อนไว้
คำตอบง่ายๆคือ: ไปที่คุณสมบัติของแอปคอนโซล (คุณสมบัติของโครงการ) ในแท็บ "แอปพลิเคชัน" เพียงแค่เปลี่ยน "ประเภทเอาท์พุท" เป็น "แอปพลิเคชัน Windows" นั่นคือทั้งหมดที่
คุณสามารถใช้FreeConsole API เพื่อแยกคอนโซลออกจากกระบวนการ:
[DllImport("kernel32.dll")]
static extern bool FreeConsole();
(แน่นอนว่าสิ่งนี้ใช้ได้เฉพาะเมื่อคุณมีสิทธิ์เข้าถึงซอร์สโค้ดของแอปพลิเคชันคอนโซล)
FreeConsole
ที่ชื่อของมันบอกว่ามันไม่ได้ป้องกัน Windows จากการแสดงคอนโซลก่อนที่มันจะถูกเรียก
[DllImport("kernel32.dll")] static extern bool AllocConsole();
จะช่วยให้คุณทำงานได้อย่างง่ายดายกับคอนโซลจากมาตรฐาน Win32 โปรแกรม
หากคุณสนใจในผลลัพธ์คุณสามารถใช้ฟังก์ชันนี้:
private static string ExecCommand(string filename, string arguments)
{
Process process = new Process();
ProcessStartInfo psi = new ProcessStartInfo(filename);
psi.Arguments = arguments;
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
process.StartInfo = psi;
StringBuilder output = new StringBuilder();
process.OutputDataReceived += (sender, e) => { output.AppendLine(e.Data); };
process.ErrorDataReceived += (sender, e) => { output.AppendLine(e.Data); };
// run the process
process.Start();
// start reading output to events
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// wait for process to exit
process.WaitForExit();
if (process.ExitCode != 0)
throw new Exception("Command " + psi.FileName + " returned exit code " + process.ExitCode);
return output.ToString();
}
มันรันโปรแกรมบรรทัดคำสั่งที่กำหนดรอให้มันเสร็จสิ้นและส่งออกเป็นสตริง
หากคุณกำลังสร้างโปรแกรมที่ไม่ต้องการการป้อนข้อมูลจากผู้ใช้คุณสามารถสร้างมันเป็นบริการได้เสมอ บริการจะไม่แสดง UI ประเภทใด
เพิ่มลงในคลาสของคุณเพื่อนำเข้าไฟล์ DLL:
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
const int SW_HIDE = 0;
const int SW_SHOW = 5;
และถ้าคุณต้องการซ่อนมันให้ใช้คำสั่งนี้:
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE);
และถ้าคุณต้องการแสดงคอนโซล:
var handle = GetConsoleWindow();
ShowWindow(handle, SW_SHOW);
ฉันรู้ว่าฉันไม่ตอบสิ่งที่คุณต้องการอย่างแน่นอน แต่ฉันสงสัยว่าคุณกำลังถามคำถามที่ถูกต้องหรือไม่
ทำไมคุณไม่ใช้อย่างใดอย่างหนึ่ง:
เสียงเหล่านั้นเหมือนตัวเลือกที่ดีกว่าหากคุณต้องการเรียกใช้กระบวนการ
แม้ว่าตามคำตอบอื่น ๆ ที่นี่บอกว่าคุณสามารถเปลี่ยน "ประเภทงานพิมพ์" เป็น "แอปพลิเคชัน Windows" ได้โปรดระวังว่านี่จะหมายความว่าคุณไม่สามารถใช้งานConsole.In
ได้เพราะจะกลายเป็น NullStreamReader
Console.Out
และConsole.Error
ดูเหมือนว่าจะยังคงทำงานได้ดี
Console.In
เมื่อไม่มีคอนโซลในการป้อนข้อมูลบางอย่าง ที่อะไรควรมาจากที่สามารถเข้าถึงได้ผ่านทางConsole.In
? มันไม่สมเหตุสมผลเลย กล่าวอีกนัยหนึ่ง: มันชัดเจนและมีเหตุผลซึ่งConsole.In
เป็นNullStreamReader
ในกรณีนี้
จากคำตอบของ Adam Markowitz ด้านบนใช้งานได้สำหรับฉัน:
process = new Process();
process.StartInfo = new ProcessStartInfo("cmd.exe", "/k \"" + CmdFilePath + "\"");
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
//process.StartInfo.UseShellExecute = false;
//process.StartInfo.CreateNoWindow = true;
process.Start();
ฉันมีวิธีทั่วไปในการแบ่งปัน:
using System;
using System.Runtime.InteropServices;
namespace WhateverNamepaceYouAreUsing
{
class Magician
{
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int HIDE = 0;
const int SHOW = 5;
public static void DisappearConsole()
{
ShowWindow(GetConsoleWindow(), HIDE);
}
}
}
Magician.DisappearConsole();
มีเพียงชั้นนี้ในโครงการของคุณและโทร
คอนโซลจะกระพริบเมื่อคุณเริ่มโปรแกรมโดยคลิกที่มัน เมื่อดำเนินการจากพรอมต์คำสั่งพรอมต์คำสั่งจะหายไปไม่นานหลังจากการดำเนินการ
ฉันทำสิ่งนี้เพื่อ Discord Bot ที่ทำงานตลอดไปในพื้นหลังของคอมพิวเตอร์ของฉันเป็นกระบวนการที่มองไม่เห็น มันง่ายกว่าการให้ TopShelf ทำงานให้ฉัน บทเรียน TopShelf คู่ล้มเหลวฉันก่อนที่ฉันจะเขียนด้วยความช่วยเหลือจากรหัสที่ฉันพบที่อื่น ; P
ฉันพยายามเปลี่ยนการตั้งค่าใน Visual Studio> โครงการ> คุณสมบัติ> แอปพลิเคชันเพื่อเปิดใช้เป็นแอปพลิเคชัน Windows แทนคอนโซลแอปพลิเคชันและบางสิ่งเกี่ยวกับโครงการของฉันทำให้ไม่สามารถซ่อนคอนโซลได้ - อาจเป็นเพราะ DSharpPlus ต้องการเปิดคอนโซล . ฉันไม่รู้ ไม่ว่าด้วยเหตุผลใดคลาสนี้ให้ฉันฆ่าคอนโซลได้ง่ายหลังจากที่มันโผล่ขึ้นมา
หวังว่านักเวทย์คนนี้จะช่วยใครซักคน ;)
แค่เขียน
ProcessStartInfo psi= new ProcessStartInfo("cmd.exe");
......
psi.CreateNoWindow = true;