콘솔이 숨겨진 상태에서 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
내가 게시하려고하는 것 :)
Jon Skeet

75
거룩한 쓰레기-존보다 빠른 사람! =)
Erik Forbes

75
그를 이기기 위해 그의 인터넷 연결을 조절해야했다;)
Adam Markowitz

11
명령 행 도구를 호출 할 때는 작동하지 않았습니다. 사용 된 yourprocess.StartInfo.CreateNoWindow = true; 대신 아래를 참조하십시오.
Christian

12
콘솔 창을 숨기지 않고 StartInfo.CreateNoWindow = true가 필요합니다.
Daniel

201

콘솔 응용 프로그램을 작성한 경우 기본적으로 숨길 수 있습니다.

새 콘솔 앱을 만든 다음 "출력 유형"유형을 "Windows 응용 프로그램"(프로젝트 속성에서 완료)으로 변경하십시오.


6
나는 내 자신의 콘솔을 숨기려고했지만 다른 것을 부르지 않고 숨겼습니다. 감사!
iamserious

6
고마워 친구 ! 이것도 내가 찾던 것입니다!
Varun Sharma

3
허용 된 답변은 질문에 명시되어 있기 때문에 가정합니다.
아쿠아

가장 간단한 방법 .. 정말 좋아했습니다 .. 우리는 확실히 그것이 나를 위해 다른 프로세스를 시작하려고 창을 보여주고 싶지 않습니다 ..
Sai Avinash

1
이것은 사용자 자격 증명을 지정하고 해당 사용자가 로그인하거나 현재 사용자가되는 ProcessStartInfo 관련 문제를 해결합니다. 이 경우 CreateNoWindow 속성이 무시되므로 항상 콘솔 창을 얻을 수 있습니다. 콘솔 응용 프로그램을 창없이 Windows 응용 프로그램으로 설정하면 창이 없습니다.
tjmoore

67

Process Class를 사용하는 경우 다음을 작성할 수 있습니다.

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

전에 yourprocess.start();프로세스가 숨겨집니다


4
프로세스를 일찍 중지해야한다면 행운을 빈다. 프로세스가 갑자기 종료됩니다. Process.CloseMainWindow가 실패합니다. GenerateConsoleCtrlEvent가 프로세스에 ctrl + c 또는 ctrl + break를 보내지 못했습니다. 프로세스의 모든 스레드 창에 대한 WM_CLOSE가 실패합니다. 이 두 매개 변수 값으로 시작한 프로세스를 완전히 끝내는 방법이없는 것 같습니다. 여기 내 질문을 참조하십시오 : stackoverflow.com/questions/16139571/…
Triynko

덕분에 이것이 가장 간단했습니다. 또한 콘솔 코드를 소유하거나 (또는 ​​부서) 있다면이 뮤텍스 예제가 깨끗한 종료에 가장 쉬운 것으로 나타났습니다. stackoverflow.com/a/31586184/1877412
cbuteau

1
@Triynko : 프로세스가 적극적으로 협력하지 않으면 프로세스를 완전히 종료 할 수 없습니다. 이것은 플래그 나 다른 문제가 아닙니다. OS에는 클린 셧다운을 유발할 수있는 것은 없습니다. 여기서 일반적인 해결책은 슬레이브 프로세스가 종료되어야 할 때 제어 프로세스에서 신호를 기다리는 대기 가능한 커널 객체를 사용하는 것입니다. 슬레이브 프로세스는이 대기 가능 객체의 상태를 능동적으로 모니터링하고 신호가 전달되면 완전히 종료해야합니다.
IInspectable

43

콘솔 응용 프로그램의 속성 (프로젝트 속성)으로 이동하십시오. "응용 프로그램"탭에서 "출력 유형"을 "Windows 응용 프로그램"으로 변경하십시오. 그게 다야.


4
황소의 눈. 이것은 폼을 호출하지 않는 Windows 응용 프로그램을 만드는 것과 같습니다.
ashes999

1
이것이 정답입니다. 다른 반창고 접근 방식은 없습니다. 이것이 실제 정답입니다. 애플리케이션이 콘솔을 절대로 열지 않기를 원합니다. 또한 언제든지 양식을 열 수 있기를 원합니다. 원할 때 양식을 호출하면됩니다. 즉, 사용자가 시스템 트레이 아이콘을 마우스 오른쪽 버튼으로 클릭하고 환경 설정을 선택하면 양식이 호출됩니다. 이것은 올바른 답변입니다 !!!
Bluebaron

20

FreeConsole을 사용할 수 있습니다 API를 하여 프로세스에서 콘솔을 분리 .

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

(물론 이것은 콘솔 응용 프로그램의 소스 코드에 액세스 할 수있는 경우에만 적용 가능합니다)


나는 콘솔을 보여주고 싶지 않았다. 하지만 FreeConsole그 이름이 말하는 않습니다, 그것은 호출하기 전에 콘솔을 보여주는에서 Windows를 방지하지 않습니다.
Jader Dias

5
그런 다음 콘솔 응용 프로그램이 아닌 Windows 응용 프로그램으로 프로젝트를 컴파일하십시오.
Thomas Levesque

1
기록을 위해, 이것은 정확히 내가 필요한 것입니다. 감사합니다. 그것은 또한 정확하게 제목을 위해 :) 요구하시는 그래서 한 다른 구글 항해자의 관심에서
sehe

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

사용자 입력이 필요없는 프로그램을 만드는 경우 항상 서비스로 만들 수 있습니다. 서비스에는 어떤 종류의 UI도 표시되지 않습니다.


그러나 작업 스케줄러에서 프로세스를 호출하여 프로세스가 종료 될 때까지 프로세스를 실행하면 서비스가 계속 존재하기 때문에 불편합니다. 경우에 따라 출력 유형을 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")] 정적 extern bool ShowWindow (IntPtr hWnd, int nCmdShow); [DllImport ( "kernel32.dll")] 정적 extern IntPtr GetConsoleWindow (); const int SW_HIDE = 0; const int SW_SHOW = 5;
soulmachine

1

나는 당신이 원하는 것에 정확히 대답하지는 않는다는 것을 알고 있지만, 당신이 올바른 질문을하고 있는지 궁금합니다.

왜 다음 중 하나를 사용하지 않습니까?

  1. 윈도우 서비스
  2. 새로운 스레드를 생성하고 프로세스를 실행하십시오.

원하는 것은 프로세스를 실행하는 것보다 더 나은 옵션처럼 들립니다.


3
유틸리티 콘솔 응용 프로그램을 시작하는 것이 합법적 인 많은 시나리오가 있습니다.
Adam Robinson

필자의 경우 작업중 인 소프트웨어가 사용하는 클라이언트 / 서버 모델로 인해 별도의 프로세스가 필요합니다.
Aaron Thomas

새 스레드를 작성하는 데 항상 문제점이 해결되는 것은 아닙니다. 백그라운드에서 성가신 창을 원하지 않는 경우가 있습니다. 또한 루프에서 process.start를 시작하면 콘솔 창이 팝업으로 표시되어 아무런 작업도 수행하지 않습니다.
user890332

1
작업 스케줄러에서 창없는 유틸리티 콘솔 앱을 시작합니다. 서비스가 필요하지 않으며 스레드를 포크하는 상위 프로세스가 없습니다. 이러한 앱은 추가 출력이 필요한 경우 EventLog에 씁니다.
subsci

1

여기의 다른 답변에서 "출력 유형"을 "Windows 응용 프로그램"으로 변경할 수 있다고 말했지만 Console.InNullStreamReader가되므로 사용할 수 없음을 의미합니다 .

Console.OutConsole.Error 그러나 여전히 잘 작동 것 같다.


2
진심 이세요? Console.In무언가를 입력 할 콘솔이 없을 때 왜 누군가가 사용 합니까? 를 통해 액세스 할 수있는 곳은 어디 Console.In입니까? 이것은 전혀 의미가 없습니다. 다시 말해 ,이 경우에 Console.In있어서는 완전히 명백하고 논리적입니다 NullStreamReader.
Robert S.

1
@RobertS. 파이프 일 수도 있습니다. 즉 다른 프로그램의 출력입니다. 이것이 내가 이것을 발견했을 때의 유스 케이스였습니다.
kjbartel

1

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

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

프로그램을 클릭하면 콘솔이 깜박입니다. 명령 프롬프트에서 실행할 때 명령 프롬프트는 실행 직후에 사라집니다.

내 컴퓨터의 배경에서 보이지 않는 프로세스로 영원히 실행되는 Discord Bot에 대해이 작업을 수행합니다. TopShelf가 나를 위해 일하는 것보다 쉬웠습니다. 다른 곳에서 찾은 코드의 도움으로 이것을 작성하기 전에 몇 가지 TopShelf 튜토리얼이 실패했습니다. ;피

또한 콘솔 응용 프로그램 대신 Windows 응용 프로그램으로 시작되도록 Visual Studio> 프로젝트> 속성> 응용 프로그램의 설정을 변경하려고 시도했지만 프로젝트에 대한 내 콘솔로 인해 콘솔이 숨겨지지 않습니다. . 모르겠어요 이유가 무엇이든,이 클래스를 사용하면 콘솔이 팝업 된 후 콘솔을 쉽게 죽일 수 있습니다.

이 마술사가 누군가를 돕기를 바랍니다. ;)


0

그냥 써

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

psi.CreateNoWindow = true;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.