コンソールアプリケーション内からwinformを作成、実行、制御するにはどうすればよいですか?
最も簡単なオプションは、Windowsフォームプロジェクトを開始し、出力タイプをコンソールアプリケーションに変更することです。または、System.Windows.Forms.dllへの参照を追加して、コーディングを開始します。
_using System.Windows.Forms;
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new Form()); // or whatever
}
_
重要なビットは、Main()
メソッドの_[STAThread]
_です。これは完全なCOMサポートに必要です。
私は最近これをやりたかったのですが、ここでの答えに満足していないことがわかりました。
Marcのアドバイスに従い、出力タイプをコンソールアプリケーションに設定すると、2つの問題があります。
1)Explorerからアプリケーションを起動すると、フォームの背後に迷惑なコンソールウィンドウが表示されますが、これはプログラムが終了するまで消えません。 GUI(Application.Run)を表示する前にFreeConsoleを呼び出すことにより、この問題を軽減できます。ここでのイライラは、コンソールウィンドウがまだ表示されることです。それはすぐに消えますが、それでもしばらくの間そこにあります。
2)コンソールから起動してGUIを表示すると、GUIが終了するまでコンソールはブロックされます。これは、コンソール(cmd.exe)がコンソールアプリを同期的に起動し、Windowsアプリを非同期に起動する必要があると判断するためです(Unixで「myprocess&」に相当)。
出力タイプをWindowsアプリケーションのままにして、正しく AttachConsoleを呼び出すと、コンソールから呼び出されたときに2番目のコンソールウィンドウが表示されず、不要なものが表示されませんエクスプローラーから呼び出された場合のコンソール。 AttachConsoleを呼び出す正しい方法は、-1を渡すことです。これにより、プロセスは親プロセスのコンソール(起動したコンソールウィンドウ)に接続されます。
ただし、これには2つの異なる問題があります。
1)コンソールはWindowsアプリをバックグラウンドで起動するため、すぐにプロンプトが表示され、さらに入力が可能になります。一方で、これは良いニュースです。コンソールはGUIアプリでブロックされませんが、コンソールに出力をダンプしてGUIを表示したくない場合、プログラムの出力はプロンプトの後に表示され、新しいプロンプトはありません完了すると表示されます。これは少しわかりにくいですが、「コンソールアプリ」がバックグラウンドで実行されており、ユーザーが実行中に他のコマンドを自由に実行できることは言うまでもありません。
2)ストリームのリダイレクトも台無しになります。 「myapp some parameters> somefile」はリダイレクトに失敗します。ストリームリダイレクトの問題は、標準ハンドルを修正するためにかなりの量のp/Invokeを必要としますが、解決可能です。
何時間も狩りと実験を重ねた結果、これを完璧に行う方法はないとの結論に至りました。副作用がなければ、コンソールとウィンドウの両方の利点をすべて手に入れることはできません。アプリケーションの目的にとって、どの副作用が最も煩わしくないかを選択するだけです。
とても簡単です:
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クラスを使用できるはずです。おそらく、新しいプロジェクトを開始する最も簡単な方法は、Marcが提案したことを実行することです。つまり、新しいWinformプロジェクトを作成し、オプションでそれをコンソールアプリケーションに変更します。
これは私のニーズに合っていました...
Task mytask = Task.Run(() =>
{
MyForm form = new MyForm();
form.ShowDialog();
});
これは、新しいスレッドから開始し、フォームが閉じられるまでスレッドを解放しません。 Task
は.Net 4以降にあります。
から逃げたいなら フォームフリーズ (ボタンのテキストのような)編集を使用して、このコードを使用します
Form form = new Form();
Form.Button.Text = "randomText";
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.Run(form);
上記の答えはすべて非常に役立ちますが、私は絶対的な初心者のためにいくつかのヒントを追加することを考えました。
そのため、Windowsアプリケーション、コンソールアプリケーション:で何かをしたい
ソリューションエクスプローラーのコンソールアプリケーションプロジェクトでSystem.Windows.Forms.dllへの参照を追加します。 (ソリューション名->追加->参照...を右クリックします)
コードで名前空間を指定します:_using System.Windows.Forms;
_
フォームに追加するコントロールのクラスで必要なプロパティを宣言します。
例えば_int Left { get; set; } // need to specify the LEFT position of the button on the Form
_
そして、Main()
に次のコードスニペットを追加します。
_static void Main(string[] args)
{
Application.EnableVisualStyles();
Form frm = new Form(); // create aForm object
Button btn = new Button()
{
Left = 120,
Width = 130,
Height = 30,
Top = 150,
Text = "Biju Joseph, Redmond, WA"
};
//… more code
frm.Controls.Add(btn); // add button to the Form
// …. add more code here as needed
frm.ShowDialog(); // a modal dialog
}
_
それは完全にあなたの選択、あなたがどのように実装しているかに依存します。
a。添付プロセス、例:フォームへの入力とコンソールでの印刷
b。独立したプロセス、例:タイマーを開始し、コンソールが終了しても閉じないでください。
のために、
Application.Run(new Form1());
//or -------------
Form1 f = new Form1();
f.ShowDialog();
bの場合、スレッドを使用するか、タスクを実行します。 winフォームを個別に開く方法