コンソールアプリ・Winフォームアプリの切替 への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 HIASOBI  (高校生) 投稿日時 2020/8/20 18:16:06
ああ、同じようなことを考える人はいるんですね。
魔界の仮面弁士様に教えていただいたページを参考に勉強し、よく考えてみます。
ありがとうございました!
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/8/20 11:38:45
「新規コンソール」への出力の場合、コマンドプロンプトから起動した場合も、
現在のコンソールではなく、新しいコンソールに対する出力になります。


> 最後にFreeConsoleを呼び出す(これもDLLImport必要)、
> という感じで良いでしょうか?

そうですね。DllImportAttribute 属性でも良いですし、Declare ステートメントでも構いません。

http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=26973

※上記で、「Public Function () As Boolean」となっている箇所は
 「Public Function FreeConsole() As Boolean」の書き間違いです。
投稿者 HIASOBI   (学生) 投稿日時 2020/8/20 10:41:44
魔界の仮面弁士様、ありがとうございます。
また、参考サイトもありがとうございます。

以下のサイトの例を参考にする場合は、
とりあえずWinフォームアプリとしてプロジェクトを作成し、
コンソールアプリとして動作させたい場合は
フォームは一切開かずにコンソールを開く(Win32API使用)、
というやり方になるでしょうか?

http://bignight.hatenablog.com/entry/2015/01/14/191931

ちなみに、

> (プログラム終了時には FreeConsole が必要)

については、最後にFreeConsoleを呼び出す(これもDLLImport必要)、
という感じで良いでしょうか?
(試してみればいいのですが、プログラム用ノートPCをお姉ちゃんに貸しているので。。。)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/8/20 09:50:35
サブシステムが異なるためですね。

プロジェクトのプロパティの[アプリケーション]タブにある
『アプリケーションの種類(A):』という項目が、
`Window フォーム アプリケーション` になっているか
`コンソール アプリケーション` になっているかが分かれ目です。

EXE 内部に記録される IMAGE_OPTIONAL_HEADER には
Subsystem というものを記録する 2 バイトの領域があるのですが、ここに
3 (IMAGE_SUBSYSTEM_WINDOWS_CUI) が記録されていればコンソールアプリで、
2 (IMAGE_SUBSYSTEM_WINDOWS_GUI) が記録されていればデスクトップアプリです。

その他の値についてはこちらを参照。
https://tech.blog.aerie.jp/entry/2015/12/24/013344#Subsystem


Windows フォームアプリケーションとしてビルドされた EXE であっても、
アプリ内から AllocConsole を呼び出せば、プロセスに新しいコンソールを割り当てて
コンソール画面への出力を行うことはできます。(プログラム終了時には FreeConsole が必要)
http://bignight.hatenablog.com/entry/2015/01/14/191931

望むものとはちょっと違うかもしれませんが…。
投稿者 HIASOBI  (学生) 投稿日時 2020/8/20 09:13:26
こんにちは!
色々とプログラムの勉強を行っています。
例えば、Visual Studioの新規プロジェクト作成で、
Winフォームアプリやコンソールアプリを選択しますが、
コンソールアプリとしてプロジェクトを作成すると、
起動時にコマンドプロンプトが表示されて、
コンソール出力がここに表示されます。
コンソールアプリとして作成したプロジェクトでは
Winフォームも表示することが出来ますが、
(System.Windows.Formsの参照設定が必要?)
その場合でもコマンドプロンプトが表示されます。
(コンソールアプリなので当然だとは思いますが。。。)

今回僕が考えているのは、以下のようなことなのですが、可能でしょうか?
・実行時にコマンドライン引数があり、その内容が適切であれば、コンソールアプリとして動作
 (コマンドプロンプトが自動的に表示)
・実行時にコマンドライン引数がない(または不正)であれば、Winフォームアプリとして動作

なお、コマンドライン引数が適切かどうかについては、Sub Main内の処理で判断します。

よろしくお願いいたします。