ShellExecute函數
ShellExecute函數原型及參數含義如下:
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,Directory: PChar; ShowCmd: Integer): HINST; stdcall;
hWnd:用于指定父視窗句柄。當函數調用過程出現錯誤時,它将作為Windows消息視窗的父視窗。例如,可以将其設定為應用程式主視窗句柄,即 Application.Handle,也可以将其設定為桌面視窗句柄(用GetDesktopWindow函數獲得)。
Operation:用于指定要進行的操作。其中“open”操作表示執行由FileName參數指定的程式,或打開由FileName參數指定的檔案或檔案夾;“print”操作表示列印由FileName參數指定的檔案;“explore”操作表示浏覽由FileName參數指定的檔案夾。當參數設為nil時,表示執行預設操作“open”。
FileName:用于指定要打開的檔案名、要執行的程式檔案名或要浏覽的檔案夾名。
Parameters:若FileName參數是一個可執行程式,則此參數指定指令行參數,否則此參數應為nil或PChar(0)。
Directory:用于指定預設目錄。
ShowCmd:若FileName參數是一個可執行程式,則此參數指定程式視窗的初始顯示方式,否則此參數應設定為0。
若ShellExecute函數調用成功,則傳回值為被執行程式的執行個體句柄。若傳回值小于32,則表示出現錯誤。
ShellExecute函數用法:
如何打開一個網頁?
如果将FileName參數設定為“http:”協定格式,那麼該函數将打開預設浏覽器并連結到指定的URL位址。若使用者機器中安裝了多個浏覽器,則該函數将根據Windows 9x/NT系統資料庫中http協定處理程式(Protocols Handler)的設定确定啟動哪個浏覽器。 如:ShellExecute(handle,L"open",L" http://www.neu.edu.cn", NULL, NULL, SW_SHOWNORMAL); ShellExecute()函數在HKEY_CLASSES_ROOT\http\shell\open\command下進行搜尋。預設浏覽器在系統資料庫HKEY_CLASSES_ROOT\.htm鍵下的Default設定。
如何激活相關程式,發送EMAIL?
如果将FileName參數設定為“mailto:”協定格式,那麼該函數将啟動預設郵件客戶程式,如Microsoft Outlook(也包括Microsoft Outlook Express)或Netscape Messanger。若使用者機器中安裝了多個郵件客戶程式,則該函數将根據Windows 9x/NT系統資料庫中mailto協定處理程式的設定确定啟動哪個郵件客戶程式。mailto:使用者賬号@郵件伺服器位址?subject=郵件主題&body=郵件正文; 如:ShellExecute(handle, L"open", L" mailto:[email protected]?subject=Hello&Body=This is a test", NULL,NULL, SW_SHOWNORMAL);打開新郵件視窗,并自動填入收件人位址、郵件主題和郵件正文。若郵件正文包括多行文本,則必須在每行文本之間加入換行轉義字元%0a。ShellExecute()函數在HKEY_CLASSES_ROOT\mailto\shell\open\command下搜尋。
如何打開一個程式?
ShellExecute(NULL,L"open",L"notepad.exe", L"c:\\MyLog.log", NULL, SW_SHOW );
如何用系統列印機列印文檔?
ShellExecute(NULL,L"print", L"c:\\abc.txt",NULL, NULL, SW_HIDE);
如何用系統查找功能來查找指定檔案?
ShellExecute(NULL,L"find",L"d:\\nish", NULL, NULL, SW_SHOW);
如何啟動一個程式,直到它運作結束?
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile =L"c:\\MyProgram.exe";
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
或:
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess(L"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(NULL,L"The process could not be started",NULL,NULL);
如何顯示檔案或檔案夾的屬性?
SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = L"properties";
ShExecInfo.lpFile = L"c:\\"; //can be a file as well
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
ShellExecuteEx函數
此部分轉自點選打開連結
ShellExecute()有一個難于使用的重大障礙:它不能傳回或使你知道建立程序的Handle。也就是說,你不能導出程式并在繼續執行之前等待它終止。換句話說ShellExecute()受到了它的16位血統的損害,它僅僅發掘了新的和更有威力的函數CreateProcess()的一個特征子集—WinExec()也支援的子集。然而在4.0以後版本中引進了一個新函數:ShellExecuteEx()。它有一個Shell函數典型的原型,支援多标志,以及上述所有功能,通過提供對程序同步和PIDLs的支援擴充了ShellExecute()。
ShellExecuteEx()函數明确地取代了ShellExecute()。它在shellapi.h中聲明:BOOL ShellExecuteEx(LPSHELLEXECUTEINFO lpExecInfo);
SHELLEXECUTEINFO定義如下:
typedef struct _SHELLEXECUTEINFO
{
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCTSTR lpVerb;
LPCTSTR lpFile;
LPCTSTR lpParameters;
LPCTSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
// 可選的成員
LPVOID lpIDList;
LPCSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
HANDLE hIcon;
HANDLE hProcess;
} SHELLEXECUTEINFO, FAR *LPSHELLEXECUTEINFO;
在使用這個結構之前,我們極力建議你把它充填為0,并設定cbSize到結構的實際長度,操作如下:
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
正如聲明中的注釋所說,結構的成員分成了兩組。實際上,頭一組使ShellExecuteEx()的功能等價于ShellExecute()。而選項成員組使函數更有力,這正是‘Ex’字尾的由來。hwnd, lpVerb, lpFile, lpParameters, lpDirectory 和 nShow成員等價于ShellExecute()的參數,這是我們已經看到的。而hInstApp成員則是一個輸出緩沖,這将由ShellExecute()的傳回值填寫。nShow成員總是表示建立視窗的風格,即使lpFile是一個應用程式,它也僅僅說明應用應該怎樣顯示。無論lpFile是應用程式還是文檔檔案,nShow必須總是指派為SW_型常量,你是知道的,如果設定為0将獲得隐藏視窗。
下面是調用ShellExecuteEx()的最簡單方法:
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.lpFile = __TEXT("explorer.exe");
sei.nShow = SW_SHOW;
sei.lpVerb = __TEXT("open");
ShellExecuteEx(&sei);
ShellExecute()中對應參數的成員之一是fMask。它可以是一個或多個下面值的組合:
标志 描述
SEE_MASK_CLASSKEY 應該使用 hkeyClass 成員
SEE_MASK_CLASSNAME 應該使用 lpClass 成員
SEE_MASK_CONNECTNETDRV lpFile将被解釋成UNC(通用命名習慣)格式的檔案名
SEE_MASK_DOENVSUBST 任何在lpDirectory和lpFile成員中的環境變量都将被展開,例如,%WINDIR% 打開Windows檔案夾
SEE_MASK_FLAG_DDEWAIT 如果函數啟動DDE會話,在傳回之前等待它終止。
SEE_MASK_FLAG_NO_UI 在錯誤情況下不顯示消息框
SEE_MASK_HOTKEY 應該使用 dwHotkey 成員
SEE_MASK_ICON 應該使用 hIcon 成員
SEE_MASK_IDLIST 強制函數使用lpIDList内容代替lpFile
SEE_MASK_INVOKEIDLIST 引起函數使用lpIDList中指定的PIDL。如果這個成員為NULL,則建立一個lpFile的PIDL,并使用這個PIDL。這個标志重載了SEE_MASK_IDLIST
SEE_MASK_NOCLOSEPROCESS 用程序Handle設定hProcess成員。lpIDList成員可以包含一個用于代替lpFile的PIDL。hProcess傳回導出的HPROCESS類型的新程序handle
附加的特征
可選字段适用于某些超出ShellExecute()的附加功能。第一點,也是最重要的一點,可以使用PIDLs來運作應用和打開檔案夾。下面是打開‘列印機’檔案夾的代碼:
LPITEMIDLIST pidl;
SHGetSpecialFolderLocation(NULL, CSIDL_PRINTERS, &pidl);
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.nShow = SW_SHOW;
sei.lpIDList = pidl;
sei.fMask = SEE_MASK_INVOKEIDLIST;
sei.lpVerb = __TEXT("open");
ShellExecuteEx(&sei);
如果指定了SEE_MASK_DOENVSUBST标志,則可以在lpFile和lpDirectory中使用任何環境變量。例如,要打開Windows目錄,可以表示為%WINDIR%。
最後,我們獲得了由ShellExecuteEx()導出的應用的同步能力。在設定了SEE_MASK_NOCLOSEPROCESS位到fMask成員後,新程序的handle将由hProcess成員傳回,是以這一行代碼:WaitForSingleObject(sei.hProcess, INFINITE);将導緻調用的應用阻塞,等待另一個應用終止。
顯示檔案屬性對話框
SEE_MASK_INVOKEIDLIST标志是一個重要标志,因為這是ShellExecuteEx()另一個優于ShellExecute()的亮點:它允許函數象執行靜态動詞那樣喚醒動态動詞。前面解釋過,動态動詞是運作時由Shell擴充的關聯菜單添加的。其工作方法是:如果ShellExecuteEx()不能在靜态動詞清單中找到這個動詞,它就試圖尋找給定檔案的關聯菜單。這個搜尋引出IContextMenu接口指針。然後通過接口暴露的方法喚醒動态動詞。
作為這個操作的結論,我們可以很容易地顯示檔案的屬性對話框—與右擊檔案,然後選擇屬性顯示的對話框相同。這裡是一個簡單的例子函數:
void ShowFileProperties(LPCTSTR szPathName)
{
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.lpFile = szPathName;
sei.nShow = SW_SHOW;
sei.fMask = SEE_MASK_INVOKEIDLIST;
sei.lpVerb = __TEXT("properties");
ShellExecuteEx(&sei);
}