天天看點

轉:ShellExecute函數與ShellExecuteEx函數

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);

}

繼續閱讀