2010-04-27 17 views
9

मैं अगर विशिष्ट के साथ एक खिड़की एक प्रक्रिया द्वारा खुला किया गया है खोजने की कोशिश कर रहा हूँ के लिए विशिष्ट पाठ के साथ खिड़की का पता लगाएं। यह प्रक्रिया कई खिड़कियों को जन्म देती है, और मुझे उन सभी को जांचना होगा।एक प्रक्रिया

मुझे कोई प्रक्रिया को ढूंढने में कठिनाई,

foreach (Process p in Process.GetProcesses()) 
{ 
    if (p.MainModule.FileName.ToLower().EndsWith("foo.exe")) 
    FindChildWindowWithText(p); //do work 

समस्या आगे क्या करना है है के साथ की है। मैं प्रक्रिया 'MainWindowText का उपयोग नहीं कर सकता, क्योंकि यह जो भी विंडो सक्रिय है के साथ बदलता है।

तब मैं विंडोज समारोह EnumChildWindows और GetWindowText उपयोग करने के लिए कोशिश की है, लेकिन मुझे यकीन है कि अगर मैं EnumChildWindows करने के लिए एक सही संभाल गुजर रहा हूँ नहीं हूँ। EnumChildWindows मेनविंडोहैंडल पारित होने पर अपेक्षित काम करता है, लेकिन निश्चित रूप से मेनविंडोहैंडल सक्रिय विंडो के साथ बदलता है। इसलिए मैंने Process.Handle पास किया, लेकिन ऐप की विंडो स्विच करते समय मुझे अलग-अलग हैंडल और अलग-अलग परिणाम मिलते हैं।

शायद मैं गलत तरीके से यह कर रहा हूं (मैं समझता हूँ कि EnumChildWindows न केवल खिड़कियों, लेकिन नियंत्रण .net बात में को हैंडल देता है, कि कोई समस्या नहीं है, तो मैं भी खिड़की के शीर्षक मिल सकता है) और मुझे एक अलग दृष्टिकोण की आवश्यकता है - दोबारा, मेरी समस्या टेक्स्ट के साथ एक विंडो ढूंढने जितनी सरल है जो विशिष्ट नियमित अभिव्यक्ति से मेल खाती है। इसलिए मुझे शायद एक ऐसे फ़ंक्शन की आवश्यकता होगी जो सभी विंडो को समझाती है, जो टास्कबार में दिखाई दे रही हैं या नहीं।

धन्यवाद

उत्तर

19

एक बार जब आप प्रक्रिया है, तो आप सभी प्रक्रिया और परीक्षण करता है, तो किसी में गणना कर सकते हैं विंडोज उनमें से उस खिड़की से मेल खाते हैं जिसे आप ढूंढ रहे हैं।

आप निम्न पी की आवश्यकता होगी/आह्वान घोषणाओं

[DllImport("user32", SetLastError=true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
private extern static bool EnumThreadWindows(int threadId, EnumWindowsProc callback, IntPtr lParam); 

[DllImport("user32", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); 

[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)] 
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount); 

followng कार्यों कि एक विशिष्ट प्रक्रिया में खिड़कियों को खोजने के लिए इस्तेमाल किया जा सकता की एक जोड़ी का एक उदाहरण है, मैं अपने प्रश्न से समझ गया कि आप प्रक्रिया है, समस्या खिड़कियों की गणना कर रहा है।

public static IntPtr FindWindowInProcess(Process process, Func<string, bool> compareTitle) 
{ 
    IntPtr windowHandle = IntPtr.Zero; 

    foreach (ProcessThread t in process.Threads) 
    { 
    windowHandle = FindWindowInThread(t.Id, compareTitle); 
    if (windowHandle != IntPtr.Zero) 
    { 
     break; 
    } 
    } 

    return windowHandle; 
} 

private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle) 
{ 
    IntPtr windowHandle = IntPtr.Zero; 
    EnumThreadWindows(threadId, (hWnd, lParam) => 
    { 
    StringBuilder text = new StringBuilder(200); 
    GetWindowText(hWnd, text, 200); 
    if (compareTitle(text.ToString())) 
    { 
     windowHandle = hWnd; 
     return false; 
    } 
    return true; 
    }, IntPtr.Zero); 

    return windowHandle; 
} 

तो फिर तुम एक विंडो शीर्षक है कि एक उदाहरण के रूप "एबीसी" के साथ समाप्त होता लगता है FindWindowInProcess समारोह कॉल कर सकते हैं।

IntPtr hWnd = FindWindowInProcess(p, s => s.EndsWith("ABC")); 
if (hWnd != IntPtr.Zero) 
{ 
    // The window was found.... 
} 
किसी भी अभिव्यक्ति उस खिड़की के लिए आपके खोज मानदंडों को पूरा करेगा के साथ

बेशक आप की जगह ले सकता रों => s.EndsWith ("एबीसी"), यह एक regex आदि

यहाँ भी है हो सकता है FindThreadWindow का एक संस्करण जो कि बाल विंडो के पहले स्तर की भी जांच करेगा। यदि आप अपनी खिड़कियां पदानुक्रम में गहरी हैं तो आप इसे आगे ले जा सकते हैं और इसे एक पुनरावर्ती कार्य कर सकते हैं।

private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle) 
{ 
    IntPtr windowHandle = IntPtr.Zero; 
    EnumThreadWindows(threadId, (hWnd, lParam) => 
    { 
    StringBuilder text = new StringBuilder(200); 
    GetWindowText(hWnd, text, 200);   
    if (compareTitle(text.ToString())) 
    { 
     windowHandle = hWnd; 
     return false; 
    } 
    else 
    { 
     windowHandle = FindChildWindow(hWnd, compareTitle); 
     if (windowHandle != IntPtr.Zero) 
     { 
     return false; 
     } 
    } 
    return true; 
    }, IntPtr.Zero); 

    return windowHandle; 
} 

private static IntPtr FindChildWindow(IntPtr hWnd, Func<string, bool> compareTitle) 
{ 
    IntPtr windowHandle = IntPtr.Zero; 
    EnumChildWindows(hWnd, (hChildWnd, lParam) => 
    { 
    StringBuilder text = new StringBuilder(200); 
    GetWindowText(hChildWnd, text, 200);   
    if (compareTitle(text.ToString())) 
    { 
     windowHandle = hChildWnd; 
     return false; 
    } 
    return true; 
    }, IntPtr.Zero); 

    return windowHandle; 
} 
+0

बहुत विस्तृत उत्तर, एक आकर्षण की तरह काम करता है। – Axarydax

+0

FindChildWindow में ... क्या तुलनात्मक परिणाम के परिणाम की जांच करने के बाद एचडब्ल्यूएनडी के बजाय यह HChildWnd नहीं होना चाहिए? – seveves

3

बल्कि प्रक्रियाओं की गणना और खिड़की की खोज, मैं खिड़कियां (EnumWindows का प्रयोग करके) की गणना और प्रक्रिया (GetGuiThreadInfo का प्रयोग करके) पाते हैं की तुलना में।

+0

या GetWindowsThreadProcessId (http://msdn.microsoft.com/en-us/library/ms633522(VS.85).aspx)। –

संबंधित मुद्दे