2013-04-24 8 views
7

यह मेरा कोड है:सी # Process.MainWindowHandle हमेशा रिटर्न IntPtr शून्य

  using (Process game = Process.Start(new ProcessStartInfo() { 
     FileName="DatabaseCheck.exe", 
     RedirectStandardOutput = true, 
     CreateNoWindow = true, 
     UseShellExecute = false })) 
     { 
      lblLoad.Text = "Loading"; 
      int Switch = 0; 

      while (game.MainWindowHandle == IntPtr.Zero) 
      { 
       Switch++; 
       if (Switch % 1000 == 0) 
       { 
        lblLoad.Text += "."; 
        if (lblLoad.Text.Contains("....")) 
         lblLoad.Text = "Loading."; 

        lblLoad.Update(); 
        game.Refresh(); 
       } 
      } 

समस्या है, कि game.MainWindowHandle हमेशा IntPtr.Zero है। मुझे लॉन्चर द्वारा गेम शुरू करने की पुष्टि करने के लिए रन प्रक्रिया की IntPtr को खोजने की आवश्यकता है, इसलिए मैंने गेम को इंटप्रार्ट भेज दिया और लॉन्चर को जवाब देने दें कि यह ठीक है या नहीं। लेकिन इसके लिए, मुझे विशेष रूप से चलने की प्रक्रिया के IntPtr को जानना चाहिए।

अग्रिम धन्यवाद!

उत्तर

10

मुख्य विंडो उस प्रक्रिया द्वारा खोली गई खिड़की है जिसमें वर्तमान में फोकस (टॉपलेवल फॉर्म) है। प्रक्रिया ऑब्जेक्ट को पर रीफ्रेश करने के लिए आपको Refresh विधि का उपयोग करना चाहिए यदि यह बदल गया है तो वर्तमान मुख्य विंडो हैंडल प्राप्त करें।

आप स्थानीय कंप्यूटर पर चल रहे प्रक्रियाओं के लिए केवल MainWindowHandle संपत्ति प्राप्त कर सकते हैं। MainWindowHandle संपत्ति एक मान है जो प्रक्रिया से जुड़े विंडो की विशिष्ट पहचान करता है।

प्रक्रिया में एक ग्राफ़िकल इंटरफ़ेस होने पर एक प्रक्रिया में केवल एक मुख्य विंडो होती है। यदि संबंधित प्रक्रिया में मुख्य विंडो नहीं है, तो MainWindowHandle मान शून्य है। मान छिपी हुई प्रक्रियाओं के लिए शून्य भी है, यानी, प्रक्रियाएं जो टास्कबार में दिखाई नहीं दे रही हैं। यह उन प्रक्रियाओं का मामला हो सकता है जो टास्कबार के बहुत दूर दाईं ओर अधिसूचना क्षेत्र में आइकन के रूप में दिखाई देते हैं।

यदि आपने अभी एक प्रक्रिया शुरू की है और इसकी मुख्य विंडो हैंडल का उपयोग करना चाहते हैं, तो प्रक्रिया को समाप्त करने की अनुमति देने के लिए WaitForInputIdle विधि का उपयोग करने पर विचार करें, यह सुनिश्चित करना कि मुख्य विंडो हैंडल बनाया गया है। अन्यथा, एक अपवाद फेंक दिया जाएगा।

+0

कि घर जब मैं कर रहा हूँ कोशिश करेंगे है। धन्यवाद – Kfirprods

+0

धन्यवाद, यह काम किया। – Kfirprods

+0

ध्यान दें कि 4.5 पर यह अब आवश्यक नहीं है (अनावश्यक - मेरा कोड 4.5 पर काम करता है और जब तक मैं जोड़ा गया तब तक 3.5 तक गिर गया जब तक मैंने जोड़ा। आरफ्रेश() ' – Basic

2
while (!proc.HasExited) 
{ 
    proc.Refresh(); 
    if (proc.MainWindowHandle.ToInt32() != 0) 
    { 
     return proc.MainWindowHandle; 
    } 
} 
+1

हाय, आपकी पोस्ट को" कम गुणवत्ता "के रूप में चिह्नित किया गया है, शायद क्योंकि यह पूरी तरह से कोड के होते हैं। आप वास्तव में कैसे और क्यों सवाल का जवाब दे सकते हैं इसका स्पष्टीकरण प्रदान करके अपने उत्तर में बड़े पैमाने पर सुधार कर सकते हैं? – Ben

3

का संभावित हल सभी उच्च-स्तरीय खिड़कियों के माध्यम से गणना और उनके प्रक्रिया आईडी की जांच जब तक आप एक मैच खोजने के लिए ...


    [DllImport("user32.dll")] 
    public static extern IntPtr FindWindowEx(IntPtr parentWindow, IntPtr previousChildWindow, string windowClass, string windowTitle); 

    [DllImport("user32.dll")] 
    private static extern IntPtr GetWindowThreadProcessId(IntPtr window, out int process); 

    private IntPtr[] GetProcessWindows(int process) { 
     IntPtr[] apRet = (new IntPtr[256]); 
     int iCount = 0; 
     IntPtr pLast = IntPtr.Zero; 
     do { 
      pLast = FindWindowEx(IntPtr.Zero, pLast, null, null); 
      int iProcess_; 
      GetWindowThreadProcessId(pLast, out iProcess_); 
      if(iProcess_ == process) apRet[iCount++] = pLast; 
     } while(pLast != IntPtr.Zero); 
     System.Array.Resize(ref apRet, iCount); 
     return apRet; 
    } 
संबंधित मुद्दे