다른 프로그램 제어하기
[ 외부 프로그램의 실행과 종료여부를 판단 ]
자신의 어플리케이션이 아닌 다른 어플리케이션의 종료여부를 판단해야할 경우에 사용합니다. 예를 들어, winzip내의 인스톨를 실행시키면, 압축된 프로그램이 바로 인스톨이 되는 경우를 보셨을껍니다. 이때, 그 인스톨되는 프로그램이 종료되었을 때, winzip도 비로소 종료가 됩니다.
1. 어플리케이션 클래스의 사전 준비
외부 어플리케이션의 정보를 관리하기위한 정보구조체를 선언압니다.이때, 어플리케이션 클래스에 Protected로 작성해 둡니다.
class CALApp : public CWinApp
{
protected:
PROCESS_INFORMATION pinfo;
};
이때, pinfo의 값은 쓰레기값을 갖고 있으므로, 이에대한 초기화를 해 줍니다.
// CALApp 생성자
CALApp::CALApp()
{
// TODO
pinf.hProcess=NULL;
pinf.hThread=NULL;
pinf.dwProcessId=0L;
pinf.dwThreadId=0L;
}
2. 외부 어플리케이션을 정보를 저장한뒤 실행시킵니다.
// 다른 프로그램을 기동하는 루틴
int CALApp::ExecuteOutsideEditor()
{
STARTUPINFO sinfo;
if(IsOutsideEditorRunning())
return -2;
memset(&sinfo, 0x00, sizeof(sinfo));
if(CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo))
return -1;
else
return 0;
}
즉, 외부프로그램을 실행하면서, 그에대한 종료여부를 판단하기위해 정보구조체를 저장하는것이죠..
szCmdLine은 실행시킬 외부프로그램의 이름을 저장하는 스트링변수이다. 예를 들어, 아래와 같은 형식의 스트링을 저장시킨다고 보면됩니다.
CString szCmdLine;
szCmdLine.Format("c:\\windows\\notepad.exe c:\\help.txt");
즉, 위의 내용은 "윈도우에 있는 메모장에 루트디렉토리에 있는 헬프파일을 여는 외부프로그램을 실행시키는 의미"가 되는 것이 되는것입니다.(노파심에서 말씀드리는데, 프로그램상에서는 \를 쓰기 위해서는 \\두 번 써야한다는건 아시겠죠?)
if(IsOutsideEditorRunning())
return -2;
위의 명령문은 외부 프로그램이 이미 실행상태인지를 의미합니다. 이는 외부 프로그램을 관리하는 정보변수가 pinfo하나밖에 없기 때문에 한번에 하나의 외부프로그램을 실행할 수 있기 때문입니다. 만약에 복수의 외부 프로그램을 실행하고 싶으시다면, 이 정보구조체변수를 배열과 같이 복수개로 만들어 놓으면 됩니다. 이때는 카운터가 필요하겠죠 ?
memset은 STARTUPINFO 구조 체형 변수 pinfo를 프로세스의 실행마다 초기화합니다. memset(&sinfo, 0x00, sizeof(sinfo))은, sinfo의 모든 멤버 변수에 0을 대입함을 의미합니다.
CreateProcess 함수는 여러 가지 인수를 갖지만, szCmdLine만 신경을 쓰시면 됩니다.
3. 외부 어플리케이션이 아직 살아 있을까를 조사하는 루틴
// 기동한 프로그램이 아직 살아 있을까 탐색하는 루틴
int CALApp::IsOutsideEditorRunning()
{
unsigned long l;
if(pinfo.hProcess)
{GetExitCodeProcess(pinfo.hProcess, &l);
if(l==STILL_ACTIVE)return -1; //동작중은 실행하지 않는다.
}
return 0;
}
pinfo는 위에서 실행한 외부프로그램의 현재상태가 저장되어 있습니다. 즉, pinfo.hProcess값이 NULL 인가 아닌가를 판단합니다. 그 값이NULL인경우는, 현재 실행중이나 판정하기 위한 정보가 없음을 의미하며, NULL이 아닌 경우는 판정하기위한 정보가 생성되었음을 의미하고, pinf.hProcess로부터, GetExitProcess Win32API 함수를 개입시켜, 외부 프로그램의 상태를 나타냅니다.
이렇게 얻은 값을 조사해 줌으로써, 외부 프로그램의 상태를 조사할 수 있습니다. 만일 동작중이면, STILL_ACTIVE를 의미하는것입니다.
4. 현재 정보를 체크합니다.
위와 같은 순서로 하면, 대부분 필요한 정보를 얻을 수 있습니다. 그러나 가장 핵심이 되는 부분이 빠졌죠 ? 바로 pinfo의 프로세스상태를 체크해주는 루틴이 필요합니다. 이것은 주기적으로 체크를 해야하기 때문에 WM_TIMER 메세지에 의해 실행되는 CWnd::OnTimer를 사용하면 간단히 해결됩니다.
이때, 타이머처리는 어플리케이션 클래스에 둘 수 없으므로, CMainFrame등과 같은 다른 클래스에 삽입합니다.
void CMainFrame::OnTimer(UINT nIDEvent)
{
// pApp는 어플리케이션 클래스에의 포인터를 의미합니다. if(pApp->IsOutsideEditorRunning()==0)
{// 만일 다른기능을 추가시, 아래 부분을 수정합니다.
AfxMessageBox("실행한 프로그램이 종료했습니다.");
CFrameWnd::OnTimer(nIDEvent);
KillTimer(nIDEvent);
return;}
CFrameWnd::OnTimer(nIDEvent);
}
여기서는 단순히 메시지 박스를 출력하도록 했지만, 이 부분을 수정해서, 다양한 기능을 추가할 수 있습니다.
'C & C++ > C & C++' 카테고리의 다른 글
현재 내 컴퓨터에 어떤 프로그램이 실행중인가 ? (0) | 2011.11.17 |
---|---|
다른 프로그램 제어하기(2) (0) | 2011.11.17 |
API함수를 이용한 해상도 조절하기 (0) | 2011.11.17 |
로그인인증 (ODBC) 구현해보자 (0) | 2011.11.03 |
메모장을 API를 이용하여 주물럭 거려보자 (0) | 2011.11.02 |
댓글