콘솔이 숨겨진 상태에서 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.Out 과 Console.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.