2011-09-23 36 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); 
相关问题