2011-09-23 4 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

Im 실행중인 다른 응용 프로그램으로 전환하려고합니다. 앱이 무엇인지 상관하지 말라. 버튼 이벤트만으로도 그 작업을 수행 할 수 있기를 원한다. 내가 이해 한 바로는 작업 관리자에 나타나는 프로세스 이름에서 호출 할 수 있습니다. 그것의 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가'다음을 사용하여 현재 상황 임에 존재하지 않는 존재하지 않습니다. using System; using System.Collections; 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.Threading; using System.IO; using System.Runtime.InteropServices; using 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()); 
    } 
} 
} 

위해 일한 행에 프로세스 이름을 정의 생각 다음하지만 난 해달라고 창을 최소화하면 작동합니다.

코드 :

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

사용 :

SwitchToThisWindow(arrProcesses[0].MainWindowHandle, true); 
관련 문제