2011-09-23 34 views
1

有人能解釋一下如何通過C#切換到另一個正在運行的程序嗎?切換到另一個正在運行的進程

例如,如果我用按鈕事件創建一個新的應用程序 - 我想使用按鈕來說打電話一個打開的應用程序,如Internet Explorer或Word。

我知道如何啓動應用程序,但不太清楚在運行時如何調用它們。

這是一直在努力迄今:

if (System.Diagnostics.Process.GetProcessesByName("ExternalApplication").Length >= 1) 
    { 
     foreach (Process ObjProcess in System.Diagnostics.Process.GetProcessesByName("ExternalApplication")) 
     { 
      ActivateApplication(ObjProcess.Id); 
      Interaction.AppActivate(ObjProcess.Id); 
      SendKeys.SendWait("~"); 
     } 
    } 
+0

你是什麼意思「叫他們時,他們已經在運行」是什麼意思?你只是想讓他們把注意力集中在用戶的電腦上嗎?你是否試圖爲正在運行的應用程序調用一些API? –

+0

是否確定要切換到其他應用程序(與在應用程序中嵌入瀏覽器控件相反)?有些背景在這裏會有幫助。 如果你真的想切換,我想你想要的是(COM)Interop API(Google是你的朋友:) - 這應該允許你切換到應用程序(如果已經運行)或啓動(如果沒有)。 – David

+0

我只是想切換到另一個正在運行的應用程序。不管是什麼應用程序 - 我只是想通過按鈕事件來做到這一點。根據我的理解,您可以從任務管理器中顯示的進程名稱中調用它。它是一個C#winform我工作。 – Steve

回答

4

我不得不解決類似的問題,我不得不做一些pInvoking把它完成。見下面的代碼。

delegate bool EnumWindowsProc(IntPtr hWnd, int lParam); 
public static class WindowEnumerator 
{ 
    [DllImport("user32.dll", SetLastError = true)] 
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 

    [DllImport("USER32.DLL")] 
    private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); 

    [DllImport("USER32.DLL")] 
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); 

    [DllImport("USER32.DLL")] 
    private static extern int GetWindowTextLength(IntPtr hWnd); 

    [DllImport("USER32.DLL")] 
    private static extern bool IsWindowVisible(IntPtr hWnd); 

    [DllImport("USER32.DLL")] 
    private static extern IntPtr GetShellWindow(); 

    public static IDictionary<IntPtr, string> GetOpenWindowsFromPID(int processID) 
    { 
     IntPtr hShellWindow = GetShellWindow(); 
     Dictionary<IntPtr, string> dictWindows = new Dictionary<IntPtr, string>(); 

     EnumWindows(delegate(IntPtr hWnd, int lParam) 
        { 
         if (hWnd == hShellWindow) return true; 
         if (!IsWindowVisible(hWnd)) return true; 

         int length = GetWindowTextLength(hWnd); 
         if (length == 0) return true; 

         uint windowPid; 
         GetWindowThreadProcessId(hWnd, out windowPid); 
         if (windowPid != processID) return true; 

         StringBuilder stringBuilder = new StringBuilder(length); 
         GetWindowText(hWnd, stringBuilder, length + 1); 
         dictWindows.Add(hWnd, stringBuilder.ToString()); 
         return true; 
        }, 0); 

     return dictWindows; 
    } 
} 

... 

[DllImport("user32.dll")] 
private static extern bool SetForegroundWindow(IntPtr hWnd); 
[DllImport("user32.dll")] 
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 
[DllImport("user32.dll")] 
private static extern bool IsIconic(IntPtr hWnd); 

... 

Process yourProcess = ???; 

Dictionary<IntPtr, string> windows = (Dictionary<IntPtr, string>)WindowEnumerator.GetOpenWindowsFromPID(yourProcess.Id); 
IntPtr mainWindowHandle = IntPtr.Zero; 
foreach (KeyValuePair<IntPtr, string> pair in windows) 
{ 
    if (pair.Value.ToUpperInvariant() == "Main Window Title") 
    { 
     mainWindowHandle = pair.Key; 
     break; 
    } 
} 

if (mainWindowHandle != IntPtr.Zero) 
{ 
    if (IsIconic(mainWindowHandle)) 
    { 
     ShowWindow(mainWindowHandle, 9); 
    } 
    SetForegroundWindow(mainWindowHandle); 
} 
+0

我不斷收到以下錯誤 - 我錯過了一些簡單的? 在當前上下文中不存在名稱'記事本' 當前上下文中不存在名稱'WindowEnumerator' 使用以下代碼進行操作。 使用系統;使用System.Collections的 ; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing;使用System.Linq的 ; using System.Text;使用System.Windows.Forms的 ; using System.Diagnostics;使用System.Threading的 ;使用System.IO的 ; using System.Runtime.InteropServices;使用System.Windows的 ; – Steve

+0

我很抱歉。我最終將我的WindowEnumerator邏輯移動到它自己的類中。請參閱上面的代碼。 – feathj

+1

@jonfen - 我知道這是老問題和答案,但幾分鐘前,我發現你的代碼,它可能救了我幾個小時,試圖通過我自己來解決這個問題。謝謝!!! – Misiu

1

我使用下列但我不認爲已定義的進程名稱正確線31

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 

namespace test_winform_app 
{ 
    public partial class Form2 : Form 
    { 
     public Form2() 
     { 
      InitializeComponent(); 
     } 

[DllImport("user32.dll")] 
private static extern bool SetForegroundWindow(IntPtr hWnd); 
[DllImport("user32.dll")] 
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 
[DllImport("user32.dll")] 
private static extern bool IsIconic(IntPtr hWnd); 

     private void button1_Click(object sender, EventArgs e) 
     { 

      Process yourProcess = Process.GetProcessesByName("notepad"); 

Dictionary<IntPtr, string> windows = (Dictionary<IntPtr, string>)WindowEnumerator.GetOpenWindowsFromPID(yourProcess.Id); 
IntPtr mainWindowHandle = IntPtr.Zero; 
foreach (KeyValuePair<IntPtr, string> pair in windows) 
{ 
    if (pair.Value.ToUpperInvariant() == "Main Window Title") 
    { 
     mainWindowHandle = pair.Key; 
     break; 
    } 
} 

if (mainWindowHandle != IntPtr.Zero) 
{ 
    if (IsIconic(mainWindowHandle)) 
    { 
     ShowWindow(mainWindowHandle, 9); 
    } 
    SetForegroundWindow(mainWindowHandle); 
} 
     } 

     delegate bool EnumWindowsProc(IntPtr hWnd, int lParam); 
     public static class WindowEnumerator 
     { 
      [DllImport("user32.dll", SetLastError = true)] 
      private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 

      [DllImport("USER32.DLL")] 
      private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); 

      [DllImport("USER32.DLL")] 
      private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); 

      [DllImport("USER32.DLL")] 
      private static extern int GetWindowTextLength(IntPtr hWnd); 

      [DllImport("USER32.DLL")] 
      private static extern bool IsWindowVisible(IntPtr hWnd); 

      [DllImport("USER32.DLL")] 
      private static extern IntPtr GetShellWindow(); 

      public static IDictionary<IntPtr, string> GetOpenWindowsFromPID(int processID) 
      { 
       IntPtr hShellWindow = GetShellWindow(); 
       Dictionary<IntPtr, string> dictWindows = new Dictionary<IntPtr, string>(); 

       EnumWindows(delegate(IntPtr hWnd, int lParam) 
       { 
        if (hWnd == hShellWindow) return true; 
        if (!IsWindowVisible(hWnd)) return true; 

        int length = GetWindowTextLength(hWnd); 
        if (length == 0) return true; 

        uint windowPid; 
        GetWindowThreadProcessId(hWnd, out windowPid); 
        if (windowPid != processID) return true; 

        StringBuilder stringBuilder = new StringBuilder(length); 
        GetWindowText(hWnd, stringBuilder, length + 1); 
        dictWindows.Add(hWnd, stringBuilder.ToString()); 
        return true; 
       }, 0); 

       return dictWindows; 
      } 
     } 
    } 
} 
1

下面的代碼爲我工作

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace SingleInstanceWindow 
{ 
static class Program 
{ 
    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool SetForegroundWindow(IntPtr hWnd); 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     var me = Process.GetCurrentProcess(); 
     var arrProcesses = Process.GetProcessesByName(me.ProcessName); 
     if (arrProcesses.Length > 1) 
     { 
      SetForegroundWindow(arrProcesses[0].MainWindowHandle); 
      return; 
     } 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 
} 
} 

上面的代碼不如果窗口最小化,則工作

code:

[DllImport("user32.dll")] 
public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); 

用法:

SwitchToThisWindow(arrProcesses[0].MainWindowHandle, true); 
相關問題