以下のことを実行する Windows アプリケーションを作成するにはどうすればよいですか?
- コマンドライン引数なしで呼び出された場合は通常のGUIアプリになります
- オプションの「--help」コマンドライン引数を指定すると、アプリは使用方法のテキストを標準出力に書き込んで終了します。
- 単一の実行可能ファイルである必要があります。コンソール アプリで 2 番目の実行可能ファイルを実行する不正行為は禁止されています。
- メインのアプリケーションコードはC/C++で書かれていると仮定する
- 「--help」が指定されているときに GUI ウィンドウが作成されない場合はボーナス ポイントが付与されます (つまり、短時間のウィンドウがちらつかない)
私の経験では、コンソール アプリ用の標準の Visual Studio テンプレートには GUI 機能がなく、通常の Win32 テンプレートは stdout を親の cmd シェルに送信しません。
ベストアンサー1
Microsoft は、コンソール アプリと GUI アプリを相互に排他的に設計しました。この少しの近視眼的な考え方は、完璧な解決策がないことを意味します。最も一般的なアプローチは、2 つの実行可能ファイル (例: cscript / wscript、java / javaw、devenv.com / devenv.exe など) を使用することですが、これを「不正行為」と見なしていると示しています。
2 つのオプションがあります。「コンソール実行可能ファイル」または「GUI 実行可能ファイル」を作成し、コードを使用して他の動作を提供するようにします。
- GUI実行可能ファイル:
cmd.exe
は、プログラムがコンソール I/O を行わないと想定し、続行する前に終了を待たないで続行します。対話モード (つまり、バッチではない) では、次の (" C:\>
") プロンプトが表示され、キーボードから読み取られます。そのため、AttachConsole を使用しても、出力は の出力と混在しcmd
、入力しようとすると状況が悪化します。これは基本的に、開始できません。
- コンソール実行可能ファイル:
信じられていることとは反対に、コンソール実行可能ファイルが GUI を表示するのを妨げるものは何もありませんが、2 つの問題があります。
1 つ目は、引数なしでコマンド ラインから実行すると (つまり GUI が必要な場合)、cmd
続行する前に終了を待つため、その特定のコンソールはその間使用できなくなります。この問題は、同じ実行可能ファイルの 2 番目のプロセスを起動し (これは不正行為とみなされますか?)、DETACHED_PROCESS フラグを CreateProcess() に渡してすぐに終了することで解決できます。新しいプロセスは、コンソールがないことを検出し、GUI を表示できます。
このアプローチを説明する C コードを以下に示します。
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[])
{
if (GetStdHandle(STD_OUTPUT_HANDLE) == 0) // no console, we must be the child process
{
MessageBox(0, "Hello GUI world!", "", 0);
}
else if (argc > 1) // we have command line args
{
printf("Hello console world!\n");
}
else // no command line args but a console - launch child process
{
DWORD dwCreationFlags = CREATE_DEFAULT_ERROR_MODE | DETACHED_PROCESS;
STARTUPINFO startinfo;
PROCESS_INFORMATION procinfo;
ZeroMemory(&startinfo, sizeof(startinfo));
startinfo.cb = sizeof(startinfo);
if (!CreateProcess(NULL, argv[0], NULL, NULL, FALSE, dwCreationFlags, NULL, NULL, &startinfo, &procinfo))
MessageBox(0, "CreateProcess() failed :(", "", 0);
}
exit(0);
}
私は cygwin の gcc でコンパイルしました - MSVC では結果が異なります。
2 つ目の問題は、エクスプローラーから実行すると、プログラムが一瞬コンソール ウィンドウを表示することです。コンソールは、アプリが起動されて実行を開始する前に Windows によって作成されるため、プログラムでこれを回避する方法はありません。実行できる唯一の方法は、インストーラーで、SW_HIDE (つまり 0) の「表示コマンド」を使用してプログラムへのショートカットを作成することです。プログラムで STARTUPINFO の wShowWindow フィールドを意図的に尊重しない限り、これはコンソールにのみ影響します。したがって、そうしないでください。
私は cygwin の "mkshortcut.exe" をハッキングしてこれをテストしました。選択したインストール プログラムでこれをどのように実現するかは、あなた次第です。
もちろん、ユーザーはエクスプローラーで実行可能ファイルを見つけてダブルクリックし、コンソールを非表示にするショートカットをバイパスして、コンソール ウィンドウの短い黒い点滅を見ることで、プログラムを実行することができます。これについては何もできません。