関連:
Should I include a command line mode in my applications?
How to grab parent process standard output?
Can a console application detect if it has been run from Explorer?ダブルクリックするとコンソールウィンドウを表示しないコンソールアプリケーションを構築できますか?
私は通常、コマンドラインから実行されたコンソールアプリケーションを、構築したいです。
しかし、(cmd.exeプロンプトから実行されているのとは対照的に)エクスプローラ内でダブルクリックすると、コンソールウィンドウを表示しないようにしたいと思います。私はこれを回避したい
:
alt text http://i36.tinypic.com/1088p5s.jpg
それは可能ですか?
EDIT私は推測することがある依頼する別の方法、それはプログラムがそれが呼び出されたかを知ることが可能です - かどうかでダブルクリックするか、コマンドラインによって?
私はWindowsの.NETで作業しています。
編集2:からthis Old New Thing blog post私は良いことを学びました。ここに私が今知っているものは...
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のから呼び出された場合、アプリケーションは、コンソールを使用することができ、およびNOTする唯一の方法は、としてexeファイルを定義することだと思います。この時点で
通常のコンソールexe(/target:exe
)、および場合によっては、起動時にウィンドウが表示されないようにします。コンソールウィンドウが表示されたままです。
まだエクスプローラから起動されたか、cmd.exeから起動されたかを知りませんでしたが、近づいています。
コンソールウィンドウが表示されませんコンソールアプリケーションを構築することはできません
に答えます。それ
はなく、そうすぐにウィンドウが表示されたことがないかのようにそれがあることを、非常に迅速にそのウィンドウを隠しコンソールアプリケーションを構築する可能です。
int left = Console.CursorLeft;
int top = Console.CursorTop;
bool ProcessWasRunFromExplorer = (left==0 && top==0);
これがあればわかります:コンソールアプリケーションはいくつかは、それが(mgb's answer、およびKB article 99115から)
で実行されているコンソールを見て示唆している、エクスプローラから起動されたかどうかを判断するために今
、プロセスはそれ自身のコンソールで起動されましたが、エクスプローラであるかどうかは関係ありませんでした。エクスプローラでダブルクリックするとこれが実行されますが、アプリケーション内の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);
}
を
winexe
(WinFormsアプリ)を作成し、適宜、親コンソールに添付する場合は、AttachConsole(-1)
とすると、通常のコンソールアプリに相当するものは得られません。 winexeの場合、親プロセス(cmd.exeなど)はGUIアプリケーションの起動直後にコマンドプロンプトに戻ります。言い換えれば、コマンドプロンプトはアクティブであり、入力の準備が整いましたが、ちょうど起動されたプロセスが出力を出力している可能性があります。これは紛らわしく、おそらくwinformsアプリケーションのデバッグにのみ役立ちます。
これは私のために働いた。
代わりに何をしたいですか? –
私はそれが見えないようにしたい。 – Cheeso
プログラムがそれ自身のコンソールで起動されたかどうかを判断するテストは間違っています。コマンドラインで 'cls&program.exe'を入力すると、プログラムがそれ自身のコンソールで起動されたと誤って記述されます。あなたはバッチファイルから同じことをすることができます。テストを敗北させる他の方法があると思われます。 –