web-dev-qa-db-ja.com

ウィンドウのないアプリケーションを作成する

ウィンドウやコンソールを開かなくても実行できるC/C++アプリケーションをどのようにプログラムしますか?

24
kiewic

WinMainプログラムを作成すると、/ SUBSYSTEMオプションがコンパイラのウィンドウとして自動的に取得されます。 (Visual Studioを使用していると仮定します)。他のコンパイラの場合、同様のオプションが存在する可能性がありますが、フラグ名が異なる場合があります。

これにより、コンパイラは実行可能ファイル形式( PE形式 )でエントリを作成し、実行可能ファイルをWindows実行可能ファイルとしてマークします。

この情報が実行可能ファイルに存在すると、プログラムを起動するシステムローダーはバイナリをコンソールプログラムではなくWindows実行可能ファイルとして扱うため、実行時にコンソールウィンドウが自動的に開かれることはありません。

ただし、Windowsプログラムは、タスクバーで実行されているすべてのプログラムやサービスと同様に、必要がなければウィンドウを作成する必要はありませんが、対応するウィンドウは表示されません。これは、ウィンドウを作成したが表示しないことを選択した場合にも発生する可能性があります。

これをすべて達成するためにあなたがする必要があるのは、

#include <Windows.h>

int WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance, 
            LPTSTR    lpCmdLine, 
            int       cmdShow)
    {
    /* do your stuff here. If you return from this function the program ends */
    }

WinMain自体が必要な理由は、サブシステムをWindowsとしてマークすると、リンカーは、エントリポイント関数(プログラムがロードされ、C Run TImeライブラリが初期化された後に呼び出される)がMainではなくWinMainであると想定するためです。このようなプログラムでWinMainを指定しないと、リンクプロセス中に未解決のシンボルエラーが発生します。

39
computinglife

Windowsの場合:

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    // <-- Program logic here
    return 0;
}   

Adam Mitzが述べたように、必ず/ SUBSYSTEMリンカースイッチを使用してください。

他のプラットフォームの場合:

int main(int argc, char**argv)
{
  // <-- Program logic here
  return 0;
}
14
Brian R. Bondy

コンソールやウィンドウがなくてもプログラムを連続して実行する必要がある場合は、便利なことがわかります * NIXのデーモン または Windowsのサービス 、プレーンが必要な場合は、この.NETの例win32は、サンプル用に少しだけグーグルで検索します。
win32のタグが付けられた質問なので、サービスの方が関連性が高いと思います。

4
Ilya

Visual Studio Express 2010では、サブシステムをWindowsに設定した後(user17224が提案)、またはメインをWinMainに変更した後(user17224とBrian R. Bondyが提案)、プロパティ、リンカー、でエントリ関数をmainに設定できます。高度なエントリポイント:テキストボックスにmainと入力するだけです。

1
crisat

VisualStudioウィザードを使用してWin32アプリケーションを作成します。ただし、ウィンドウを作成しないでください。つまり、ウィンドウ作成機能を削除します。または、WinServiceアプリケーションを作成することもできます。

0
Vinay

これはメッセージも処理します:

#include <windows.h>
#include <stdio.h>

int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    MSG msg;
    DWORD curThreadId;

    curThreadId = GetCurrentThreadId();

    // Send messages to self:
    PostThreadMessage(curThreadId, WM_USER, 1, 2);
    PostThreadMessage(curThreadId, WM_USER+1, 3, 4);
    PostThreadMessage(curThreadId, WM_USER+2, 5, 6);
    PostThreadMessage(curThreadId, WM_USER+3, 7, 8);
    PostThreadMessage(curThreadId, WM_QUIT, 9, 10);

    while (GetMessage(&msg, NULL, 0, 0)) {
        printf("message: %d; wParam: %d; lParam: %d\n", msg.message, msg.wParam, msg.lParam);
    }

    return (int) msg.wParam;
} 
0
WndProc