コンソール アプリケーション内から winform を作成、実行、および制御するにはどうすればよいですか?
10 に答える
最も簡単なオプションは、Windows フォーム プロジェクトを開始し、出力タイプをコンソール アプリケーションに変更することです。または、System.Windows.Forms.dll への参照を追加して、コーディングを開始します。
using System.Windows.Forms;
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new Form()); // or whatever
}
重要な部分は、完全な COM サポートに必要なメソッドにあり[STAThread]
ます。Main()
私は最近これをやりたかったのですが、ここでの答えのどれにも満足していないことがわかりました。
Marcのアドバイスに従い、output-typeをConsole Applicationに設定すると、次の2つの問題が発生します。
1)エクスプローラーからアプリケーションを起動すると、フォームの背後に迷惑なコンソールウィンドウが表示され、プログラムが終了するまで消えません。GUI(Application.Run)を表示する前にFreeConsoleを呼び出すことで、この問題を軽減できます。ここでの煩わしさは、コンソールウィンドウがまだ表示されていることです。それはすぐに消えますが、それでもしばらくの間そこにあります。
2)コンソールから起動してGUIを表示すると、GUIが終了するまでコンソールはブロックされます。これは、コンソール(cmd.exe)が、コンソールアプリを同期的に起動し、Windowsアプリを非同期的に起動する必要があると考えているためです(UNIXでは「myprocess&」に相当)。
出力タイプをWindowsアプリケーションのままにして、 AttachConsoleを正しく呼び出すと、コンソールから呼び出されたときに2番目のコンソールウィンドウが表示されず、エクスプローラーから呼び出されたときに不要なコンソールが表示されません。AttachConsoleを呼び出す正しい方法は、それに-1を渡すことです。これにより、プロセスが親プロセスのコンソール(起動したコンソールウィンドウ)にアタッチされます。
ただし、これには2つの異なる問題があります。
1)コンソールはバックグラウンドでWindowsアプリを起動するため、プロンプトがすぐに表示され、さらに入力できるようになります。一方では、これは朗報です。コンソールはGUIアプリでブロックされませんが、出力をコンソールにダンプしてGUIを表示したくない場合、プログラムの出力はプロンプトの後に表示され、新しいプロンプトは表示されません。完了すると表示されます。これは、「コンソールアプリ」がバックグラウンドで実行されており、実行中にユーザーが他のコマンドを自由に実行できることは言うまでもなく、少し紛らわしいように見えます。
2)ストリームのリダイレクトも混乱します。たとえば、「myapp someparameters>somefile」はリダイレクトに失敗します。ストリームリダイレクトの問題は、標準ハンドルを修正するために大量のp / Invokeを必要としますが、解決可能です。
何時間にもわたる狩猟と実験の結果、これを完璧に行う方法はないという結論に達しました。副作用がなければ、コンソールとウィンドウの両方のメリットをすべて享受することはできません。アプリケーションの目的にとって、どの副作用が最も煩わしくないかを選択することが重要です。
私が見つけた最良の方法は次のとおりです。まず、プロジェクトの出力タイプを「Windows アプリケーション」に設定し、次に P/Invoke AllocConsole を呼び出してコンソール ウィンドウを作成します。
internal static class NativeMethods
{
[DllImport("kernel32.dll")]
internal static extern Boolean AllocConsole();
}
static class Program
{
static void Main(string[] args) {
if (args.Length == 0) {
// run as windows app
Application.EnableVisualStyles();
Application.Run(new Form1());
} else {
// run as console app
NativeMethods.AllocConsole();
Console.WriteLine("Hello World");
Console.ReadLine();
}
}
}
やり方はとても簡単です:
次の属性とコードを Main メソッドに追加するだけです。
[STAThread]
void Main(string[] args])
{
Application.EnableVisualStyles();
//Do some stuff...
while(!Exit)
{
Application.DoEvents(); //Now if you call "form.Show()" your form won´t be frozen
//Do your stuff
}
}
これで、WinForms を完全に表示できるようになりました:)
VS2005/VS2008 で winform プロジェクトを作成し、そのプロパティをコマンド ライン アプリケーションに変更できます。その後、コマンド ラインから起動できますが、引き続き winform が開きます。
Winform アプリと同じ方法で Application クラスを使用できるはずです。おそらく、新しいプロジェクトを開始する最も簡単な方法は、Mar が提案したことを実行することです。新しい Winform プロジェクトを作成し、オプションでそれをコンソール アプリケーションに変更します。
これは私のニーズに合っていました...
Task mytask = Task.Run(() =>
{
MyForm form = new MyForm();
form.ShowDialog();
});
これにより、新しいスレッドでフォームが開始され、フォームが閉じられるまでスレッドが解放されません。Task
.Net 4 以降です。
それはあなたの選択、つまりあなたがどのように実装しているかに完全に依存します。
を。付帯工程 例:フォームへの入力、コンソールへの印刷
b.独立したプロセス、例: タイマーを開始、コンソールが終了しても終了しない。
のために、
Application.Run(new Form1());
//or -------------
Form1 f = new Form1();
f.ShowDialog();
for b, スレッドを使用するか、何でもタスクを実行します, 独立して win フォームを開く方法は?