Konsol gizliyken bir C # konsol uygulaması nasıl çalıştırılır


141

Bir konsol uygulaması yürütürken konsol penceresini gizlemenin bir yolu var mı?

Şu anda bir konsol işlemi başlatmak için bir Windows Forms uygulaması kullanıyorum, ancak görev çalışırken konsol penceresinin görüntülenmesini istemiyorum.


Konsol uygulamasını zamanlanmış görevden çalıştırmayı deneyin.

Yanıtlar:


158

ProcessStartInfoSınıfı kullanıyorsanız, pencere stilini gizli olarak ayarlayabilirsiniz - konsol (GUI değil) uygulamalarında, CreateNoWindow'u şu şekilde ayarlamanız gerekir 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

26
Ben ne
yazacaktım

75
Kutsal bok - Jon'dan daha hızlı biri! =)
Erik Forbes

75
Onu yenmek için internet bağlantısını kısmak zorunda kaldım;)
Adam Markowitz

11
Bir komut satırı aracını çağırmak için çalışmadı. Yourprocess.StartInfo.CreateNoWindow = true; bunun yerine aşağıya bakın.
Christian

12
Konsol penceresini gizlemez, StartInfo.CreateNoWindow = true gerekir.
Daniel

201

Konsol uygulamasını yazdıysanız, uygulamayı varsayılan olarak gizleyebilirsiniz.

Yeni bir konsol uygulaması oluşturun ve ardından "Çıktı Türü" türünü "Windows Uygulaması" olarak değiştirin (proje özelliklerinde yapılır)


6
Kendi konsolumu saklamaya çalışıyordum, başka bir şey çağırmıyordum ve sonra saklıyordum (kabul edilen cevap varsayar) - bu benim için en iyisiydi. Teşekkürler!
iamserious

6
Sağol kanka ! Ben de aradığım şey buydu!
Varun Sharma

3
Kabul edilen cevap, soruda belirtildiği için bunu varsayar.
aqua

en basit şekilde .. gerçekten sevdim ... kesinlikle pencereyi göstermek istemiyoruz çünkü bu benim için başka bir işlem başlatacak çünkü ...
Sai Avinash

1
Bu işlem, kullanıcı kimlik bilgilerini belirttiğiniz ve kullanıcının oturum açmış veya geçerli kullanıcı olduğu ProcessStartInfo ile ilgili sorunları çözer. Bu durumda, her zaman bir konsol penceresi almak için CreateNoWindow özelliği yok sayılır. Konsol uygulamasını Windows uygulamasına ayarlayarak ancak penceresiz olarak pencereniz olmaz.
tjmoore

67

Process Class kullanıyorsanız yazabilirsiniz.

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

önce yourprocess.start();ve işlem gizlenecek


4
Bu süreci erken durdurmanız gerekiyorsa iyi şanslar. Öldürme, aniden sona erer. Process.CloseMainWindow başarısız. GenerateConsoleCtrlEvent, işleme ctrl + c veya ctrl + break gönderemez. WM_CLOSE işlemdeki tüm iş parçacığı pencereleri başarısız. Bu iki parametre değeriyle başlatılan bir işlemi temiz bir şekilde sonlandırmanın bir yolu yok gibi görünüyor. Soruma buradan bakın: stackoverflow.com/questions/16139571/…
Triynko

Teşekkürler ton bu en basit oldu. Ayrıca, konsolun koduna sahipseniz (veya borçluysanız) bu muteks örneğini temiz kapatma için en kolay olarak buldum. stackoverflow.com/a/31586184/1877412
cbuteau

1
@Triynko: Aktif olarak işbirliği yapmadığı sürece hiçbir işlemi temiz bir şekilde sonlandıramazsınız. Bu bir bayrak meselesi ya da başka bir şey değil. İşletim sisteminde temiz bir kapatmayı tetikleyebilecek hiçbir şey yok. Buradaki ortak çözüm, köle sürecinin sona ermesi gerektiğinde, kontrol sürecinde işaret edilen, beklenebilir bir çekirdek nesnesi kullanmaktır. Köle işleminin bu beklenebilir nesnenin durumunu etkin bir şekilde izlemesi ve bir kez sinyal verildiğinde temiz kapatmayı başlatması gerekir.
Tahmin edilemeyen

43

Basit cevap şudur: Konsol uygulamanızın özelliklerine (projenin özellikleri) gidin. "Uygulama" sekmesinde, "Çıktı türü" nü "Windows Uygulaması" olarak değiştirin. Bu kadar.


4
Bullseye. Bu, hiçbir formu çağırmayan bir Windows uygulaması oluşturmakla aynıdır.
ashes999

1
Bu doğru cevap. Diğer bandaid yaklaşımlarınızdan hiçbiri. Bu gerçek SAĞ yanıttır. Uygulamanızın ilk etapta asla bir konsol açmamasını istiyorsunuz. Ayrıca, istediğiniz zaman bir form açabilirsiniz. Yani sadece formu istediğiniz zaman arayın. yani kullanıcı sistem tepsisi simgesini sağ tıklayıp tercihleri ​​seçtiğinde formumuz çağrılır. BU DOĞRU CEVAP!!!
Bluebaron

20

Konsolu işlemden ayırmak için FreeConsole API'sını kullanabilirsiniz :

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

(tabii ki bu yalnızca konsol uygulamasının kaynak koduna erişiminiz varsa geçerlidir)


Konsolu göstermek istemedim. İken FreeConsoleAdından ne diyor, onu çağrılmadan önce konsolu göstermesini Windows'u engellemez.
Jader Dias

5
Ardından projeyi bir Konsol Uygulaması değil, bir Windows Uygulaması olarak derleyin
Thomas Levesque

1
Kayıt için, bu tam olarak ne ben , teşekkürler gerekiyordu. Ayrıca tam olarak başlık ne istiyor :) Yani diğer google
voyagers

3
Buna ek olarak [DllImport("kernel32.dll")] static extern bool AllocConsole();, standart bir Win32 uygulamasından bir konsol ile kolayca çalışmanıza izin verir
sehe

1
.NET Core 2.2 uygulamam için çalışır - herkes bunu özellikle arıyorsa.
Medismal

7

Çıktıyla ilgileniyorsanız, bu işlevi kullanabilirsiniz:

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

Verilen komut satırı programını çalıştırır, bitmesini bekler ve çıktıyı dize olarak döndürür.


4

Kullanıcı girişi gerektirmeyen bir program oluşturuyorsanız, bunu her zaman bir hizmet olarak oluşturabilirsiniz. Bir hizmet herhangi bir kullanıcı arayüzü göstermez.


Ancak tüm yapmak istediğiniz işlem, örneğin Görev Zamanlayıcı'dan çağırarak işlemi tamamlayana kadar çalıştırmaksa, bir hizmet varolmaya devam ettiği için sakıncalıdır. Bazı durumlarda Çıktı Türünü gizli olarak alternatif ProcessWindowStyle'a göre Windows Uygulaması olarak değiştirmek çok uygundur.
subsci

2

DLL dosyasını içe aktarmak için bunu sınıfınıza ekleyin:

[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;

Ve sonra gizlemek istiyorsanız bu komutu kullanın:

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

Ve konsolu göstermek istiyorsanız:

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

1
[DllImport ("user32.dll")] statik extern bool ShowWindow (IntPtr hWnd, int nCmdShow); [DllImport ("kernel32.dll")] statik extern IntPtr GetConsoleWindow (); const int SW_HIDE = 0; const int SW_SHOW = 5;
soulmachine

1

Tam olarak ne istediğini cevaplamadığımı biliyorum, ama doğru soruyu sorup sormadığını merak ediyorum.

Neden ikisini de kullanmıyorsunuz:

  1. windows hizmeti
  2. yeni bir iş parçacığı oluşturun ve işleminizi bu konuda çalıştırın

İstediğiniz tek şey bir işlem yapmaksa, bunlar daha iyi seçeneklere benziyor.


3
Bir yardımcı program konsolu uygulamasını başlatmanın tamamen meşru olduğu birçok senaryo vardır.
Adam Robinson

Benim durumumda, üzerinde çalıştığım yazılımın kullandığı istemci / sunucu modeli nedeniyle ayrı bir işlem gereklidir.
Aaron Thomas

Yeni bir iş parçacığı oluşturmak her zaman sorunu çözmez. Arka planda sinir bozucu pencereyi istemediğiniz zamanlar vardır. Ayrıca, bir işleminiz varsa. Bir döngüde başlayın, o zaman yüzünüzde konsol pencereleri açılırken herhangi bir iş yapmazsınız.
user890332

1
Görev Zamanlayıcı'dan penceresiz yardımcı konsol uygulamaları başlatıyorum. Servise gerek yoktur ve bir ipliğin çatallanacağı ana işlem yoktur. Ek çıktı gerekiyorsa bu uygulamalar EventLog'a yazar.
subsci

1

Buradaki diğer yanıtların söylediği gibi "Çıktı türü" Console.Innü "Windows Uygulaması" olarak değiştirebilirsiniz, ancak bunun bir NullStreamReader olacağı için kullanamayacağınız anlamına geleceğini unutmayın.

Console.Outve Console.Erroryine de iyi çalışıyor gibi görünüyor.


2
Ciddi misin? Bir Console.Inşey girmek için konsol olmadığında neden kimse kullansın ki? Nereden erişilebilir herhangi bir şey gelmelidir Console.In? Bu hiç mantıklı değil. Başka bir deyişle: O tamamen açık ve mantıklı Console.Inbir olduğu NullStreamReaderbu durumda.
Robert S.

1
@RobertS. Belki bir boru. Yani başka bir programın çıktısı. Bunu keşfettiğimde bu benim kullanım durumumdu.
kjbartel

1

Adam Markowitz'in yukarıdaki cevabına dayanarak, aşağıdakiler benim için çalıştı:

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

1

Paylaşmak için genel bir çözümüm var:

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

Bu sınıfı projenize ekleyin ve arayın Magician.DisappearConsole(); .

Programı tıklattığınızda başlattığınızda bir konsol yanıp söner. Komut isteminden yürütülürken, komut istemi yürütmeden kısa bir süre sonra kaybolur.

Bunu, görünmez bir süreç olarak bilgisayarımın arka planında sonsuza dek çalışan bir Discord Bot için yapıyorum. TopShelf'in benim için çalışmasını sağlamaktan daha kolaydı. Ben başka bir yerde buldum kodu bazı yardımı ile yazmadan önce birkaç TopShelf öğreticiler bana başarısız oldu. P

Ayrıca, bir Konsol Uygulaması yerine bir Windows Uygulaması olarak başlatmak için Visual Studio> Proje> Özellikler> Uygulama'daki ayarları değiştirmeyi denedim ve projemle ilgili bir şey bunun konsolumu gizlemesini engelledi - belki de DSharpPlus başlangıçta bir konsol başlatmak istediğinden . Bilmiyorum. Nedeni ne olursa olsun, bu sınıf açıldıktan sonra konsolu kolayca öldürmeme izin veriyor.

Umarım bu Büyücü birine yardım eder. ;)


0

Sadece yaz

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

psi.CreateNoWindow = true;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.