천객만래 [千客萬來] (It has an interminable succession of visitors)

CreateProcess 함수 예제 소스코드





/*
 * 출처 : 
http://sosal.tistory.com/
 * made by so_Sal
 */


CreateProcess 라는 함수를 이용하여
Notepad를 실행시키는 간단한 소스입니다.
이해가 가지 않는 부분이 있다면
아래 링크를 참조하세요.
LINK_

====================== CreateProcess ======================

#include<stdio.h>
#include<windows.h>
#include<tchar.h>

#define DIR_LEN BUFSIZ
//BUFSIZ는 운영체제마다 다른 크기를 가지고 있습니다.
//한번 크기를 출력해보시는것도 좋겠네요.

int _tmain(int argc, TCHAR* argv[]){
 STARTUPINFO si = {0,};    //구조체 선언, 초기화
 PROCESS_INFORMATION pi;
 
 si.cb = sizeof(si);
 si.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE;
 //Flags 값들이 여러가지가 있습니다.
 //STARTF_USEPOSITION :: dwX, dwY 위치 사용
 //STARTF_USESIZE     :: dwXSize, dwYSize 사용
 //Flags 값이 주어지지 않는 si구조체 값은
 //새로 만들어지는 프로세스에 영향을 주지 않습니다.
 si.dwX = 100;
 si.dwY = 100;
 si.dwXSize = 300;
 si.dwYSize = 300;  //dw ~ 는 사실 잘 쓰이지 않습니다.

 si.lpTitle = _T(" Child process! ");
 
 TCHAR command[] = _T("notepad 10 10");
 //10 10은 argv[]로 들어가겠죠, 아래 결과를 보시면
 //notepad의 이름으로 들어간다는걸 확인하실 수 있습니다.

 BOOL state;

 state = CreateProcess(
  NULL, //여기에 이름을 넣을 수 있습니다.
  command, // 경로를 System에 해줬기 때문에 notepad가 열릴 수 있죠!
  NULL,NULL, 
  TRUE, //부모프로세스중 상속가능한 핸들 상속
  CREATE_NEW_CONSOLE, //dwCreationFlags
  NULL,NULL,
  &si, //STARTUPINFO 구조체 정보를 위에서 만들어줬죠.
  &pi  //이젠 프로세스의 정보를 가져올때 이 구조체를 사용!
 );

 if(state!=0){
  _fputts(_T("Creation OK! \n"), stdout);
 }
 else{
  _fputts(_T("Creation Fail! \n"), stdout);
 }

 return 0;
}


=======================================================================================


프로세스 :: 시스템 자원들을 포함하는 하나의 주소공간

프로세스는 프로그램 코드, 자료, 변수들, 열린 파일들,
그리고 환경으로 구성됩니다.
하드 메모리에 저장되어 있는 프로그램을 시스템 메모리에 끌어와
하드메모리에 존재하는 하나의 복사본만 존재할 수 있도록
프로그램 코드와 시스템 라이브러리들을 여러 프로세스들이 공유하게 합니다.
더 자세한 내용은 이전에 쓴 '04. Windows 프로세스' 글을 참조하시고
여기서는 프로세스 생성 함수에 대해서 설명하겠습니다.
(프로세스가 새로운 프로세스를 실행시키는것)


프로세스의 생성

하나의 프로세스가 새로운 프로세스를 만든다면,(CreateProcess)
원래의 프로세스는 부모 프로세스라고 하고,
새로 만들어진 프로세스는 자식 프로세스라고 합니다.

그렇다면, 이것은 바탕화면에서 프로그램을 더블클릭하여
생성한 프로세스와 다른것인가?
아닙니다. 바탕화면을 보여주는것도 프로세스입니다.
바탕화면 관리자에서 보여지는 프로그램을 실행시킨다면 (더블클릭)
바탕화면 관리자는 부모프로세스, 실행된 프로세스는 자식 프로세스가 됩니다.
ㅇㅋ?



** :: CreateProcess :: **
MSDN :: 
http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx ::
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 구조체 변수의 주소값을 받음
);

9번째 인자 LPSTARTUPINFO 에 정보를 저장하여
CreateProcess를 통하여 프로세스를 생성합니다.
그럼 프로세스의 정보를 다시 가져올때는?
LPPROCESS_INFORMATION을 통해 가져오게 됩니다.

아.. 그런데 위에 CreateProcess 함수 하나에 매개변수가 10개고..
미친듯이 외워야 할거같고,.. 답답..합니다.
저거 다 외워서 쓰는사람... 아무도 없습니다.
공부할때 한번쯤 훑어주고..
중요하게 굵게 써놓은거 정도만 자세히 봐주고...
넘어갑시다!!!!
아주 많이 사용되는 함수도 아닐 뿐더러
책을 보던가 인터넷 조금만 뒤져봐도
상당히 자세히 나와있고, 예제도 널려있으니
그거 보고 프로그래밍 하시면 됩니다!

위 함수를 실행하면 새로운 프로세스가 생성되는데..
프로그램이 부모 프로세스가 되고, 프로그램 안에서 함수에 의해 새로 생성된 프로세스는
자식 프로세스라고 말합니다.

CreateProcess의 첫번째로 전달되는 인자를 통해서 실행파일의 이름이 전달하는 경우에는
현재 디렉터리를 기준으로 실행파일을 찾게 된다.
하지만 두번째 인자로 (첫번째에 NULL을 넣고) 전달되는 경우에는
표준 검색경로 순서대로 실행파일을 찾는다.

1.프로세스의 실행파일이 존재하는 풀더
2.실행중인 프로세스의 현재 풀더
3.windows의 시스템 풀더(system Directory)
4.windows풀더 (windows directory)
5.환경변수 PATH


함수 매개변수의 9번째 매개변수를 보면 STARTUPINFO 라는 구조체가 있다고 나오는데,
그 구조체에 대해서 살펴봅시답!
이것은 새롭게 생성할 프로세스에 정보를 입력하기 위한 구조체입니다.

LPSTARTUPINFO의 구조이다.
MSDN :: 
http://msdn.microsoft.com/en-us/library/ms686331(VS.85).aspx ::

typedef struct _STARTUPINFO {
  DWORD  cb;                           //구조체 변수 크기
  LPTSTR lpReserved;
  LPTSTR lpDesktop;
  LPTSTR lpTitle;                      // 타이틀 바 제목
  DWORD  dwX;                        // 시작될 프로세스 윈도우의 x좌표
  DWORD  dwY;                        // 시작될 프로세스 윈도우의 y좌표
  DWORD  dwXSize;                  // 윈도우의 가로길이
  DWORD  dwYSize;                  // 윈도우의 세로길이
  DWORD  dwXCountChars;
  DWORD  dwYCountChars;
  DWORD  dwFillAttribute;
  DWORD  dwFlags;                   // 설정된 멤버의 정보
  WORD   wShowWindow;
  WORD   cbReserved2;
  LPBYTE lpReserved2;
  HANDLE hStdInput;           // 이 글에서는 CreateProcess에 대해서
  HANDLE hStdOutput;         // 적당히 살펴보는 취지라..
  HANDLE hStdError;           // 핸들에 대한 내용은 넘기겠습니다.
} STARTUPINFO, *LPSTARTUPINFO;

첫번째 인자 DWORD cb가 중요한 이유는
CreateProcess 함수에서 9번째에 들어갈 프로세스 정보 구조체에 들어가는 구조체가
혹시나 다음에 바뀔 수도 있고, 다양한 구조체가 들어갈 수 있게 하기 위해서 둔것인데,
즉 정보를 전달하는 구조체가 무엇인지 구분짓겠다는 의도라고 생각하시면 되겠네요.


Posted by SB패밀리





직접 예제를 만들수도 있지만 시간상 핑계로 인터넷에 있던 팁들을 나열했다.


Q: I want to bring up the Windows Find window on a particular folder.
A: We use the find verb as the operation parameter and we have the Windows Find window open up with the directory we have specified. This can be rather handy if you want to allow users to find some file within some folder. Just ask them for their folder and pop up a Find Window which has their folder as the root folder.

ShellExecute(m_hWnd,"find","d:\\nish",
    NULL,NULL,SW_SHOW);Big Brother - ShellExecuteEx
ShellExecuteEx is a more flexible call, in that it allows us to retrieve information about the program we just spawned. You'll need to fill up the SHELLEXECUTEINFO structure and pass it's address to ShellExecuteEx. Please lookup both on your copy of MSDN.

Q: How do I start a program, and halt execution of my current program, till that program exits?
A: You start the program using ShellExecuteEx and use WaitForSingleObject on the process handle.

SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";  
ShExecInfo.lpParameters = ""; 
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL; 
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);


Q: I want to show the File or Folder properties window for a file or a folder.
A: This time what we do is to pass properties as the operation verb. We also need to specify SEE_MASK_INVOKEIDLIST as the fmask parameter of the SHELLEXECUTEINFO structure. That's why we have to use ShellExecuteEx here instead of ShellExecute. I owe this tip to David Lowndes, Microsoft MVP because it was David who helped me with that tip about the SEE_MASK_INVOKEIDLIST flag.

SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\\"; //can be a file as well
ShExecInfo.lpParameters = ""; 
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL; 
ShellExecuteEx(&ShExecInfo);


CreateProcess - an ultra brief introduction

The CreateProcess function is part of Kernel32.dll. Windows uses this call to create a new process and a primary thread for the new process. The primary thread then starts executing the specified executable. Normally, if this is a C++  program, execution starts with your WinMain [actually prior to this the CRT library is loaded and initialized]. For a more comprehensive tutorial on the use of CreateProcess, I recommend that you read Joseph M Newcomer's article, An Introduction to Processes: Asynchronous Process Notification.

PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("c:\\winnt\\notepad.exe", NULL, 
    NULL,NULL,FALSE,0,NULL,
    NULL,&StartupInfo,&ProcessInfo))

    WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
}  
else
{
    MessageBox("The process could not be started...");
}
As you can observe, I am using WaitForSingleObject on the process handle. But since CreateProcess creates a thread object in addition to the process object, I might as well have waited on the thread handle as in :-

WaitForSingleObject(ProcessInfo.hThread,INFINITE);This might cause problems though if, for some reasons, one or more of your secondary threads are still active even after the main thread finishes. MSDN says that a process is fully terminated only when all it's threads have ceased execution. So I recommend that you wait on the process handle rather than on the thread handle.

// 디폴트 브라우저 감지하기
void GetDefaultBrowser(LPTSTR szBrowerName)
{
HFILE h = lcreate("dummy.htm", 0);
_lclose(h);

FindExecutable("dummy.htm", NULL, szBrowserName);
DeleteFile("dummy.htm");
}

// 파일에 연결된 프로그램 경로 읽어오기
HINSTANCE FindExecutableEx(... 인자는 동일하다 ...) 

TCHAR drive[_MAX_DRIVE]; 
TCHAR dir[_MAX_DIR]; 
TCHAR dir1[_MAX_DIR]; 
TCHAR file[_MAX_FILE]; 
TCHAR ext[_MAX_EXT];

HINSTANCE hi = FindExecutable(file, dir, result); 
result[lstrlen(result)] = 32;

_splitpath(result, deive, dir, file, ext);

LPTSTR p = strchr(dir, ':'); 
if(p != NULL) 

--p; 
dir[p-dir] = 0; 
_splitpath(dir, NULL, dir1, file, ext); 
p = strchr(ext, 32); 
ext[p-ext] = 0; 
_makepath(result, drive, dir1, file, ext); 

return hi; 



출처 : 인터넷


Posted by SB패밀리
[delphi] Execute and wait for termination (16 and 32bit applications)

http://www.delphifaq.com/faq/delphi_windows_API/f353_0.htm

This unit is based upon the well-known and largely used WinExecAndWait function The former WinexecAndWait function doesn't compile under Delphi 2.0 because the GetModuleUsage function is no longer supported under Win95.

I have simply updated the previous code so that it works with Delphi 2.0 under Windows 95. With this function you can call Windows-based applications as well as Dos-based commands. That is 'c:\myapp\app32.exe' as well as command.com /c del *.bak'.

This new WinexecAndWait32 is intended for Delphi 2.0 Win95 only, it works for me but you use it at your own risk:


   
 unit WinExc32;
// Author    : Francis Parlant.
// Update    : Bill Rinko-Gay
// Parameters:
//    Path: a null terminated string with the command line
//    Visibility: Windows SHOW constant such as WS_RESTORE
//    Timeout: DWORD time in miliseconds or INFINITE to wait forever 
//
// The previous version went into a loop, constantly checking to see
// if the exec'ed program had terminated.  This version uses the Win95
// API call to WaitForSingleObject to block processing until the
// exec'ed program has terminated.  The return value will be either
// an error code from the CreateProcess function, or the result
// of the wait.

interface

uses Windows;

function WinExecAndWait32(Path: PChar; Visibility: Word;
  Timeout : DWORD): integer;

implementation

function WinExecAndWait32(Path: PChar; Visibility: Word;
  Timeout : DWORD): integer;
var
  WaitResult : integer;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  iResult : integer;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  with StartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
{ you could pass sw_show or sw_hide as parameter: }
    wShowWindow := visibility;
  end;
  if CreateProcess(nil,path,nil, nil, False,
NORMAL_PRIORITY_CLASS, nil, nil,
StartupInfo, ProcessInfo) then
  begin
    WaitResult := WaitForSingleObject(ProcessInfo.hProcess, timeout);
    { timeout is in miliseconds or INFINITE if
 you want to wait forever }
    result := WaitResult;
  end
  else
  { error occurs during CreateProcess see help for details }
    result:=GetLastError;
end;

end.
 

Posted by SB패밀리
출처 : http://www.jiniya.net

DllMain에서 다음 작업들은 절대로 하지 말 것.

1.LoadLibrary, LoadLibraryEx 호출. 데드락이나 크래시를 유발한다.
2.다른 스레드와 동기화. 데드락을 유발한다.
3.로더 락을 획득하려는 코드가 가지고 있는 동기화 오브젝트를 획득하려는 시도. 데드락을 유발한다.
4.CoInitializeEx를 사용한 COM 스레드 초기화. 특정 조건이 충족될 경우 이 함수는 LoadLibraryEx를 호출한다.
5.레지스트리 함수들. 이 함수들은 advapi32.dll에 구현되어 있다. advapi32.dll이 초기화 되지 않았다면 크래시가 발생할 수 있다.
6.CreateProcess 호출. 프로세스 생성은 다른 DLL을 로드할 수 있다.
7.ExitThread 호출. DLL 디태치(detach) 과정 중에 스레드를 종료하면 로더 락을 다시 획득하도록 만들 수 있다. 이는 데드락이나 크래시가 유발된다.
8.CreateThread 호출. 동기화만 하지 않는다면 스레드 생성은 괜찮을 수 있다. 하지만 위험하다.
9.네임드 파이프나 네임드 오브젝트 생성 (2000만 해당한다). 윈도우 2000에서 네임드 오브젝트 생성은 터미널 서비스 DLL에서 구현되어 있다. 해당 DLL이 초기화되어 있지 않다면 크래시.
10.CRT에 포함된 메모리 관리 함수들. CRT DLL이 초기화되어 있지 않다면 크래시.
11.user32.dll이나 gdi32.dll에 포함된 함수 호출. 일부 함수들은 다른 DLL을 로드하고, 이 사실은 크래시가 발생할 수 있다는 것을 의미한다.
12.관리된 코드 사용.

* 가장 아름다운 DllMain은 존재하지 않는 것이다 (비어 있는 함수 바디).
** 그래도 먼가 하고 싶다면 kernel32.dll에 포함된 함수 중에 위에서 언급되지 않은 것들만 쓰도록 한다. kernel32.dll이 초기화는 운영체제가 보장해 준다. 
*** 글로벌 오브젝트에 대한 초기화 코드 또한 DllMain 과정에 포함된다. 따라서 글로벌 오브젝트의 생성자 내지는 초기화 함수 부분에 위에서 언급한 내용이 있어서는 안된다.
**** 초기화를 하지 말란 소린가? 아니다. 지연시키라는 말이다.
Posted by SB패밀리

직접 예제를 만들수도 있지만 시간상 핑계로 인터넷에 있던 팁들을 나열했다.


Q: I want to bring up the Windows Find window on a particular folder.
A: We use the find verb as the operation parameter and we have the Windows Find window open up with the directory we have specified. This can be rather handy if you want to allow users to find some file within some folder. Just ask them for their folder and pop up a Find Window which has their folder as the root folder.

ShellExecute(m_hWnd,"find","d:\\nish",
    NULL,NULL,SW_SHOW);Big Brother - ShellExecuteEx
ShellExecuteEx is a more flexible call, in that it allows us to retrieve information about the program we just spawned. You'll need to fill up the SHELLEXECUTEINFO structure and pass it's address to ShellExecuteEx. Please lookup both on your copy of MSDN.

Q: How do I start a program, and halt execution of my current program, till that program exits?
A: You start the program using ShellExecuteEx and use WaitForSingleObject on the process handle.

SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";  
ShExecInfo.lpParameters = ""; 
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL; 
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);


Q: I want to show the File or Folder properties window for a file or a folder.
A: This time what we do is to pass properties as the operation verb. We also need to specify SEE_MASK_INVOKEIDLIST as the fmask parameter of the SHELLEXECUTEINFO structure. That's why we have to use ShellExecuteEx here instead of ShellExecute. I owe this tip to David Lowndes, Microsoft MVP because it was David who helped me with that tip about the SEE_MASK_INVOKEIDLIST flag.

SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\\"; //can be a file as well
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);


CreateProcess - an ultra brief introduction

The CreateProcess function is part of Kernel32.dll. Windows uses this call to create a new process and a primary thread for the new process. The primary thread then starts executing the specified executable. Normally, if this is a C++  program, execution starts with your WinMain [actually prior to this the CRT library is loaded and initialized]. For a more comprehensive tutorial on the use of CreateProcess, I recommend that you read Joseph M Newcomer's article, An Introduction to Processes: Asynchronous Process Notification.

PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("c:\\winnt\\notepad.exe", NULL,
    NULL,NULL,FALSE,0,NULL,
    NULL,&StartupInfo,&ProcessInfo))
{
    WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);

else
{
    MessageBox("The process could not be started...");
}
As you can observe, I am using WaitForSingleObject on the process handle. But since CreateProcess creates a thread object in addition to the process object, I might as well have waited on the thread handle as in :-

WaitForSingleObject(ProcessInfo.hThread,INFINITE);This might cause problems though if, for some reasons, one or more of your secondary threads are still active even after the main thread finishes. MSDN says that a process is fully terminated only when all it's threads have ceased execution. So I recommend that you wait on the process handle rather than on the thread handle.

// 디폴트 브라우저 감지하기
void GetDefaultBrowser(LPTSTR szBrowerName)
{
HFILE h = lcreate("dummy.htm", 0);
_lclose(h);

FindExecutable("dummy.htm", NULL, szBrowserName);
DeleteFile("dummy.htm");
}

// 파일에 연결된 프로그램 경로 읽어오기
HINSTANCE FindExecutableEx(... 인자는 동일하다 ...)
{
TCHAR drive[_MAX_DRIVE];
TCHAR dir[_MAX_DIR];
TCHAR dir1[_MAX_DIR];
TCHAR file[_MAX_FILE];
TCHAR ext[_MAX_EXT];

HINSTANCE hi = FindExecutable(file, dir, result);
result[lstrlen(result)] = 32;

_splitpath(result, deive, dir, file, ext);

LPTSTR p = strchr(dir, ':');
if(p != NULL)
{
--p;
dir[p-dir] = 0;
_splitpath(dir, NULL, dir1, file, ext);
p = strchr(ext, 32);
ext[p-ext] = 0;
_makepath(result, drive, dir1, file, ext);
}
return hi;
}


출처 : 인터넷

Posted by SB패밀리

외부 프로세스 실행을 위한 소스
아래 함수는 Windows 7 에서 관리자 권한으로 실행이 가능하게 하는 코드이다.
MFC 개발하시분 분들에게는 많이 유용할 것이다.
쌈꼬쪼려 소백촌닭

=======================================================
사례1

// 프로세스 실행
BOOL SBRICH::ExecuteProcess(CString FilePath, CString Parameter)

 //TCHAR path[1024] = {0,};
 //::GetModuleFileName(NULL, path, 1024);
 BOOL bRes = FALSE;

 if(OSVersionXPOver())
 {
  // 관리자 모드로 실행
  SHELLEXECUTEINFO exeInfo = {0,};

  exeInfo.cbSize = sizeof(SHELLEXECUTEINFO);
  exeInfo.hwnd = NULL;
  exeInfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
  exeInfo.lpVerb = _T("runas");
  exeInfo.lpFile = FilePath;
  exeInfo.lpParameters = Parameter;
  exeInfo.nShow = SW_SHOWNORMAL;

  bRes = ::ShellExecuteEx(&exeInfo);

 }
 else
 {
  //xp 이하이므로 그냥 호출.
  if( ::ShellExecute(NULL, _T("open"), FilePath, Parameter, NULL, SW_SHOW) == (HINSTANCE)HINSTANCE_ERROR)
   bRes = FALSE;
  else
   bRes = TRUE;
 }

 return bRes;
}


===================================================================
사례2

// 프로세스 실행
BOOL SBRICH::ExecuteProcess(CString FilePath, CString Parameter)

 //TCHAR path[1024] = {0,};
 //::GetModuleFileName(NULL, path, 1024);
 BOOL bRes = FALSE;

 if(OSVersionXPOver())
 {
  // 관리자 모드로 실행
  CString sRun;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  si.lpDesktop = "winsta0\\default";
  ZeroMemory(&pi, sizeof(pi));

  sRun = FilePath;
  sRun += Parameter;
  // start the child process
  if (!CreateProcess(NULL, // no module name (use command line)
   (LPSTR)(LPCSTR)sRun, // Command line
   NULL, // Process handle not inheritate
   NULL, // Thread handle not inheritate
   FALSE, // Set handle inheritance to FALSE
   0, // No creation flags
   NULL, // Use parent's environment block
   NULL, // Use parent's starting directory
   &si, // Pointer STARTUPINFO structure
   &pi) // Pointer to PROCESS_INFORMATION structure
   )
  {
#ifdef _DEBBUG
   fprintf(Filelog, "CreateProcess Failed (%d)\n", GetLastError());
   Filelog.flush();
#endif
   return FALSE;
  }
  // wait until child process exits
  WaitForSingleObject(pi.hProcess, INFINITE);
  // Close process and thread handles;
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);   


 }
 else
 {
  //xp 이하이므로 그냥 호출.
  if( ::ShellExecute(NULL, _T("open"), FilePath, Parameter, NULL, SW_SHOW) == (HINSTANCE)HINSTANCE_ERROR)
   bRes = FALSE;
  else
   bRes = TRUE;
 }

 return bRes;
}

Posted by SB패밀리

/*
 * 출처 :
http://sosal.tistory.com/
 * made by so_Sal
 */


CreateProcess 라는 함수를 이용하여
Notepad를 실행시키는 간단한 소스입니다.
이해가 가지 않는 부분이 있다면
아래 링크를 참조하세요.
LINK_

====================== CreateProcess ======================

#include<stdio.h>
#include<windows.h>
#include<tchar.h>

#define DIR_LEN BUFSIZ
//BUFSIZ는 운영체제마다 다른 크기를 가지고 있습니다.
//한번 크기를 출력해보시는것도 좋겠네요.

int _tmain(int argc, TCHAR* argv[]){
 STARTUPINFO si = {0,};    //구조체 선언, 초기화
 PROCESS_INFORMATION pi;
 
 si.cb = sizeof(si);
 si.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE;
 //Flags 값들이 여러가지가 있습니다.
 //STARTF_USEPOSITION :: dwX, dwY 위치 사용
 //STARTF_USESIZE     :: dwXSize, dwYSize 사용
 //Flags 값이 주어지지 않는 si구조체 값은
 //새로 만들어지는 프로세스에 영향을 주지 않습니다.
 si.dwX = 100;
 si.dwY = 100;
 si.dwXSize = 300;
 si.dwYSize = 300;  //dw ~ 는 사실 잘 쓰이지 않습니다.

 si.lpTitle = _T(" Child process! ");
 
 TCHAR command[] = _T("notepad 10 10");
 //10 10은 argv[]로 들어가겠죠, 아래 결과를 보시면
 //notepad의 이름으로 들어간다는걸 확인하실 수 있습니다.

 BOOL state;

 state = CreateProcess(
  NULL, //여기에 이름을 넣을 수 있습니다.
  command, // 경로를 System에 해줬기 때문에 notepad가 열릴 수 있죠!
  NULL,NULL,
  TRUE, //부모프로세스중 상속가능한 핸들 상속
  CREATE_NEW_CONSOLE, //dwCreationFlags
  NULL,NULL,
  &si, //STARTUPINFO 구조체 정보를 위에서 만들어줬죠.
  &pi  //이젠 프로세스의 정보를 가져올때 이 구조체를 사용!
 );

 if(state!=0){
  _fputts(_T("Creation OK! \n"), stdout);
 }
 else{
  _fputts(_T("Creation Fail! \n"), stdout);
 }

 return 0;
}


=======================================================================================


프로세스 :: 시스템 자원들을 포함하는 하나의 주소공간

프로세스는 프로그램 코드, 자료, 변수들, 열린 파일들,
그리고 환경으로 구성됩니다.
하드 메모리에 저장되어 있는 프로그램을 시스템 메모리에 끌어와
하드메모리에 존재하는 하나의 복사본만 존재할 수 있도록
프로그램 코드와 시스템 라이브러리들을 여러 프로세스들이 공유하게 합니다.
더 자세한 내용은 이전에 쓴 '04. Windows 프로세스' 글을 참조하시고
여기서는 프로세스 생성 함수에 대해서 설명하겠습니다.
(프로세스가 새로운 프로세스를 실행시키는것)


프로세스의 생성

하나의 프로세스가 새로운 프로세스를 만든다면,(CreateProcess)
원래의 프로세스는 부모 프로세스라고 하고,
새로 만들어진 프로세스는 자식 프로세스라고 합니다.

그렇다면, 이것은 바탕화면에서 프로그램을 더블클릭하여
생성한 프로세스와 다른것인가?
아닙니다. 바탕화면을 보여주는것도 프로세스입니다.
바탕화면 관리자에서 보여지는 프로그램을 실행시킨다면 (더블클릭)
바탕화면 관리자는 부모프로세스, 실행된 프로세스는 자식 프로세스가 됩니다.
ㅇㅋ?



** :: CreateProcess :: **
MSDN ::
http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx ::
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 구조체 변수의 주소값을 받음
);

9번째 인자 LPSTARTUPINFO 에 정보를 저장하여
CreateProcess를 통하여 프로세스를 생성합니다.
그럼 프로세스의 정보를 다시 가져올때는?
LPPROCESS_INFORMATION을 통해 가져오게 됩니다.

아.. 그런데 위에 CreateProcess 함수 하나에 매개변수가 10개고..
미친듯이 외워야 할거같고,.. 답답..합니다.
저거 다 외워서 쓰는사람... 아무도 없습니다.
공부할때 한번쯤 훑어주고..
중요하게 굵게 써놓은거 정도만 자세히 봐주고...
넘어갑시다!!!!
아주 많이 사용되는 함수도 아닐 뿐더러
책을 보던가 인터넷 조금만 뒤져봐도
상당히 자세히 나와있고, 예제도 널려있으니
그거 보고 프로그래밍 하시면 됩니다!

위 함수를 실행하면 새로운 프로세스가 생성되는데..
프로그램이 부모 프로세스가 되고, 프로그램 안에서 함수에 의해 새로 생성된 프로세스는
자식 프로세스라고 말합니다.

CreateProcess의 첫번째로 전달되는 인자를 통해서 실행파일의 이름이 전달하는 경우에는
현재 디렉터리를 기준으로 실행파일을 찾게 된다.
하지만 두번째 인자로 (첫번째에 NULL을 넣고) 전달되는 경우에는
표준 검색경로 순서대로 실행파일을 찾는다.

1.프로세스의 실행파일이 존재하는 풀더
2.실행중인 프로세스의 현재 풀더
3.windows의 시스템 풀더(system Directory)
4.windows풀더 (windows directory)
5.환경변수 PATH


함수 매개변수의 9번째 매개변수를 보면 STARTUPINFO 라는 구조체가 있다고 나오는데,
그 구조체에 대해서 살펴봅시답!
이것은 새롭게 생성할 프로세스에 정보를 입력하기 위한 구조체입니다.

LPSTARTUPINFO의 구조이다.
MSDN ::
http://msdn.microsoft.com/en-us/library/ms686331(VS.85).aspx ::

typedef struct _STARTUPINFO {
  DWORD  cb;                           //구조체 변수 크기
  LPTSTR lpReserved;
  LPTSTR lpDesktop;
  LPTSTR lpTitle;                      // 타이틀 바 제목
  DWORD  dwX;                        // 시작될 프로세스 윈도우의 x좌표
  DWORD  dwY;                        // 시작될 프로세스 윈도우의 y좌표
  DWORD  dwXSize;                  // 윈도우의 가로길이
  DWORD  dwYSize;                  // 윈도우의 세로길이
  DWORD  dwXCountChars;
  DWORD  dwYCountChars;
  DWORD  dwFillAttribute;
  DWORD  dwFlags;                   // 설정된 멤버의 정보
  WORD   wShowWindow;
  WORD   cbReserved2;
  LPBYTE lpReserved2;
  HANDLE hStdInput;           // 이 글에서는 CreateProcess에 대해서
  HANDLE hStdOutput;         // 적당히 살펴보는 취지라..
  HANDLE hStdError;           // 핸들에 대한 내용은 넘기겠습니다.
} STARTUPINFO, *LPSTARTUPINFO;

첫번째 인자 DWORD cb가 중요한 이유는
CreateProcess 함수에서 9번째에 들어갈 프로세스 정보 구조체에 들어가는 구조체가
혹시나 다음에 바뀔 수도 있고, 다양한 구조체가 들어갈 수 있게 하기 위해서 둔것인데,
즉 정보를 전달하는 구조체가 무엇인지 구분짓겠다는 의도라고 생각하시면 되겠네요.

Posted by SB패밀리

#pragma comment(lib,"ws2_32")

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>

void main(int argc, char *argv[])
{
        STARTUPINFO si;
     PROCESS_INFORMATION pi;

     si.cb= sizeof(STARTUPINFO);
     si.lpReserved= NULL;
     si.lpReserved2   = NULL;
     si.cbReserved2   = 0;
     si.lpDesktop = NULL;
     si.lpTitle   = NULL;
     si.dwFlags   = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
     si.dwX   = 0;
     si.dwY   = 0;
     si.dwFillAttribute   = 0;
     si.wShowWindow   = SW_SHOW;

    

     CreateProcess(NULL,"c:\\windows\\system32\\calc.exe",NULL,NULL,true,dwCreationFlags = DETACHED_PROCESS ,NULL,NULL,&si,&pi);

}

Posted by SB패밀리

XP이상의 윈도우즈에서 UAC 계정관리컨트롤에 따른 관리자 권한으로 외부 어플리케이션을 실행하는 관련 소스
visual c++로 된 것으로 CreateProcess()함수를 사용한다.


TCHAR* serviceName = "";
TCHAR* exePath = "";
STARTUPINFO si;
PROCESS_INFORMATION pi;
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
HANDLE stopServiceEvent = 0;
DWORD exitCode = -1;

void StartExe()
{
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    // Start the child process.
    CreateProcess( NULL, // No module name (use command line).
        exePath, // Command line.
        NULL,             // Process handle not inheritable.
        NULL,             // Thread handle not inheritable.
        FALSE,            // Set handle inheritance to FALSE.
        0,                // No creation flags.
        NULL,             // Use parent's environment block.
        NULL,             // Use parent's starting directory.
        &si,              // Pointer to STARTUPINFO structure.
        &pi );            // Pointer to PROCESS_INFORMATION structure.
}

Posted by SB패밀리