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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2315561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:57:54  来源:igfitidea点击:

Correct way (in .NET) to switch the focus to another application

.netprocesspinvoke

提问by Jonathan Allen

This is what I have so far:

这是我到目前为止:

    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

It has two problems.

它有两个问题。

  1. Some people have told me that SwitchToThisWindow is depricated.
  2. If application B is minimized, this function silently fails from the user's perspective.
  1. 有人告诉我 SwitchToThisWindow 已被弃用。
  2. 如果应用程序 B 被最小化,从用户的角度来看,这个函数会默默地失败。

So what's the right way to do this?

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

回答by caesay

Get the window handle (hwnd), and then use this user32.dll function:

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

VB.net declaration:

VB.net声明:

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

C# declaration:

C#声明:

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

One consideration is that this will not work if the window is minimized, so I've written the following method which also handles this case. Here is the C# code, it should be fairly straight forward to migrate this to VB.

一个考虑是如果窗口被最小化,这将不起作用,所以我编写了以下方法来处理这种情况。这是 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 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);
    }
}

Using that code, it would be as simple as setting the appropriate process variables and calling BringMainWindowToFront("processName");

使用该代码,只需设置适当的流程变量并调用 BringMainWindowToFront("processName");

回答by Simon Mourier

There is another way, which uses the not well-known UI Automation API:

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

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

Most of the time, this will work if it's possible to switch to that window. There are a lot of limitations in Windows (security, UAC, specific configuration, etc...) that can prevent you to change the end-user focus.

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

回答by Tijo Tom

Create a New Class in your project and copy-paste the below code in it.

在您的项目中创建一个新类并将以下代码复制粘贴到其中。

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

    }
}

Now copy-paste the below code in your required area.

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

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

Here you are calling the function to bring focus to the other application's window.

在这里,您正在调用该函数将焦点移至其他应用程序的窗口。

回答by Snake

In VB.Net, you can use the AppActivatefunction.

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

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

回答by Daniel N

I used SetForegroundWindow to make the window from another application appear.

我使用 SetForegroundWindow 来显示来自另一个应用程序的窗口。

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

How can I give another Process focus from C#?

如何从 C# 提供另一个 Process 焦点?

回答by CrazyTim

Imports:

进口:

Imports System.Runtime.InteropServices

Put this in a 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

Usage:

用法:

FocusWindow("Notepad")

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

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

回答by Kelin

This work for 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();
        }