正确的方式(在.NET中)将焦点切换到另一个应用程序

这是我迄今为止:

Dim bProcess = Process.GetProcessesByName("By").FirstOrDefault If bProcess IsNot Nothing Then SwitchToThisWindow(bProcess.MainWindowHandle, True) Else Process.Start("C:\Program Files\B\B.exe") End If 

它有两个问题。

  1. 有人告诉我,SwitchToThisWindow是depricated。
  2. 如果应用程序B被最小化,则从用户的angular度来看,该function静静地失败。

那么做正确的方法是什么?

获取窗口句柄(hwnd),然后使用这个user32.dll函数:

VB.net声明:

 Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Integer) As Integer 

C#声明:

 [DllImport("user32.dll")] public static extern int SetForegroundWindow(int hwnd) 

一个考虑因素是,如果窗口最小化,这将不起作用,所以我写了下面的方法,也处理这种情况。 这里是C#代码,它应该是相当直接的将其迁移到VB。

 [System.Runtime.InteropServices.DllImport("user32.dll")] [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)] private static extern bool ShowWindow(IntPtr hWnd, ShowWindowEnum flags); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int SetForegroundWindow(IntPtr hwnd); private enum ShowWindowEnum { Hide = 0, ShowNormal = 1, ShowMinimized = 2, ShowMaximized = 3, Maximize = 3, ShowNormalNoActivate = 4, Show = 5, Minimize = 6, ShowMinNoActivate = 7, ShowNoActivate = 8, Restore = 9, ShowDefault = 10, ForceMinimized = 11 }; public void BringMainWindowToFront(string processName) { // get the process Process bProcess = Process.GetProcessesByName(processName).FirstOrDefault(); // check if the process is nothing or not. if (bProcess != null) { // get the hWnd of the process IntPtr hwnd = bProcess.MainWindowHandle; if (hwnd == IntPtr.Zero) { // the window is hidden so try to restore it before setting focus. ShowWindow(bProcess.Handle, ShowWindowEnum.Restore); } // set user the focus to the window SetForegroundWindow(bProcess.MainWindowHandle); } else { // the process is nothing, so start it Process.Start(processName); } } 

使用该代码,就像设置适当的stream程variables和调用BringMainWindowToFront("processName");一样简单BringMainWindowToFront("processName");

还有另一种方法,它使用了不太知名的UI自动化API:

 AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle); if (element != null) { element.SetFocus(); } 

大多数情况下,如果可以切换到该窗口,这将工作。 Windows(安全性,UAC,特定configuration等)有很多限制,可能会阻止您更改最终用户的注意力。

我使用SetForegroundWindow来使另一个应用程序的窗口出现。

 [DllImport("user32.dll")] static extern bool SetForegroundWindow(IntPtr hWnd); 

我怎样才能从C#提供另一个过程焦点?

在你的项目中创build一个新类,并复制粘贴下面的代码。

 using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace MyProject { public class ProcessHelper { public static void SetFocusToExternalApp(string strProcessName) { Process[] arrProcesses = Process.GetProcessesByName(strProcessName); if (arrProcesses.Length > 0) { IntPtr ipHwnd = arrProcesses[0].MainWindowHandle; Thread.Sleep(100); SetForegroundWindow(ipHwnd); } } //API-declaration [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd); } } 

现在将以下代码复制粘贴到您所需的区域。

 string procName = Process.GetCurrentProcess().ProcessName; ProcessHelper.SetFocusToExternalApp(procName); 

这里你正在调用函数来把焦点带到另一个应用程序的窗口。

在VB.Net中,您可以使用AppActivate函数。

 Dim App As Process() = Process.GetProcessesByName("program.exe") If App.Length > 0 Then AppActivate(App(0).Id) End If 

import:

 Imports System.Runtime.InteropServices 

把它放在一个模块中

 <DllImport("user32.dll")> _ Private Function SetForegroundWindow(hWnd As IntPtr) As Boolean End Function Public Sub FocusWindow(ByVal ProcessName As String) Dim p As System.Diagnostics.Process = System.Diagnostics.Process.GetProcessesByName(ProcessName).FirstOrDefault If p IsNot Nothing Then SetForegroundWindow(p.MainWindowHandle) SendKeys.SendWait("~") ' maximize the application if it's minimized End If End Sub 

用法:

 FocusWindow("Notepad") 

资料来源: http : //www.codeproject.com/Tips/232649/Setting-Focus-on-an-External-application#_rating