コンソールを非表示にしてC#コンソールアプリケーションを実行する方法


141

コンソールアプリケーションの実行時にコンソールウィンドウを非表示にする方法はありますか?

現在、Windowsフォームアプリケーションを使用してコンソールプロセスを開始していますが、タスクの実行中にコンソールウィンドウを表示したくありません。


スケジュールされたタスクからコンソールアプリケーションを実行してみてください。

回答:


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を使用しました。代わりに、以下を参照してください。
クリスチャン

12
コンソールウィンドウを非表示にしない場合、StartInfo.CreateNoWindow = trueが必要です。
ダニエル

201

コンソールアプリケーションを作成した場合は、デフォルトで非表示にすることができます。

新しいコンソールアプリを作成し、[出力タイプ]タイプを[Windowsアプリケーション]に変更します(プロジェクトプロパティで行います)。


6
私は自分のコンソールを隠そうとしましたが、他のものを呼び出さずに隠しました(受け入れられた回答が想定しているように)-したがって、これは私にとって最高のものでした。ありがとう!
iamserious

6
ありがとう !これも私が探していたものです!
Varun Sharma

3
受け入れられた回答は、質問に記載されているため、それを前提としています。
アクア2013年

最も簡単なのはway..really it..weは確かに私のために...それから、別のプロセスを起動しようとしているbeacuseウィンドウ表示したくない言っています
サイのAvinash

1
これは、ユーザーの資格情報を指定し、そのユーザーが偶然ログインしているか現在のユーザーであるProcessStartInfoの問題を回避します。その場合、CreateNoWindowプロパティは無視されるため、常にコンソールウィンドウが表示されます。コンソールアプリをWindowsアプリケーションに設定し、ウィンドウがない場合、ウィンドウは表示されません。
tjmoore 2015年

67

プロセスクラスを使用している場合は、次のように記述できます。

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

前にyourprocess.start();、プロセスは非表示になります


4
そのプロセスを早期に停止する必要がある場合は、幸運を祈ります。Process.Killが突然終了します。Process.CloseMainWindowが失敗します。GenerateConsoleCtrlEventは、プロセスへのctrl + cまたはctrl + breakの送信に失敗します。プロセス内のすべてのスレッドウィンドウに対するWM_CLOSEは失敗します。これら2つのパラメーター値で開始されたプロセスを完全に終了する方法はないようです。ここで私の質問を参照してください:stackoverflow.com/questions/16139571/...
Triynko

おかげでこれは最も簡単でした。また、コンソールのコード(またはdept)を所有している場合、このミューテックスの例がクリーンシャットダウンの最も簡単な方法であることがわかりました。 stackoverflow.com/a/31586184/1877412
cbuteau 2016年

1
@Triynko:プロセスがアクティブに連携しない限り、プロセスを完全に終了することはできません。これはフラグやその他の問題ではありません。クリーンシャットダウンをトリガーできるものはOSにはありません。ここでの一般的な解決策は、スレーブプロセスが終了する必要があるときに、制御プロセスで通知される待機可能なカーネルオブジェクトを使用することです。スレーブプロセスは、この待機可能なオブジェクトの状態をアクティブに監視し、信号が送られたらクリーンシャットダウンを開始する必要があります。
IInspectable

43

簡単な答えは次のとおりです。コンソールアプリのプロパティ(プロジェクトのプロパティ)に移動します。[アプリケーション]タブで、[出力タイプ]を[Windowsアプリケーション]に変更するだけです。それで全部です。


4
ブルズアイ。これは、フォームを呼び出さないWindowsアプリケーションを作成するのと同じです。
ashes999

1
これが正解です。他の絆創膏のアプローチはありません。これが実際の正しい答えです。アプリケーションが最初からコンソールを開かないようにする必要があります。また、いつでもフォームを開くことができるようにする必要があります。したがって、必要なときにフォームを呼び出すだけです。つまり、ユーザーがシステムトレイアイコンを右クリックして設定を選択すると、フォームが呼び出されます。これは正しい答えです!!!
Bluebaron 2015

20

FreeConsole APIを使用して、プロセスからコンソールを切り離すことができます。

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

(もちろん、これは、コンソールアプリケーションのソースコードにアクセスできる場合にのみ適用されます)


コンソールを見せたくなかった。一方でFreeConsole、その名前が言うん、それが呼び出される前に、コンソールを示すからWindowsを防ぐことはできません。
Jader Dias、2010

5
次に、プロジェクトをコンソールアプリケーションではなくWindowsアプリケーションとしてコンパイルします
Thomas Levesque '19

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

ユーザー入力を必要としないプログラムを作成している場合は、いつでもサービスとして作成できます。サービスはいかなる種類のUIも表示しません。


ただし、タスクスケジューラからそれを呼び出すなどして、終了するまでプロセスを実行するだけの場合、サービスは存在し続けるため不便です。状況によっては、出力タイプをWindowsアプリケーションに変更するのではなく、代わりのProcessWindowStyleを非表示に変更すると非常に便利です。
subsci 2014年

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")] 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;
soulmachine

1

私はあなたが望むものに正確に答えているわけではないことを知っていますが、あなたが正しい質問をしているのかどうか疑問に思っています。

どちらも使用しないのはなぜですか。

  1. Windowsサービス
  2. 新しいスレッドを作成し、その上でプロセスを実行します

プロセスを実行することだけが目的の場合、これらはより良いオプションのように思えます。


3
ユーティリティコンソールアプリケーションの起動が完全に合法であるシナリオはたくさんあります。
アダムロビンソン

私の場合、使用しているソフトウェアが使用しているクライアント/サーバーモデルのため、別のプロセスが必要です。
アーロン・トーマス

新しいスレッドを作成するという問題が常に解決するとは限りません。煩わしいウィンドウをバックグラウンドで表示したくない場合があります。また、ループ内にprocess.startがある場合は、コンソールウィンドウが顔にポップアップ表示されるため、何の作業も行われません。
user890332

1
タスクスケジューラからウィンドウレスユーティリティコンソールアプリを起動します。サービスは必要なく、スレッドをフォークする親プロセスもありません。追加の出力が必要な場合、これらのアプリはEventLogに書き込みます。
subsci 2014年

1

ここで他の回答で「出力タイプ」を「Windowsアプリケーション」に変更できると述べましたが、これはConsole.InNullStreamReaderになるため使用できないことを意味することに注意してください。

Console.OutConsole.Errorしかし、まだ作業罰金に思えます。


2
真剣ですか?Console.In何かを入力するためのコンソールがないときに、なぜ誰かが使用するのですか?どこからアクセスできますConsole.Inか?これはまったく意味がありません。言い換えると、この場合のConsole.Ina は完全に明白で論理的ですNullStreamReader
ロバートS.

1
@RobertS。たぶんパイプ。つまり、別のプログラムの出力です。私がこれを発見したとき、それは私のユースケースでした。
kjbartel 2016

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ボットに対して、これを目に見えないプロセスとして実行します。TopShelfを動作させるよりも簡単でした。他の場所で見つけたコードの助けを借りてこれを書く前に、いくつかのTopShelfチュートリアルが失敗しました。; P

また、Visual Studio>プロジェクト>プロパティ>アプリケーションの設定を変更して、コンソールアプリケーションではなくWindowsアプリケーションとして起動することも試みました。プロジェクトに関する何かが原因で、コンソールを非表示にできませんでした。おそらくDSharpPlusが起動時にコンソールを起動するよう要求しているためです。 。知りません。理由が何であれ、このクラスを使用すると、ポップアップしたコンソールを簡単に強制終了できます。

この魔術師が誰かを助けることを願っています。;)


0

書くだけ

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

psi.CreateNoWindow = true;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.