2008-05-17

サービスの開始と終了

このところバタバタとしていて ずいぶんと更新をサボっていました。
色々と未解決の問題があったはずなのですが、このまま忘れてしまいそうですね。
 
サボりだすとキリがないので、とりあえず一番記憶に残っている MCAlertから手をつけることにします。
 
MCAlertは新しい試みとしてサービスとして実行するようにしてみました。
WindowsMobileでは同時実行プロセス数が32個に制限されているらしいので、GUIを伴わないようなツールをサービスとして実行できればプロセス数を節約することができますね。
 
先日のテストバージョンではこの辺を参考にXXX_Init()、XXX_Deinit()を実装したDLLを作って、サービスを開始するだけのプログラムからActivateService()で呼び出すところまで作っていました。
このままではサービスを終了することができないので、既にサービスが動作中であればサービスを停止できるように変更してみます。
 
動作中のサービスのハンドルはGetServiceHandle()で取得するみたいです。
ActivateService()ではレジストリに登録したサービスのキー名を指定しますが、GetServiceHandle()に指定するのはサービスのプレフィックス(XXX_Init()等のXXXに相当する部分ですね)とインデックスを指定するようです。
サービスが動作中であればハンドルが取得できるので DeregisterService()でサービス終了、ハンドルが取得できなければサービスが動作中でないという事でActivateService()でサービスを起動するようにしました。
 
// **********************************************************************
// 定数
//
#define APP_NAME        _T("MCAlert")
#define MUTEX_NAME      _T("MCAlertStartupMutex")
#define SERVICE_NAME    _T("MCAlert")
#define SERVICE_PREFIX  _T("MCA0:")


// **********************************************************************
// WinMain
//
INT WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   INT       nCmdShow)
{
    HANDLE  hMutex              = NULL,
            hService            = NULL;
    TCHAR   szMessage[256]      = _T("");
    BOOL    bRet                = TRUE;

    hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME);
    if (hMutex) {
        if (ERROR_ALREADY_EXISTS == GetLastError()) {
            CloseHandle(hMutex);
            hMutex = NULL;
            return FALSE;
        }
    } else {
        return FALSE;
    }

    hService = GetServiceHandle(SERVICE_PREFIX, NULL, NULL);
    if (INVALID_HANDLE_VALUE != hService) {
        if (DeregisterService(hService)) {
            MessageBox(NULL, _T("サービスを停止しました"), APP_NAME, MB_ICONINFORMATION | MB_OK);
        } else {
            wsprintf(szMessage, _T("サービス停止エラー(%d)"), GetLastError());
            MessageBox(NULL, szMessage, APP_NAME, MB_ICONERROR | MB_OK);
            bRet = FALSE;
        }
    } else {
        if (NULL == ActivateService(SERVICE_NAME, 0)) {
            wsprintf(szMessage, _T("サービス開始エラー(%d)"), GetLastError());
            MessageBox(NULL, szMessage, APP_NAME, MB_ICONERROR | MB_OK);
            bRet = FALSE;
        }
    }

    ReleaseMutex(hMutex);
    CloseHandle(hMutex);
    hMutex = NULL;

    return bRet;
}
 
あとはメール着信時の制御もできるようにして設定画面を作れば MCAlertについては一段落といったところでしょうか。
 

0 件のコメント: