Voie correcte (in.NET) pour passer à une autre application
c'est Ce que j'ai jusqu'à présent:
Dim bProcess = Process.GetProcessesByName("By").FirstOrDefault
If bProcess IsNot Nothing Then
SwitchToThisWindow(bProcess.MainWindowHandle, True)
Else
Process.Start("C:Program FilesBB.exe")
End If
Il a deux problèmes.
- certains m'ont dit que ce commutateur est déprimé.
- si l'application B est minimisée, cette fonction échoue silencieusement du point de vue de l'utilisateur.
Alors, quelle est la bonne façon de le faire?
7 réponses
Obtenir le handle de la fenêtre (hwnd), et ensuite utiliser cette user32.dll fonction:
VB.net déclaration:
Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Integer) As Integer
C# déclaration:
[DllImport("user32.dll")] public static extern int SetForegroundWindow(int hwnd)
une considération est que cela ne fonctionnera pas si la fenêtre est minimisée, donc j'ai écrit la méthode suivante qui gère aussi ce cas. Voici le code C#, il devrait être assez simple de migrer ceci vers 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);
}
}
en utilisant ce code, il serait aussi simple que de définir le variables de processus et appel BringMainWindowToFront("processName");
Il y a une autre façon, qui utilise L'API D'automatisation de L'interface utilisateur peu connue:
AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
if (element != null)
{
element.SetFocus();
}
La plupart du temps, cela fonctionnera s'il est possible de passer à cette fenêtre. Il y a beaucoup de limitations dans Windows (Sécurité, UAC, configuration spécifique, etc.)...) qui peut vous empêcher de changer l'accent de l'utilisateur final.
J'ai utilisé SetForegroundWindow pour faire apparaître la fenêtre d'une autre application.
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
Comment puis-je me concentrer sur un autre processus à partir de C#?
Créer une Nouvelle Classe dans votre projet et copiez-collez le code ci-dessous.
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);
}
}
maintenant, copiez-collez le code ci-dessous dans votre zone requise.
string procName = Process.GetCurrentProcess().ProcessName;
ProcessHelper.SetFocusToExternalApp(procName);
ici vous appelez la fonction pour attirer l'attention sur la fenêtre de l'autre application.
Importations:
Imports System.Runtime.InteropServices
mettez ceci dans un Module
<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
Utilisation:
FocusWindow("Notepad")
Source: http://www.codeproject.com/Tips/232649/Setting-Focus-on-an-External-application#_rating
Dans VB.Net, vous pouvez utiliser le AppActivate fonction.
Dim App As Process() = Process.GetProcessesByName("program.exe")
If App.Length > 0 Then
AppActivate(App(0).Id)
End If
Ce travail pour moi
[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();
}