如何抓到 ShellExecute 所開啟檔案 的 window handle |
尚未結案
|
uj
一般會員 發表:14 回覆:25 積分:7 註冊:2003-03-06 發送簡訊給我 |
|
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 目前想到的是 等ShellExecute 開啟檔案 後 再來抓秀在最前面那個 但有點問題, 任意開啟一個檔案...不知多久會開得起來 請問有沒好一點的方法 HWND handle; HINSTANCE hInst = ShellExecute(handle, "open", "test.txt", NULL, NULL, SW_SHOWNORMAL); Sleep(1000); handleOpen = GetForegroundWindow();uj 你好: 是否先說明你的目的,也許有更簡單的方法喔 --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
uj
一般會員 發表:14 回覆:25 積分:7 註冊:2003-03-06 發送簡訊給我 |
多謝 RaynorPao 回覆 我用 ShellExecute 開啟檔案 後希望知道這 window 是否還開著
GetWindow( handleOpen, NULL ); 而某些情況我又想把他 關掉
if(handleOpen){
GetWindowThreadProcessId(handleOpen,&dwx);
hProc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwx);
TerminateProcess(hProc, 0);
} 我想要做到這兩件事都需要知道 window handle 有看到討論 WaitForSingleObject(execinfo.hProcess,INFINITE);
好像也不合我的需求 另外我有收到另一封回覆的信函但是卻沒在討論區看到
請問是被刪掉了嗎
|
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 多謝 RaynorPao 回覆 我用 ShellExecute 開啟檔案 後希望知道這 window 是否還開著 GetWindow( handleOpen, NULL ); 而某些情況我又想把他 關掉 if(handleOpen){ GetWindowThreadProcessId(handleOpen,&dwx); hProc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwx); TerminateProcess(hProc, 0); } 我想要做到這兩件事都需要知道 window handle 有看到討論 WaitForSingleObject(execinfo.hProcess,INFINITE); 好像也不合我的需求 另外我有收到另一封回覆的信函但是卻沒在討論區看到 請問是被刪掉了嗎 uj 你好: 以下是我的建議,參考看看 (> --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
uj
一般會員 發表:14 回覆:25 積分:7 註冊:2003-03-06 發送簡訊給我 |
|
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
較可靠的方法 :
1. 用 FindExecutable 找出執行檔(連 Full Path)
2. 用 CreateProcess 來開啟檔案
3. 從 CreateProcess 回傳的 TProcessInformation 提取 dwProcessId 及 hProcess
4. 要取得 Window Handle 較煩,先用 hProcess 給 WaitForInputIdle 去等 Application 完成啟動
5. 使用 EnumWindows 並使用 dwProcessId 作 lParam 去對應出該 Process 的各個 windows
6. 從那些 Windows 找出 MainWindows (沒100%準確的方法,一般是看是否 Hidden, 有沒有 Caption, 是否沒 ParentWindow 等等)
7. 你亦可在 CreateProcess 前先在TStartupInfo設定一些特別的主視窗大小位置以便在 EnumWindows 後作對應條件,可大大的增加認出 Main Window 的機會。 這是我上年花了一個星期在網上找資料及實作的結果,亦成功地在 Delphi 做了出來,但找 WindowHandle 真的沒辦法 100% 準確。若有其他可從 ProcessID 或 hProcess 可準確找到 MainWindow Handle 的方法我亦很想知道。
|
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 多謝 RaynorPao 的回覆 還寫了一段 source code...感謝 只是我想這樣似乎不能確定找到的 > 誰知道較好的方法請告訴我 >>< face="Verdana, Arial, Helvetica"> uj 你好: 請參考以下的做法 < class="code"> HWND ghwnd; BOOL CALLBACK MyEnumWndProc5(HWND hWnd, LPARAM lParam); BOOL CALLBACK MyEnumWndProc5(HWND hWnd, LPARAM lParam) { DWORD id; GetWindowThreadProcessId(hWnd, &id); if(id==(DWORD)lParam) { ghwnd=hWnd; return FALSE; } return TRUE; } //.................................................................... ghwnd=NULL; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb=sizeof(STARTUPINFO); CreateProcess(NULL, "notepad.exe test.txt", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); WaitForInputIdle(pi.hProcess, 4000); EnumWindows((WNDENUMPROC)MyEnumWndProc5, (LPARAM)pi.dwProcessId); if(ghwnd) { char szCaption[256]={0}; GetWindowText(ghwnd, szCaption, 256); ShowMessage(szCaption); } //.................................................................... -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
uj
一般會員 發表:14 回覆:25 積分:7 註冊:2003-03-06 發送簡訊給我 |
|
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 多謝 RaynorPao 與 Justmade 指教 我想做的是 開啟不固定的檔案類型 ( txt, zip, doc...等) 所以我用ShellExecute, 但似乎又無法明確的抓到所開啟的window handle RaynorPao 兄所提的 CreateProcess 的第二個參數 command line , 須自行去指定所開啟檔案的執行檔... 這樣一來...我就得自行依照其副檔名來找系統中可以開檔的ap... 有沒簡單些的用法uj 你好: 其實~~這個問題我也已經想了很久,也做了很多實驗< > 但是~~似乎還找不到一個比較簡單的方法來達成目的< > 你說的問題,目前也只能夠使用 Win32 API FindExecutable 先找到檔案所對應的執行檔(exe),然後再用 CreateProcess 執行 如果覺得可以的話,就先暫時這樣使用吧,有空我再想一想 --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
brant
一般會員 發表:1 回覆:64 積分:23 註冊:2003-04-07 發送簡訊給我 |
引言: 多謝 RaynorPao 與 Justmade 指教 我想做的是 開啟不固定的檔案類型 ( txt, zip, doc...等) 所以我用ShellExecute, 但似乎又無法明確的抓到所開啟的window handle RaynorPao 兄所提的 CreateProcess 的第二個參數 command line , 須自行去指定所開啟檔案的執行檔... 這樣一來...我就得自行依照其副檔名來找系統中可以開檔的ap... 有沒簡單些的用法用 ShellExecuteEx 如何? 把 fMask 設上 SEE_MASK_NOCLOSEPROCESS 就可從 hProcess 的 output 欄位來讀出開啟的 handle 但條件是一定要是新開啟的 process ,如果程式就已經開啟,只是多開一個 MDI 的子視窗來顯示的話,會傳回 NULL,這點要特別注意。 |
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 用 ShellExecuteEx 如何? 把 fMask 設上 SEE_MASK_NOCLOSEPROCESS 就可從 hProcess 的 output 欄位來讀出開啟的 handle 但條件是一定要是新開啟的 process ,如果程式就已經開啟,只是多開一個 MDI 的子視窗來顯示的話,會傳回 NULL,這點要特別注意。brant 你好: 是否能夠冒昧的請教你?? 你有實際試過這個方法嗎??< > 老實說,我第一個實驗的方法,就是你說的這個方法< > 但是,一直沒有辦法成功(找不到用 ShellExecuteEx 執行的 Window Handle) 如果你有這方面的經驗的話,是否願意跟大家分享你的程式碼呢?? --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
brant
一般會員 發表:1 回覆:64 積分:23 註冊:2003-04-07 發送簡訊給我 |
用 ShellExecuteEx 得到的不是 window handle 而是 process handle
以下的 code 可以控制被開啟的外部程式:
SHELLEXECUTEINFO ExecInfo; DWORD exit_code; int i=0; memset(&ExecInfo,0,sizeof(SHELLEXECUTEINFO)); ExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ExecInfo.fMask=SEE_MASK_NOCLOSEPROCESS; ExecInfo.hwnd = NULL; ExecInfo.lpFile = "c:\\test.txt"; ExecInfo.nShow = SW_SHOWNORMAL; MessageBox(NULL,"三十秒後自動關閉","開啟外部檔案",MB_OK); ShellExecuteEx(&ExecInfo); GetExitCodeProcess(ExecInfo.hProcess,&exit_code); while (exit_code==STILL_ACTIVE) { i ; Sleep(1000); if (i==30) { TerminateProcess(ExecInfo.hProcess,0); break; } GetExitCodeProcess(ExecInfo.hProcess,&exit_code); } if (i!=30) { MessageBox(NULL,"程式已被使用者關閉","開啟外部檔案",MB_OK); }發表人 - brant 於 2003/04/22 11:43:28 |
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
引言: uj 你好: 請參考以下的做法 < class="code"> HWND ghwnd; BOOL CALLBACK MyEnumWndProc5(HWND hWnd, LPARAM lParam); BOOL CALLBACK MyEnumWndProc5(HWND hWnd, LPARAM lParam) { DWORD id; GetWindowThreadProcessId(hWnd, &id); if(id==(DWORD)lParam) { ghwnd=hWnd; return FALSE; } return TRUE; } //.................................................................... ghwnd=NULL; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb=sizeof(STARTUPINFO); CreateProcess(NULL, "notepad.exe test.txt", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); WaitForInputIdle(pi.hProcess, 4000); EnumWindows((WNDENUMPROC)MyEnumWndProc5, (LPARAM)pi.dwProcessId); if(ghwnd) { char szCaption[256]={0}; GetWindowText(ghwnd, szCaption, 256); ShowMessage(szCaption); } //....................................................................我不懂寫bcb所以只能談原理,看這程式碼應是和我說的原理相若罷,大家果然所見略同啊。 不過我上次實作時只找出第一個附合pi.dwProcessId的視窗真的不成耶,對notepad 是沒問題,對較複雜的程式找錯的機會很大,很多時會找了該程式的其他視窗(包括隱藏視窗)出來,加了第六點的測試便準確了很多但還不是100%,所以我覺得這還是需要的。 另外若 uj 接受抓秀在最前面那個視窗,其實亦可在 WaitForInputIdle 後去抓而不用 enumWindows,但其實也不大可靠因若使用者中途按了去別的程式便會抓錯了。 |
uj
一般會員 發表:14 回覆:25 積分:7 註冊:2003-03-06 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |