Modo corretto (in .NET) per passare lo stato attivo a un’altra applicazione

Questo è quello che ho finora:

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 

Ha due problemi.

  1. Alcune persone mi hanno detto che SwitchToThisWindow è stato privato.
  2. Se l’applicazione B è ridotta a icona, questa funzione non riesce automaticamente dal punto di vista dell’utente.

Quindi qual è il modo giusto per farlo?

Ottenere l’handle di finestra (hwnd) e quindi utilizzare questa funzione user32.dll:

Dichiarazione VB.net:

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

Dichiarazione C #:

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

Una considerazione è che questo non funzionerà se la finestra è ridotta a icona, quindi ho scritto il seguente metodo che gestisce anche questo caso. Ecco il codice C #, dovrebbe essere abbastanza semplice per migrare a 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 running if (bProcess != null) { // check if the window is hidden / minimized if (bProcess.MainWindowHandle == 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 not running, so start it Process.Start(processName); } } 

Usando quel codice, sarebbe semplice come impostare le variabili di processo appropriate e chiamare BringMainWindowToFront("processName");

C’è un altro modo, che utilizza l’API di automazione UI non nota:

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

Il più delle volte, questo funzionerà se è ansible passare a quella finestra. Esistono molte limitazioni in Windows (sicurezza, controllo dell’account utente, configurazione specifica, ecc.) Che possono impedire di modificare l’attenzione dell’utente finale.

Ho usato SetForegroundWindow per far apparire la finestra da un’altra applicazione.

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

Come posso dare un altro focus di processo da C #?

Crea una nuova class nel tuo progetto e copia-incolla il codice qui sotto.

 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); } } 

Ora copia-incolla il codice qui sotto nella tua area richiesta.

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

Qui stai chiamando la funzione per focalizzare l’attenzione sull’altra finestra dell’applicazione.

importazioni:

 Imports System.Runtime.InteropServices 

Metti questo in un modulo

  _ 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 

Uso:

 FocusWindow("Notepad") 

Fonte: http://www.codeproject.com/Tips/232649/Setting-Focus-on-an-External-application#_rating

In VB.Net, è ansible utilizzare la funzione AppActivate .

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

Questo lavoro per me

 [DllImport("user32.dll", SetLastError = true)] static extern void SwitchToThisWindow(IntPtr hWnd, bool turnOn); [STAThread] static void Main() { Process bProcess = Process.GetProcessesByName(processnamehere).FirstOrDefault() ; if (bProcess != null) { SwitchToThisWindow(bProcess.MainWindowHandle, true); } GC.Collect(); }