Як запустити консольну програму C # із прихованою консоллю


141

Чи є спосіб приховати вікно консолі під час виконання консольного додатка?

Наразі я використовую програму Windows Forms для запуску консольного процесу, але я не хочу, щоб вікно консолі відображалось під час виконання завдання.


спробуйте запустити консольний додаток із запланованого завдання.

Відповіді:


158

Якщо ви використовуєте 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

26
Якраз те, що я збирався опублікувати :)
Джон Скіт

75
Святе лайно - хтось швидший за Йона! =)
Ерік Форбс

75
Мені довелося заглушити його інтернет-зв’язок, щоб його перемогти;)
Адам Марковіц

11
Не вдалося викликати інструмент командного рядка. Використовується yourprocess.StartInfo.CreateNoWindow = true; замість цього див. нижче.
Крістіан

12
Не приховує вікно консолі, StartInfo.CreateNoWindow = true потрібно.
Даніель

201

Якщо ви написали консольну програму, ви можете зробити її прихованою за замовчуванням.

Створіть нову консольну програму, а потім змініть тип "Тип виводу" на "Додаток Windows" (зроблено у властивостях проекту)


6
Я намагався приховати власну консоль, не називати щось інше, а потім приховати це (як передбачає прийнята відповідь) - тож це було найкращим для мене. Дякую!
примхливий

6
Дякую друже ! Це я теж шукав!
Варун Шарма

3
Прийнята відповідь передбачає, що оскільки це зазначено у запитанні.
аква

найпростіший спосіб .. дійсно сподобалося .. ми, звичайно, не хочемо показувати вікно, тому що він збирається запустити для нього ще один процес ..
Сай Авінаш

1
Це вирішує проблеми з ProcessStartInfo, де ви вказуєте облікові дані користувачів, і цей користувач увійшов або поточний користувач. У цій ситуації властивість CreateNoWindow ігнорується, тому ви завжди отримуєте вікно консолі. Встановивши консольний додаток на програму Windows, але без вікна, ви не отримаєте вікна.
tjmoore

67

Якщо ви використовуєте Process Class, то можете писати

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

раніше yourprocess.start();і процес буде приховано


4
Удачі, якщо вам доведеться рано зупинити цей процес. Process.Kill припиняється різко. Збій Process.CloseMainWindow. GenerateConsoleCtrlEvent не вдається надіслати ctrl + c або ctrl + перерву в процес. WM_CLOSE для всіх вікон потоку в процесі виходить з ладу. Здається, немає способу чітко закінчити процес, розпочатий із цих двох значень параметрів. Дивіться моє запитання тут: stackoverflow.com/questions/16139571 / ...
Triynko

Спасибі тонн це було найпростіше. Крім того, якщо ви володієте (або депт) кодом консолі, я вважав, що цей мутексний приклад є найпростішим для чистого відключення. stackoverflow.com/a/31586184/1877412
cbuteau

1
@Triynko: Ви не можете чітко припинити жоден процес, якщо цей процес активно не співпрацює. Це не питання прапорів чи чогось іншого. В ОС просто немає нічого, що могло б викликати чисте відключення. Поширене рішення тут полягає у використанні об'єкта ядра, що чекає, про що сигналізує в процесі управління, коли підлеглий процес повинен завершитися. Підлеглий процес повинен активно контролювати стан цього очікуваного об'єкта та ініціювати чисте відключення, коли про нього подано сигнал.
Неочікуваний

43

Проста відповідь полягає в тому, що: Перейдіть до властивостей додатка консолі (властивості проекту). На вкладці "Програма" просто змініть "Тип виходу" на "Додаток Windows". Це все.


4
Bullseye. Це те саме, що створити програму Windows, яка не викликає жодної форми.
ashes999

1
Це правильна відповідь. Ніхто з інших ваших бандаїдних підходів. Це фактична ПРАВА відповідь. Ви хочете, щоб ваша програма ніколи не відкривала консоль. Також ви хочете мати можливість відкрити форму в будь-який час. Тож ви просто зателефонуйте до форми, коли захочете. тобто наша форма викликається, коли користувач правою кнопкою миші натискає на піктограму системного лотка і вибирає налаштування. ЦЕ ПРАВА ВІДПОВІДЬ !!!
Bluebaron

20

Ви можете використовувати API FreeConsole для від'єднання консолі від процесу:

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

(звичайно, це застосовується лише в тому випадку, якщо у вас є доступ до вихідного коду програми консолі)


Я хотів не показувати консоль. Хоча FreeConsoleте, що говорить його назва, це не заважає Windows показувати консоль, перш ніж її викликати.
Джадер Діас

5
Потім складіть проект як додаток для Windows, а не консольний додаток
Thomas Levesque

1
Для запису, це саме те, що мені було потрібно, дякую. Це також саме те, про що йдеться в заголовку :) Тож в інтересах інших
гулячів

3
Крім того [DllImport("kernel32.dll")] static extern bool AllocConsole();дозволяє легко працювати з консоллю від стандартного Win32 додатка
sehe

1
Працює для мого додатка .NET Core 2.2 - якщо хтось шукає саме це.
Medismal

7

Якщо вас цікавить результат, ви можете скористатися цією функцією:

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

Він запускає задану програму командного рядка, чекає її завершення і повертає результат у вигляді рядка.


4

Якщо ви створюєте програму, яка не потребує введення користувача, ви завжди можете просто створити її як службу. Послуга не відображатиме ніякого інтерфейсу користувача.


Але якщо все, що ви хочете зробити, це запустити процес, поки він не завершиться, наприклад, зателефонувавши до нього із планувальника завдань, послуга незручна, оскільки вона продовжує існувати. У деяких ситуаціях дуже зручно змінити тип виводу на додаток Windows проти альтернативного ProcessWindowStyle як прихованого.
subsci

2

Додайте це до свого класу, щоб імпортувати файл 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);

1
[DllImport ("user32.dll")] статичне зовнішнє bool ShowWindow (IntPtr hWnd, int nCmdShow); [DllImport ("kernel32.dll")] статичний зовнішній IntPtr GetConsoleWindow (); const int SW_HIDE = 0; const int SW_SHOW = 5;
соулмашина

1

Я знаю, що я не відповідаю саме того, що ви хочете, але мені цікаво, чи правильно ви ставите запитання.

Чому ви не скористаєтесь жодним із них:

  1. сервіс Windows
  2. створіть новий потік і запустіть свій процес на цьому

Вони звучать як кращі варіанти, якщо все, що ви хочете, - це запустити процес.


3
Існує безліч сценаріїв, коли запуск програми утилітної консолі є цілком законним.
Адам Робінсон

У моєму випадку окремий процес необхідний через модель клієнт / сервер, яку використовує програмне забезпечення, над яким я працюю.
Аарон Томас

Це не завжди вирішує проблему, щоб створити новий потік. Бувають випадки, коли просто не хочеться дратувати вікно у фоновому режимі. Крім того, що робити, якщо у вас цикл process.start в циклі, ви не виконаєте жодної роботи, коли вікна консолі спливуть вам в обличчя.
user890332

1
Я запускаю програми, що не мають віконних консольних програм із Планувальник завдань. Немає необхідності в обслуговуванні та жодного батьківського процесу, з якого слід роздвоєти нитку. Ці додатки записують у EventLog, якщо потрібен додатковий вихід.
subsci

1

Хоча, як і інші відповіді тут говорили, що ви можете змінити "тип виводу" на "Додаток Windows", майте на увазі, що це означає, що ви не можете використовувати, Console.Inоскільки він стане NullStreamReader.

Console.Outале, Console.Errorздається, все ще добре працює, однак.


2
Ти серйозно? Навіщо комусь користуватися, Console.Inколи немає консолі, щоб щось ввести? Звідки що-небудь з цього може бути доступним Console.In? Це взагалі не має сенсу. Іншими словами: Цілком очевидно і логічно, що Console.Inє NullStreamReaderсправою в цьому випадку.
Роберт С.

1
@RobertS. Можливо, труба. Тобто вихід іншої програми. Це був мій випадок використання, коли я виявив це.
kjbartel

1

Спираючись на вищезгадану відповідь Адама Марковіца, для мене працювало наступне:

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

У мене є загальне рішення поділитися:

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

При запуску програми консоль спалахне, натиснувши на неї. При виконанні командного рядка командний рядок зникає дуже скоро після виконання.

Я роблю це для бота розбрату, який вічно працює на тлі мого комп’ютера як невидимий процес. Це було простіше, ніж змусити TopShelf працювати на мене. Кілька навчальних посібників з TopShelf провалили мене, перш ніж я написав це за допомогою допомоги з коду, який я знайшов в іншому місці. ; P

Я також спробував просто змінити налаштування в Visual Studio> Project> Properties> Application для запуску як додатка Windows замість консольного додатка, і щось про мій проект заважало цьому приховувати консоль - можливо, тому що DSharpPlus вимагає запустити консоль при запуску. . Не знаю. Незалежно від причини, цей клас дозволяє мені легко вбити консоль після того, як вона спливе.

Сподіваюся, цей фокусник комусь допомагає. ;)


0

Просто напишіть

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

psi.CreateNoWindow = true;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.