336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

//제가 다 짠건 아니구 이것 저것 편집해서 만든겁니다.

//제가 넘 화려한 C++이나 넘 딱딱한 코드는 않좋아해서 좀 바꿔 봤습니다.

//MFC사용 할려구 몇개 추가 했습니다.


// 다 보실 필요는 없구요 ServiceMainFn만 보시면 됩니다

//아래 소스를 콘솔로 컴파일 하시고 cmd에서 install하면 컴퓨터 관리 서비스에 등록 되며

//remove하시면 서비스에서 사라 집니다 (물론 서비스 진행 중이라면 내려 가지 안습니다)

//자동으로 실행하실지 수동으로 실행 하실지 옵션과 장애가 있을시 자동시작 하실지 여부는

//컴퓨터 관리 서비스에서 해주시기 바랍니다


  if ( _stricmp( "install", argv[1]+1 ) == 0 )

        {

            InstallService();

        }

        else if ( _stricmp( "remove", argv[1]+1 ) == 0 )


#include "stdafx.h"

#include "winsvc.h"

 

DWORD                   g_dwNowState    = 0; //현재 상태

SERVICE_STATUS_HANDLE   g_hSrv          = 0; //서비스 모듈의 핸들

HANDLE                  g_hExitEvent    = 0; //나가기 위핸 핸들

static SERVICE_STATUS   g_sStatus;

 

void ServiceMainFn(DWORD argc, LPTSTR *argv);

void ServiceHandlerFn(DWORD opCode);

 

void WriteDebug(LPCTSTR szDebug)

{

    FILE * fp = fopen("c:\\디버그 파일.txt" , "at");

    fprintf(fp , szDebug);

    fclose(fp);

}

 

 BOOL InstallService()

{

    SC_HANDLE schService = NULL;

    SC_HANDLE schSCManager = NULL;

    TCHAR szError[MAX_PATH] = {0, };

    BOOL bRet = FALSE;

    

    TCHAR szPath[512] = {0, };

    

    if ( ::GetModuleFileName( NULL, szPath, 512 ) == 0 )

    {

        WriteDebug("Unable to install RealRoadInfo \n");

        printf("Unable to install RealRoadInfo \n");

        return bRet;

    }

    

    schSCManager = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS );

    

    if ( NULL != schSCManager )

    {

        schService = ::CreateService(

            schSCManager, // SCManager database

            "RealRoadInfo", // name of service

            "RealRoadInfo", // name to display

            SERVICE_ALL_ACCESS, // desired access

            SERVICE_WIN32_OWN_PROCESS, // service type

            SERVICE_DEMAND_START, // start type

            SERVICE_ERROR_NORMAL, // error control type

            szPath, // service's binary

            NULL, // no load ordering group

            NULL, // no tag identifier  (종속성을 추가해 주는 부분 )

            NULL, // dependencies

            NULL, // LocalSystem account

            NULL); // no password

        

        if ( NULL != schService )

        {

            SERVICE_DESCRIPTION srvdesc = {0, };

            srvdesc.lpDescription = "설명 입니다.";

            if(FALSE == ::ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &srvdesc))

            {

                WriteDebug("ChangeServiceConfig2 Error \n");

                printf("ChangeServiceConfig2 Error \n");

                bRet = FALSE;

            }

            

            printf("RealRoadInfo installed \n");

            WriteDebug("RealRoadInfo installed \n");

            ::CloseServiceHandle(schService);

            bRet = TRUE;

        }

        else

        {

            printf("CreateService failed \n");

            WriteDebug("CreateService failed \n");

            bRet = FALSE;

        }

        

        ::CloseServiceHandle(schSCManager);

    }

    else

    {

        printf("OpenSCManager failed \n");

        WriteDebug("OpenSCManager failed \n");

        bRet = FALSE;

    }

    

    if(FALSE == bRet)

    {

        return FALSE;

    }

    

    return bRet;

}

 

 

BOOL RemoveService()

{

    SC_HANDLE schService = NULL;

    SC_HANDLE schSCManager = NULL;

    TCHAR szError[MAX_PATH] = {0, };

    BOOL bRet = FALSE;

    

    schSCManager = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS );

    if ( NULL != schSCManager )

    {

        schService = ::OpenService(schSCManager,"RealRoadInfo",SERVICE_ALL_ACCESS);

        

        if (NULL != schService)

        {

            if (TRUE == ::ControlService(schService,SERVICE_CONTROL_STOP, &g_sStatus))

            {

                while( ::QueryServiceStatus( schService, &g_sStatus) )

                {

                    if (g_sStatus.dwCurrentState == SERVICE_STOP_PENDING )

                    {

                        ::Sleep( 1000 );

                    }

                    else

                    {

                        break;

                    }

                }

                

                if (g_sStatus.dwCurrentState == SERVICE_STOPPED )

                {

                    WriteDebug("RealRoadInfo Stop \n");

                    printf("RealRoadInfo Stop \n");

                    bRet = TRUE;

                }

                else

                {

                    WriteDebug("RealRoadInfo failed \n");

                    printf("RealRoadInfo failed \n");

                    bRet = FALSE;

                }

                

            }

            

            // now remove the service

            if( TRUE == ::DeleteService(schService) )

            {

                WriteDebug("RealRoadInfo removed \n");

                printf("RealRoadInfo removed \n");

                bRet = TRUE;

            }

            else

            {

                WriteDebug("RealRoadInfo DeleteService failed \n");

                printf("RealRoadInfo DeleteService failed \n");

                bRet = FALSE;

            }

            

            ::CloseServiceHandle(schService);

        }

        else

        {

            WriteDebug("RealRoadInfo OpenService failed \n");

            printf("RealRoadInfo OpenService failed \n");

            bRet = FALSE;

        }

        

        ::CloseServiceHandle(schSCManager);

    }

    else

    {

        WriteDebug("RealRoadInfo OpenSCManager failed \n");

        printf("RealRoadInfo OpenSCManager failed \n");

        bRet = FALSE;

    }

    

    return bRet;

}

 

int main(int argc, char *argv[])

{

    SERVICE_TABLE_ENTRY dispatchTable[] =

    {

        {"RealRoadInfo",(LPSERVICE_MAIN_FUNCTION)ServiceMainFn}, {NULL,NULL}

    };

    

    if ( (argc > 1) &&

        ((*argv[1] == '-') || (*argv[1] == '/')) )

    {

        if ( _stricmp( "install", argv[1]+1 ) == 0 )

        {

            InstallService();

        }

        else if ( _stricmp( "remove", argv[1]+1 ) == 0 )

        {

            RemoveService();

        }

        else

        {

            goto dispatch;

        }

        ::exit(0);

    }

    

    // if it doesn't match any of the above parameters

    // the main control manager may be starting the main

    // so we must call StartServiceCtrlDispatcher

dispatch:

    // this is just to be friendly

    printf( "%s -install to install the main\n", "RealRoadInfo" );

    printf( "%s -remove to remove the main\n", "RealRoadInfo" );

    printf( "\nStartServiceCtrlDispatcher being called.\n" );

    printf( "This may take several seconds. Please wait.\n" );

    

    if (!StartServiceCtrlDispatcher(dispatchTable))

    {

        WriteDebug("StartServiceCtrlDispatcher failed. \n");

    }

    

    return 0;

}

 

// 서비스의 현재 상태를 변경하는 함수

void MySetStatus(DWORD dwState, DWORD dwAccept = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE)

{

    SERVICE_STATUS ss;

    ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS;

    ss.dwCurrentState=dwState;

    ss.dwControlsAccepted=dwAccept;

    ss.dwWin32ExitCode=0;

    ss.dwServiceSpecificExitCode=0;

    ss.dwCheckPoint=0;

    ss.dwWaitHint=0;

 

    // 현재 상태를 보관해 둔다.

    g_dwNowState = dwState;

    SetServiceStatus(g_hSrv,&ss);

}

 

void ServiceMainFn(DWORD argc, LPTSTR *argv)

{

    // 서비스 핸들러를 등록한다.

    WriteDebug("서비스 시작\n");

    g_hSrv = RegisterServiceCtrlHandler("RealRoadInfo",(LPHANDLER_FUNCTION)ServiceHandlerFn);

    if (g_hSrv == 0)

    {

        return;

    }

 

    // 서비스가 시작중임을 알린다.

    MySetStatus(SERVICE_START_PENDING);

 

    g_hExitEvent = CreateEvent(0, FALSE, FALSE, 0);

    ResetEvent(g_hExitEvent);

 

    CoInitialize(NULL); // COM 컴퍼넌트를 쓰기위한 라리브러리 초기화  ado를 쓰는 넘이라 이거 넣습니다. 필요 없으면 빼셔두

 

    AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0); //MFC를 쓰기 위한 초기화

    

    CRealMgr * pCRM = new CRealMgr; //제 메인 프로세스 스레드로 동작구동만 시키면 동작 합니다.

 

    WriteDebug("시작 통보\n");

            

    // 서비스가 시작되었음을 알린다.

    MySetStatus(SERVICE_RUNNING);

 

    while(1)

    {

        DWORD dwRet = WaitForMultipleObjects(1, &g_hExitEvent , FALSE, INFINITE); //메인 프로세스가 알아서 하기 때문에 서비스는 정지

 

        if (dwRet == WAIT_FAILED)

        {

            continue;

        }

        else if (dwRet == WAIT_TIMEOUT)

        {

            continue;

        }

 

        WriteDebug("서비스 종료\n");

 

        break;

    }

 

    delete pCRM;

    

 

    CoUninitialize();

    CloseHandle(g_hExitEvent);

 

    MySetStatus(SERVICE_STOPPED);

 

    

}

 

// 핸들러 함수

void ServiceHandlerFn(DWORD fdwControl)

{

    // 현재 상태와 같은 제어 코드일 경우는 처리할 필요 없다.

    if (fdwControl == g_dwNowState)return;

 

    switch (fdwControl)

    {

        

    case SERVICE_CONTROL_STOP:

        MySetStatus(SERVICE_STOP_PENDING,0);

        SetEvent(g_hExitEvent); //서비스 프로세스를 시그널 시켜 줍니다.

        WriteDebug("종료 메세지\n");

        break;

    default:

        MySetStatus(g_dwNowState);

        break;

    }

}


336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
요즘은 거의 VC7.0을 안 쓰는 추세이긴 하지만 가끔 필요 할때가 있네요 ^^


336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
릴리스 모드에서 디버깅을 하기 위해서라는

모듈이 죽을 당시 메모리에 올라와 있는 프로세스들의 메모리 위치가 필요 합니다

프로그램이 죽으면서 주소만 알려주고 죽기 때문입니다

아래와 같은 방법으로 현재 OS에 올라와 있는 주소를 확인 할수 있습니다

저는 MFC를 주력으로 쓰기 때문에 아래와 같이 코딩 하였습니다

기타를 API를 쓰신다면 CString을 LPCTSTR 등으로 변환 하셔서 쓰시기 바랍니다

이때 Microsoft SDK 필요 합니다 최신일 경우 그 안에 PSAPI.H, PSAPI.LIB가 있으실 거고

만약 PSAPI.H가 없으시다면 BugslayerUtil에 있는 PSAPI.H를 이용 하시기 바랍니다

void PrintModules(CString & pString)
{
    HMODULE hMods[1024];
    DWORD cbNeeded;
    unsigned int i;
 
    // Get a list of all the modules in this process.

    pString += "메모리 모듈 상태 \r\n\r\n";

    if(EnumProcessModules(GetCurrentProcess(), hMods,
        sizeof(hMods), &cbNeeded))
    {
        for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            TCHAR szModName[MAX_PATH];
            
            // Get the full path to the module's file.
            if (GetModuleFileNameEx(GetCurrentProcess(),
                hMods[i], szModName,
                sizeof(szModName) / sizeof(TCHAR)))
            {
                // Print the module name and handle value.
                CString strTemp;
                strTemp.Format("\t%s (0x%08X)\r\n",szModName, hMods[i]);
                //fprintf(fp , "\t%s (0x%08X)\r\n",szModName, hMods[i] );
                pString += strTemp;
            }
        }
    }

    pString += "\r\n\r\n";
}

+ Recent posts