2014. 5. 12. 09:59

어렵다....


나중에 써먹을때가 오겠지머....


---------------------------------------------------


이번장에서 살펴볼 함수들

1.WinExec()

   CreateProcess()

2.ShellExecute()

   ShellExecuteEx()


================= 1. WinExec(), CreateProcess() =================

아래는 WinExec() 와 CreateProcess()를 살펴보겠습니다.


WinExec() 함수는 Windows 3.x 버전에서

새로운 프로세스 (프로그램)을 실행시키는 유일한 함수였습니다.

상당히 간결하게 사용할 수 있는 함수입니다.


WinExec의 문제점은? ::

프로그램이 실행되고 나면 이전의 프로세스가 새로이 생성된

프로세스에게 간섭할 수 없다. (접근 불가)

(프로그램이 제대로 작동하는지, 종료시 리턴값 등)

아래 첫번째 인자에 대한 보안 위험성도 문제점중 하나이다.

결론 :: 아주 간단하게 프로그램을 실행시키기 위한 경우에만 쓰자!

     :: 그외에는 CreateProcess 함수 호출!!

     :: 아래에서 배울 ShellExecute() 함수는 내부적으로 CreateProcess()를 호출


UINT WinExec(

     LPCSTR lpCmdLine,

     UINT uCmdShow);


LPCSTR lpCmdLine // 실행될 프로그램의 경로를 입력받습니다.


절대 경로를 입력시에 절대경로에 맞춰서 실행됩니다.

그 외에 상대경로를 입력시

1. 함수를 실행하는 프로그램이 존재하는 디렉토리

2. Windows System 디렉토리

3. Windows 디렉토리

4. :: PATH :: 환경변수에 등록된 디렉토리

를 순서로 검색하여 실행합니다.


* lpCmdLine 입력시 보안상 문제가 발생한다.

WinExec( "C:\\Program Files\\Games.... " , ...);

이렇게 입력했다고 가정했을때, lpCmdLine으로 넘어가는 인자의 값은

c: -> Program Files -> Games -> 로 검색해서 파일을 찾는다.

하지만 중간에 누군가 악의적으로 "Program.exe"라는 파일을 만들어 놓는다면

위처럼 Program Files를 호출하는 모든 프로세스가 Program.exe 파일을

실행하게 된다. 따라서 인자를 넘길때 " (\" ) 따옴표로 묶는걸 권장한다.

ex)

WinExec( " \"C:\\Program Files\\Games.... \" " , ...);


UINT uCmdShow // 실행되어질 프로그램의 상태 Flag를 나타냄

INT nShowCmd                 // 윈도우 상태 옵션

SW_HIDE                           // 숨긴다

SW_SHOWNORMAL            // Normal 크기로 활성화

SW_SHOWMINIMIZED         // 최소화 크기로 활성화

SW_SHOWMAXIMIZED        // 최대화 크기로 활성화

SW_SHOWNOACTIVATE      // 최근의 위치와 크기로 활성화

SW_SHOW                         // 조건 없이 활성화

SW_MINIMIZE                    // 최소화 상태로 활성화

SW_MAXIMIZE                   // 최대화 상태로 활성화

SW_SHOWDEFAULT            // 초기에 윈도우 생성시의 Flag값에 따라 결정

SW_SHOWMINNOACTIVE    // 최소화 상태로 표시, 이미 활성화되어 있다면 내버려둔다

SW_SHOWNA                     // 현상태 유지


프로그램의 실행이 성공시 리턴값은 31보다 크며,

실패시 아래 에러값들이 리턴됩니다.


Error Code                         :: Description

0                                       :: out of memory, out of resource

ERROR_BAD_FORMAT         :: 실행할 수 있는 파일이 아니다.

ERROR_FILE_NOT_FOUND   :: 정해진 경로에 파일이 없다.

ERROR_PATH_NOT_FOUND :: 정해진 경로가 존재하지 않는다.



아래는 CreateProcess 함수입니다.


BOOL CreateProcess(

    LPCTSTR lpApplicationName,

             //생성될 프로세스의 이름 (NULL을 넣고 IpCommandLine로 전달 가능)

     LPTSTR lpCommandLine,

           //argc. argv[] 인자로 전달할 문자 매개변수. 표준 검색 경로를 기준으로 찾는다.

     LPSECURITY_ATTRIBUTES lpProcessAttributes, //보안 속성을 지정하는 인자. 보통 NULL

     LPSECURITY_ATTRIBUTES lpThreadAttributes,

                           //쓰레드의 보안 속성 지정. NULL 입력시 기본 보안 속성지정

     BOOL bInheritHandles, // TRUE ::부모 프로세스가 소유하는 상속 가능한 핸들을 상속한다.

     DWORD dwCreationFlags, // 프로세스의 특성을 결정짓는 옵션. 사용 안할경우 0 입력

     LPVOID lpEnvironment, //환경변수 지정. NULL 전달시 부모는 자식에게 환경변수 복사

     LPCTSTR lpCurrentDirectory, //생성하는 프로세스의 현재 디렉터리 NULL시 자식위치 = 부모위치

     LPSTARTUPINFO lpStartupInfo, //STARTUPINFO 구조체 변수 초기화후 변수의 포인터를

               //매개변수 로 전달. STARTUPINFO 구조체 변수들은 프로세스의 속성 정보를 전달한다.

     LPPROCESS_INFORMATION lpProcessInformation

            //생성하는 프로세스의 정보를 얻기 위한 매개변수.

               //PROCESS_INFORMATION 구조체 변수의 주소값을 받음

);

다들 잘 알고있을거란 생각에..

자세한 내용은 링크로 대신합니다.

LINK_





================= 2. ShellExecute(), ShellExecuteEx() =================


ShellExecute()함수에 대해서 먼저 설명한다.


HINSTANCE ShellExecute(

     HWND hwnd,                  // 부모가 될 윈도우 핸들

     LPCTSTR lpVerb,           // 실행시 행동

     LPCTSTR lpFile,             // 실행 대상 문서

     LPCTSTR lpParameters,  // argv[] 인자

     LPCTSTR lpDirectory,      // 현재 디렉토리

     INT nShowCmd              // 윈도우 상태 옵션

);


HWND hwnd ::

CreateProcess()는 함수를 실행하는 프로세스가 부모 프로세스가 되지만

ShellExecute() 함수는 부모프로세스를 임의로 지정할 수 있습니다.


HWND hwnd = GetDesktopProcess(); (바탕화면 HWND 리턴. NULL을 집어넣은것과 같음)

HWND hwnd = GetForegroundProcess(); (화면에서 가장 앞에 떠있는 프로세스)


다른 HWND 값을 얻어와서 넣든 간에 IPC 프로그래밍이 아닌 이상

비중있는 인자는 아닙니다. (물론 상황에 따라서.. 중요할수도)


LPCTSTR lpVerb :: <대소문자 관계 없음>

open    // 실제 프로그램을 실행시킨다.

explore // 디렉토리를 lpFile 인자로 전달시에 탐색기로 실행한다.

           // open으로 디렉토리를 실행시키면 단순 풀더만 연다.

           // 실행파일 (.exe 등)을 넣을경우 아무런 반응 없다.

print     // lpFile 매개변수로 들어온 파일을 인쇄한다.

           // 파일의 확장자에 따른 프로그램의 인쇄명령어를 검색하여 실행한다.

           // 프린터나 출력될 포트를 설정하고 싶으면 printto를 사용

find      // lpFile 매개변수로 들어온 디렉토리에 검색창을 띄운다.

           // 디렉토리를 실행할 경우 반응無


LPCTSTR lpParameters,  // argv[] 인자를 넣어준다.

LPCTSTR lpDirectory

     // 현재 디렉토리를 직접 지정할 수 있다.

     // NULL 입력시 프로그램이 실행되는 위치의 Directory가 설정된다.



INT nShowCmd                 // 윈도우 상태 옵션

SW_HIDE                           // 숨긴다

SW_SHOWNORMAL            // Normal 크기로 활성화

SW_SHOWMINIMIZED         // 최소화 크기로 활성화

SW_SHOWMAXIMIZED        // 최대화 크기로 활성화

SW_SHOWNOACTIVATE      // 최근의 위치와 크기로 활성화

SW_SHOW                         // 조건 없이 활성화

SW_MINIMIZE                    // 최소화 상태로 활성화

SW_MAXIMIZE                   // 최대화 상태로 활성화

SW_SHOWDEFAULT            // 초기에 윈도우 생성시의 Flag값에 따라 결정

SW_SHOWMINNOACTIVE    // 최소화 상태로 표시, 이미 활성화되어 있다면 내버려둔다

SW_SHOWNA                     // 현상태 유지


ex)

#include<stdio.h>

#include<tchar.h>

#include<windows.h>


int _tmain(int argc, TCHAR *argv[]){


 HWND hwnd = GetForegroundWindow();

 ShellExecute(hwnd,_T("open"),_T("notepad"),_T("Sosal"),,SW_SHOW);

 ShellExecute(hwnd,_T("find"),_T("c:\\"),NULL,,SW_SHOWMAXIMIZED);

 ShellExecute(hwnd,_T("explore"),_T("c:\\"),NULL,,SW_SHOW);

 //프린트는 제가..;; 없는관계로 ㅇ_ㅇ ;;

Sleep(2000);


 return 0;

}


=== ShellExecuteEx() 함수 설명


BOOL ShellExecuteEx(LPSHELLEXECUTEINFO lpExexInfo);

ShellExecute() 함수에서는, 매개변수로 모든 정보를 넘기는 반면

ShellExecuteEx() 함수는 구조체로 원하는 프로세스의 정보를 모두 담아서

프로세스를 실행시킵니다.


SHELLEXECUTEINFO 구조체의 정의


typedef struct _SHELLEXECUTEINFO {

    DWORD     cbSize;              // 구조체 사이즈(=60)

    ULONG     fMask;               // 옵션

    HWND      hwnd;                // 친 윈도우

    LPCTSTR   lpVerb;             // 동작명

    LPCTSTR   lpFile;              // 파일명

    LPCTSTR   lpParameters;   // 커멘드 라인 파라미터

    LPCTSTR   lpDirectory;       // 기동시 디렉토리

    int       nShow;                   // 표시 형식

    HINSTANCE hInstApp;        // 결과치

    LPVOID    lpIDList;              // 아이템ID리스트

    LPCTSTR   lpClass;           // 클래스명

    HKEY      hkeyClass;          // 파일 클래스의 레지스트리 키

    DWORD     dwHotKey;         // hot key

    union {

        HANDLE  hIcon;             // 파일 클래스의 아이콘

        HANDLE  hMonitor;        // 모니터

    } DUMMYUNIONNAME;

    HANDLE    hProcess;         // 프로세스 핸들

} SHELLEXECUTEINFO, FAR *LPSHELLEXECUTEINFO;


구조체에 대한 자세한 설명은 설명이 잘 되어있는 링크로 넘기겠습니다.

LINK_


cbSize는 전달하는 구조체가 무엇인지 분명히 하기 위한

인자이기 때문에, 꼭 정의해주셔야 합니다.


SHELLEXECUTEINFO sci = {0,};

sci.cbSize = sizeof(SHELLEXECUTEINFO);  // == sizeof(sci);


sci.lpFile = __T("notepad");                // lpFile 역할

sci.nShow = SW_SHOWMAXIMIZED;   // nShowCmd 역할

sci.lpVerb = _T("open");                    // lpVerb 역할


여기까지만 정의해주고 ShellExecuteEx(&sci); 로

함수를 실행해줘도 ShellExecute() 함수와 비슷하게 사용이 가능합니다.



이것 외에 SHELLEXECUTEINFO 구조체를 이용해서

PIDL을 호출하여 더욱 많은 기능을 활용할 수 있다.


//#include<shlobj.h>


LPITEMIDLIST pidl;

SHGetSpecialFolderLocation(NULL, CSIDL_PRINTER, &pidl);


sci.lpIDList = pidl;

sci.fMask = SEE_MASK_INVOKEIDLIST;


ShellExecuteEx(&sci);


fMask에 SEE_MASK_NOCLOSEPROCESS 인자가 들어가있다면

sci 구조체 안에 hProcesss 멤버변수러

새로 생설되어질 프로세스의 핸들을 반환받아

핸들값을 사용할 수 있습니다.

ShellExecute, ShellExecuteEx()

lpverb, lpFile 모두 동적으로 매개변수를 지정할 수 있습니다.


-----------------------------------------------------------


출처 : http://sosal.tistory.com/103


'OLD - 일 > ' 카테고리의 다른 글

html 특수문자 코드표 엔티티코드  (0) 2014.07.01
C - Socket  (0) 2014.06.11
C - Socket : fork  (0) 2014.06.11
Socket - SOL_SOCKET 정리  (0) 2014.06.11
아스키코드 표  (0) 2014.02.05
Posted by 평범한직장인 토끼씨