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





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


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패밀리
[개발/VC++] 외부프로그램 실행완료 기다리기 또는 종료 기다리기

Windows 환경에서 외부 프로그램을 부를 때 종종 ShellExcute 혹은 ShellExcuteEx 또는 WinExec 를 사용한다.

가장 사용방법이 간단한건 ShellExcute와 WinExec 가 있는데 이걸 사용하면 호출한 프로세스가 언제 끝나는지 알 수가 없다. 언제 끝나는지 아는게 중요한 것이 다음과 같은 경우이다. C#에서는 Process 클래스를 사용하면 쉽다.

외부 프로그램이 데이터를 공유하거나 실행순서가 중요할 때에 필요한 방법을 알아보자.
그렇다면 먼저 실행하는 외부프로그램이나 실행하려는 외부프로그램이 종료나 끝나기를 기다려야 하는 경우를 살펴보자.

이를 해결하기 위해서는, First.exe 가 다 끝날때가지 그 다음 코드를 실행하는 것을 멈춰야 한다.
이를 ShellExcuteInfo 를 이용해서 구현해보자

SHELLEXECUTEINFO lpExecInfo;
 lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
 lpExecInfo.lpFile =  "First.exe";
 lpExecInfo.fMask= SEE_MASK_NOCLOSEPROCESS;
 lpExecInfo.hwnd = NULL;
 lpExecInfo.lpVerb = NULL;
 lpExecInfo.lpParameters = "";
 lpExecInfo.lpDirectory = NULL;
 lpExecInfo.nShow = SW_SHOW;
 lpExecInfo.hInstApp = (HINSTANCE) SE_ERR_DDEFAIL; //WINSHELLAPI BOOL WINAPI result;

 int success = ShellExecuteEx(&lpExecInfo);
 WaitForSingleObject(lpExecInfo.hProcess, INFINITE);   // 여기서 계속 기다리게 셋팅하는 것이다.





Posted by SB패밀리