Jon*_*len 35 .net pinvoke process
这是我到目前为止:
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
Run Code Online (Sandbox Code Playgroud)
它有两个问题.
那么这样做的正确方法是什么?
cae*_*say 36
获取窗口句柄(hwnd),然后使用此user32.dll函数:
VB.net声明:
Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Integer) As Integer
Run Code Online (Sandbox Code Playgroud)
C#声明:
[DllImport("user32.dll")] public static extern int SetForegroundWindow(int hwnd)
Run Code Online (Sandbox Code Playgroud)
一个考虑因素是,如果窗口最小化,这将不起作用,所以我编写了以下方法来处理这种情况.这是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);
}
}
Run Code Online (Sandbox Code Playgroud)
使用该代码,就像设置适当的流程变量和调用一样简单 BringMainWindowToFront("processName");
Sim*_*ier 35
还有另一种方法,它使用了不为人知的UI Automation API:
AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
if (element != null)
{
element.SetFocus();
}
Run Code Online (Sandbox Code Playgroud)
大多数情况下,如果可以切换到该窗口,这将有效.Windows(安全性,UAC,特定配置等)中存在许多限制,这些限制可能会阻止您更改最终用户的关注点.
小智 7
在您的项目中创建一个新类并将以下代码复制粘贴到其中。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在将以下代码复制粘贴到您需要的区域。
string procName = Process.GetCurrentProcess().ProcessName;
ProcessHelper.SetFocusToExternalApp(procName);
Run Code Online (Sandbox Code Playgroud)
在这里,您正在调用该函数将焦点移至其他应用程序的窗口。
小智 5
在VB.Net中,可以使用AppActivate函数。
Dim App As Process() = Process.GetProcessesByName("program.exe")
If App.Length > 0 Then
AppActivate(App(0).Id)
End If
Run Code Online (Sandbox Code Playgroud)