프로그램을 하다보면 필요에 의해서 제작중인 프로그램 내에서 외부프로그램(타프로그램)을 종료시켜야할 경우가 있습니다.

이럴경우 C#에서는 어떻게 할까요?


여러 프로그램 언어을 접해보신 분들이 알고계신 알고리즘과 동일하게 C#에서도 프로세스를 찾아서 Kill하는 방식과 FindWindow를 찾아서 SendMessage를 사용하는 방식을 사용합니다.

그런데 C#에서 어떻게 사용을 해야하는지, 사용하는 방법을 모를 경우가 있습니다.

저도 도데체 어디에 있으며 어떻게 사용해야하는 지 난감하더군요. 여기저기 뒤지고 검색해서 간단하게 구현한 소스를 소개합니다.

서두에 언급한 것처럼 2가지 방법을 소개할 예정이며 코드를 보시면 쉽게 이해가 되리라 생각됩니다.

1. 프로그램의 타이틀로 찾아서 종료


1) FindWindow를 사용해서 해당 프로그램의 핸들을 찾습니다.
2) SendMessage를 사용해서 종료 메시지를 보냅니다.

C#,C Sharp, .Net, 외부프로그램 종료, 타 프로그램 종료, GetProcessesByName, FindWindow, SendMessage, Process, Kill

2. 프로세스의 이름으로 찾아서 종료


1) Process.GetProcessesByName을 사용해서 해당 프로그램의 정보를 가져옵니다.
2) Process.Kill을 사용해서 외부 프로그램을 종료합니다.

C#,C Sharp, .Net, 외부프로그램 종료, 타 프로그램 종료, GetProcessesByName, FindWindow, SendMessage, Process, Kill

3. 프로그램 소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Process를 사용하기 위해 아래 네임스페이스 추가
using System.Diagnostics;
// DllImport를 사용하기 위해 아래 네임스페이스 추가
using System.Runtime.InteropServices;
// API Import
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd,uint Msg,int wParam,int lParam);
private void ErrExit()
{
// 타이틀 바의 이름으로 찾아서 프로그램 종료
IntPtr hwd = FindWindow(null, "테스트.txt - 메모장");
if (hwd.ToString() != "0")
SendMessage(hwd, 0x0010, 0, 0);
// 프로세스 프로그램 이름으로 찾아서 프로그램 종료
Process[] p = Process.GetProcessesByName("notepad");
if (p.GetLength(0) > 0)
p[0].Kill();
}

 

Posted by wakira
,
MFC 안에서 외부 프로그램을 동작 시킬수 있다는 (획기적인) 방법이 있다는 것을 듣고 직접 실행 시켜 보았습니다. 프로그램안에서 외부 프로그램을 동작 시켜 볼 수 있다는 점에서 참 재미가 있었네요.

1) WinExec 함수

외부 프로그램을 동작 시킬 수 있는 함수들 중에서 제일 먼저 사용된 그래서 오래된 함수(win3.x 버전부터 사용된 함수입니다.)는 WinExec함수입니다.

이 함수의 프로토 타입은

UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);

으로 사용방법은 아래와 같습니다.

WinExec("C:/Program Files/Internet Explorer/IEXPLORE.EXE",SW_SHOW);
혹은 WinExec("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",SW_SHOW);

로 프로그램안에서 위 함수를 위와 같이 인자를 넣으면 인터넷 익스프롤러가 실행이되는 구문입니다.

이 함수의 장점은 인자가 2개뿐이어서 사용하기는 간편다는 것이지만,
단점으로는 실행을 시켜 놓으면 실행이 되는지 에러가 났는지, 종료 되었는지 전혀 알수가 없다는 것입니다.

2) CreateProcess 함수

다음은 CreateProcess()의 Prototype입니다.

BOOL CreateProcess(
LPCTSTR lpApplicationName, // 실행파일 모듈의 이름에 대한 포인터
LPTSTR lpCommandLine, // 커맨드 문자열에 대한 포인터
LPSECURITY_ATTRIBUTES lpPA, // 프로세스 보안 속성 포인터
LPSECURITY_ATTRIBUTES lpTA, // 스레드 보안속성 포인터
BOOL bInheritHandles, // 핸들 상속 여부 플래그
DWORD dwCreationFlags, // 생성 플래그
LPVOID lpEnvironment, // 환경 블록에 대한 포인터
LPCTSTR lpCurrentDirectory, // 현재 디렉토리
LPSTARTUPINFO lpStartupInfo, // STARTUPINFO 포인터
LPPROCESS_INFORMATION lpPI // PROCESS_INFORMATION 포인터
);

이 함수의 실행 방법은 아래와 같습니다.

STARTUPINFO StartupInfo = {0};
PROCESS_INFORMATION ProcessInfo;
StartupInfo.cb = sizeof( STARTUPINFO );
::CreateProcess("C:/Program Files/Internet Explorer/IEXPLORE.EXE",
NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo);

만약 위의 프로그램을 실행시키고 종료하기를 기다린다고 하면,

BOOL ret = CreateProcess(............);
if(!ret)
return FALSE;

WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
return TRUE;

이렇게 하면 됩니다.

3) ShellExecute 함수

이 함수의 원형은 아래와 같습니다.

HINSTANCE ShellExecute(
HWND hwnd, // 부모 윈도우 핸들
LPCTSTR lpVerb, // 동사 혹은 작업
LPCTSTR lpFile, // 실행 대상 문서
LPCTSTR lpParameters, // 컴맨드 인자
LPCTSTR lpDirectory, // 현재 디렉토리
INT nShowCmd // 보여주기 옵션
);

일단 위의 함수를 살펴보면 CreateProcess() 함수보다 기능이 많이 떨어지는 것 처럼 보이지만 이 함수의 진정한 의미는 동사 연결이라는 점입니다.
보통 우리가 말하는 [연결 프로그램]을 지칭합니다.

이 함수는 아래와 같이 사용할 수 있습니다.

ShellExecute(NULL,
"open",
//"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", // 경로가 이렇게도 사용가능
"C:/Program Files/Internet Explorer/IEXPLORE.EXE",
NULL,NULL,SW_SHOW);

이 함수는 3번째 인자에 다양한 타입을 열수 있도록 되어 있으므로 다양한 응용이 가능한 함수가 되겠습니다.

 

Posted by wakira
,