Cara menjalankan aplikasi konsol C # dengan konsol tersembunyi

141

Apakah ada cara untuk menyembunyikan jendela konsol saat menjalankan aplikasi konsol?

Saat ini saya menggunakan aplikasi Windows Forms untuk memulai proses konsol, tetapi saya tidak ingin jendela konsol ditampilkan saat tugas sedang berjalan.

Aaron Thomas
sumber
coba jalankan aplikasi konsol dari tugas yang dijadwalkan.

Jawaban:

158

Jika Anda menggunakan ProcessStartInfokelas Anda dapat mengatur gaya jendela untuk disembunyikan - dalam kasus aplikasi konsol (bukan GUI), Anda harus mengatur CreateNoWindow ke 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
Adam Markowitz
sumber
26
Hanya apa yang saya akan posting :)
Jon Skeet
75
Omong kosong - seseorang yang lebih cepat dari Jon! =)
Erik Forbes
75
Saya harus mencekik koneksi internetnya untuk mengalahkannya;)
Adam Markowitz
11
Itu tidak berfungsi untuk memanggil alat baris perintah. Menggunakan proses Anda. MulaiInfo.CreateNoWindow = true; sebagai gantinya, lihat di bawah.
Christian
12
Tidak menyembunyikan jendela konsol, StartInfo.CreateNoWindow = true diperlukan.
Daniel
201

Jika Anda menulis aplikasi konsol, Anda dapat membuatnya tersembunyi secara default.

Buat aplikasi konsol baru kemudian ubah tipe "Jenis Keluaran" menjadi "Aplikasi Windows" (dilakukan di properti proyek)

Simon
sumber
6
Saya mencoba untuk menyembunyikan konsol saya sendiri, tidak memanggil sesuatu yang lain dan kemudian menyembunyikannya (seperti asumsi yang diterima) - jadi ini adalah yang terbaik untuk saya. Terima kasih!
iamserius
6
Terimakasih kawan ! Ini yang saya cari juga!
Varun Sharma
3
Jawaban yang diterima mengasumsikan bahwa karena itu dinyatakan dalam pertanyaan.
aqua
cara paling sederhana..sangat menyukainya..kami tentu saja tidak ingin menunjukkan jendela karena akan meluncurkan proses lain darinya untuk saya ..
Sai Avinash
1
Yang ini mengatasi masalah dengan ProcessStartInfo di mana Anda menentukan kredensial pengguna dan pengguna yang kebetulan masuk atau pengguna saat ini. Dalam situasi itu, properti CreateNoWindow diabaikan sehingga Anda selalu mendapatkan jendela konsol. Dengan mengatur aplikasi konsol ke Aplikasi Windows tetapi tanpa jendela maka Anda tidak mendapatkan jendela.
tjmoore
67

Jika Anda menggunakan Kelas Proses maka Anda dapat menulis

yourprocess.StartInfo.UseShellExecute = false;
yourprocess.StartInfo.CreateNoWindow = true;

sebelum yourprocess.start();dan proses akan disembunyikan

Peter Mortensen
sumber
4
Semoga beruntung jika Anda harus menghentikan proses itu lebih awal. Process.Kill berakhir tiba-tiba. Process.CloseMainWindow gagal. GenerateConsoleCtrlEvent gagal mengirim ctrl + c atau ctrl + break ke proses. WM_CLOSE ke semua jendela utas dalam proses gagal. Tampaknya tidak ada cara untuk mengakhiri proses yang dimulai dengan dua nilai parameter tersebut. Lihat pertanyaan saya di sini: stackoverflow.com/questions/16139571/…
Triynko
Terima kasih banyak, ini yang paling sederhana. Juga jika Anda memiliki (atau dept) kode untuk konsol saya menemukan contoh mutex ini menjadi yang paling mudah untuk shutdown bersih. stackoverflow.com/a/31586184/1877412
cbuteau
1
@Triynko: Anda tidak dapat menghentikan proses apa pun dengan bersih, kecuali jika proses itu secara aktif bekerja sama. Ini bukan masalah bendera atau apa pun. Tidak ada apa-apa di OS yang dapat memicu shutdown yang bersih. Solusi umum di sini adalah dengan menggunakan objek kernel yang ditunggu, yang ditandai dalam proses pengendalian, ketika proses slave harus dihentikan. Proses slave perlu secara aktif memantau keadaan objek yang bisa ditunggu ini, dan memulai shutdown bersih setelah diisyaratkan.
IInspectable
43

Jawaban sederhananya adalah: Buka properti aplikasi konsol Anda (properti proyek). Di tab "Aplikasi", cukup ubah "Jenis keluaran" menjadi "Aplikasi Windows". Itu saja.

Cihan
sumber
4
Tepat sasaran. Ini sama dengan membuat aplikasi Windows yang tidak memanggil formulir apa pun.
ashes999
1
Ini jawaban yang benar. Tak satu pun dari pendekatan bandaid Anda yang lain. Ini adalah jawaban yang BENAR. Anda ingin aplikasi Anda tidak pernah membuka konsol di tempat pertama. Anda juga dapat membuka formulir kapan saja. Jadi, Anda cukup memanggil formulir itu saat Anda inginkan. yaitu formulir kami dipanggil ketika pengguna mengklik kanan ikon baki sistem dan memilih preferensi. INI ADALAH JAWABAN YANG BENAR!!!
Bluebaron
20

Anda dapat menggunakan API FreeConsole untuk melepaskan konsol dari proses:

[DllImport("kernel32.dll")]
static extern bool FreeConsole();

(tentu saja ini hanya berlaku jika Anda memiliki akses ke kode sumber aplikasi konsol)

Thomas Levesque
sumber
Saya ingin tidak menunjukkan konsol. Sementara FreeConsolemelakukan apa yang namanya, itu tidak mencegah Windows menampilkan konsol sebelum dipanggil.
Jader Dias
5
Kemudian kompilasi proyek tersebut sebagai Aplikasi Windows, bukan Aplikasi Konsol
Thomas Levesque
1
Sebagai catatan, ini persis apa yang saya butuhkan, terima kasih. Ini juga persis seperti yang diminta judulnya :) Jadi untuk kepentingan
pelaut
3
Selain itu [DllImport("kernel32.dll")] static extern bool AllocConsole();memungkinkan Anda untuk dengan mudah menjalankan dengan konsol dari aplikasi Win32 standar
lihat
1
Bekerja untuk aplikasi .NET Core 2.2 - jika ada yang mencari ini secara khusus.
Medismal
7

Jika Anda tertarik dengan hasilnya, Anda dapat menggunakan fungsi ini:

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

Itu menjalankan program baris perintah yang diberikan, menunggu untuk menyelesaikan dan mengembalikan output sebagai string.

JCH2k
sumber
4

Jika Anda membuat program yang tidak memerlukan input pengguna, Anda selalu bisa membuatnya sebagai layanan. Layanan tidak akan menampilkan UI apa pun.

Chris Bregg
sumber
Tetapi jika semua yang ingin Anda lakukan adalah menjalankan proses sampai keluar, misalnya dengan memanggilnya dari Penjadwal Tugas, maka layanan tidak nyaman karena terus ada. Dalam beberapa situasi mengubah Jenis Output ke Aplikasi Windows versus ProcessWindowStyle alternatif sebagai tersembunyi sangat nyaman.
subsci
2

Tambahkan ini ke kelas Anda untuk mengimpor file 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;

Dan kemudian jika Anda ingin menyembunyikannya gunakan perintah ini:

 var handle = GetConsoleWindow();
 ShowWindow(handle, SW_HIDE);

Dan jika Anda ingin menampilkan konsol:

var handle = GetConsoleWindow();
ShowWindow(handle, SW_SHOW);
IDK apa saja
sumber
1
[DllImport ("user32.dll")] static extern bool ShowWindow (IntPtr hWnd, int nCmdShow); [DllImport ("kernel32.dll")] extern statis IntPtr GetConsoleWindow (); const int SW_HIDE = 0; const int SW_SHOW = 5;
soulmachine
1

Saya tahu saya tidak menjawab apa yang Anda inginkan, tetapi saya ingin tahu apakah Anda mengajukan pertanyaan yang tepat.

Mengapa tidak Anda gunakan:

  1. layanan windows
  2. buat utas baru dan jalankan proses Anda pada itu

Itu terdengar seperti opsi yang lebih baik jika semua yang Anda inginkan adalah menjalankan proses.

Nathan Koop
sumber
3
Ada banyak skenario di mana meluncurkan aplikasi konsol utilitas sangat sah.
Adam Robinson
Dalam kasus saya, proses yang terpisah diperlukan karena model klien / server yang saya gunakan menggunakan perangkat lunak.
Aaron Thomas
Tidak selalu menyelesaikan masalah untuk membuat utas baru. Ada kalanya Anda tidak ingin jendela yang mengganggu di latar belakang. Juga, bagaimana jika Anda memiliki proses. Mulai dalam satu lingkaran, maka Anda tidak akan mendapatkan pekerjaan yang dilakukan ketika jendela konsol muncul di wajah Anda.
user890332
1
Saya meluncurkan aplikasi konsol utilitas tanpa jendela dari Penjadwal Tugas. Tidak perlu untuk layanan, dan tidak ada proses induk dari mana untuk garpu utas. Aplikasi ini menulis ke EventLog jika diperlukan output tambahan.
subsci
1

Meskipun seperti jawaban lain di sini yang mengatakan Anda dapat mengubah "tipe Output" ke "Aplikasi Windows", perlu diketahui bahwa ini berarti Anda tidak dapat menggunakannya Console.Inkarena akan menjadi NullStreamReader.

Console.Outdan Console.Errortampaknya masih berfungsi dengan baik.

kjbartel
sumber
2
Apakah kamu serius? Mengapa ada orang yang menggunakan Console.Inketika tidak ada konsol untuk memasukkan sesuatu? Dari mana datangnya sesuatu yang bisa diakses melalui Console.In? Ini sama sekali tidak masuk akal. Dengan kata lain: Sangat jelas dan logis bahwa Console.Inini adalah NullStreamReaderdalam kasus ini.
Robert S.
1
@RobertS. Sebuah pipa mungkin. Yaitu output dari program lain. Itu adalah kasus penggunaan saya ketika saya menemukan ini.
kjbartel
1

Berdasarkan jawaban Adam Markowitz di atas, berikut ini berhasil bagi saya:

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();
Volcan Baru
sumber
1

Saya punya solusi umum untuk dibagikan:

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

Cukup sertakan kelas ini dalam proyek Anda, dan hubungi Magician.DisappearConsole();.

Sebuah konsol akan berkedip ketika Anda memulai program dengan mengkliknya. Ketika mengeksekusi dari prompt perintah, prompt perintah menghilang sangat lama setelah eksekusi.

Saya melakukan ini untuk Discord Bot yang berjalan selamanya di latar belakang komputer saya sebagai proses yang tidak terlihat. Itu lebih mudah daripada membuat TopShelf bekerja untuk saya. Beberapa tutorial TopShelf gagal sebelum saya menulis ini dengan bantuan kode yang saya temukan di tempat lain. ; P

Saya juga mencoba mengubah pengaturan di Visual Studio> Proyek> Properti> Aplikasi untuk diluncurkan sebagai Aplikasi Windows, bukan Aplikasi Konsol, dan sesuatu tentang proyek saya mencegah hal ini menyembunyikan konsol saya - mungkin karena DSharpPlus menuntut untuk meluncurkan konsol saat startup . Saya tidak tahu Apa pun alasannya, kelas ini memungkinkan saya untuk dengan mudah membunuh konsol setelah itu muncul.

Semoga Penyihir ini membantu seseorang. ;)

Lucas Jarrett
sumber
0

Cukup tulis

ProcessStartInfo psi= new ProcessStartInfo("cmd.exe");
......

psi.CreateNoWindow = true;
Navin
sumber