関連:
アプリケーションにコマンド ライン モードを含める必要がありますか?
親プロセスの標準出力を取得するには?
コンソール アプリケーションは、エクスプローラーから実行されたかどうかを検出できますか?
通常はコマンド ラインから実行されるコンソール アプリを作成したいと考えています。
ただし、(cmd.exe プロンプトから実行するのではなく) Explorer 内からダブルクリックすると、プログラムがコンソール ウィンドウを表示しないようにします。
私はこれを避けたい:
出来ますか?
編集私はそれを尋ねる別の方法だと思います.プログラムがどのように呼び出されたかを知ることは可能ですか?ダブルクリックまたはコマンドラインによって?
私は Windows の .NET で作業しています。
編集 2:このOld New Thing のブログ投稿から、いくつかの良いことを学びました。これが私が今知っていることです...
Windows では、EXE ファイルは GUI または非 GUI としてマークされます。csc.exe では、 または で選択し/target:winexe
ます/target:exe
。プロセスの最初の命令が実行される前に、Windows カーネルは実行環境をセットアップします。その時点で、EXE が GUI とマークされている場合、カーネルはプロセスの stdin/stdout を NULL に設定し、非 GUI (コマンドライン) の場合、カーネルはコンソールを作成し、プロセスの stdin/stdout をそれに設定します。コンソール。
プロセスの起動時に stdin/stdout (== /target:winexe
) がない場合、呼び出しはすぐに戻ります。そのため、cmd.exe から GUI アプリを起動すると、すぐに cmd プロンプトが返されます。stdin/stdout があり、cmd.exe から実行されている場合、親の cmd.exe はプロセスの終了を待ちます。
親のコンソールにアタッチするように GUI アプリをコーディングすると、console.writeline などを実行できるようになるため、「即時復帰」は重要です。ただし、cmd.exe プロンプトはアクティブです。ユーザーは、新しいコマンドを入力したり、新しいプロセスを開始したりできます。つまり、winexe から親コンソールにアタッチするだけではAttachConsole(-1)
、コンソール アプリに「変換」されません。
この時点で、アプリが cmd.exe から呼び出された場合にコンソールを使用できるようにし、ダブルクリックされた場合にコンソールを使用できないようにする唯一の方法は、exe を通常のコンソール exe ( /target:exe
)として定義することだと思います。必要に応じて、起動時にウィンドウを非表示にします。コンソール ウィンドウが短時間表示されます。
エクスプローラーから起動されたのかcmd.exeから起動されたのかはまだわかりませんが、近づいています..
答え
コンソール ウィンドウを表示しないコンソール アプリをビルドすることはできません。
ウィンドウを非常にすばやく非表示にするコンソール アプリを作成することは可能ですが、ウィンドウがまったく表示されないかのようにすばやくではありません。
ここで、コンソール アプリがエクスプローラーから起動されたかどうかを判断するために、実行されているコンソールを確認することを提案する人もいます
( mgb の回答およびKB 記事 99115 から)。
int left = Console.CursorLeft;
int top = Console.CursorTop;
bool ProcessWasRunFromExplorer = (left==0 && top==0);
これは、プロセスが独自のコンソールで起動されたかどうかを示しますが、エクスプローラーであったかどうかは示しません。エクスプローラーでダブルクリックするとこれが実行されますが、アプリ内から Start.Process() を実行しても同じことが実行されます。
これらの状況を別の方法で扱いたい場合は、これを使用して親プロセスの名前を学習します。
System.Console.WriteLine("Process id: {0}", Process.GetCurrentProcess().Id);
string name = Process.GetCurrentProcess().ProcessName ;
System.Console.WriteLine("Process name: {0}", name);
PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", name);
Process p = Process.GetProcessById((int)pc.RawValue);
System.Console.WriteLine("Parent Process id: {0}", p.Id);
System.Console.WriteLine("Parent Process name: {0}", p.ProcessName);
// p.ProcessName == "cmd" or "Explorer" etc
プロセスの起動後にウィンドウをすばやく非表示にするには、次を使用します。
private static readonly int SW_HIDE= 0;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);
....
{
IntPtr myHandle = Process.GetCurrentProcess().MainWindowHandle;
ShowWindow(myHandle, SW_HIDE);
}
(WinForms アプリ)を生成し、winexe
必要に応じて で親コンソールにアタッチするAttachConsole(-1)
と、通常のコンソール アプリと同等のものは得られません。winexe の場合、親プロセス (cmd.exe など) は、GUI アプリケーションを開始した直後にコマンド プロンプトに戻ります。つまり、起動したばかりのプロセスが出力を発行している間、コマンド プロンプトはアクティブで入力の準備ができています。これは紛らわしく、おそらく winforms アプリのデバッグにのみ役立ちます。
これは私にとってはうまくいきました。