Win32提供了SetForegroundWindow方法能夠將應用設置到前臺並激活,可是在某些場景下,只調用該接口會返回0,即設置失敗。好比以下場景:工具
當前前臺應用爲一個全屏的應用,非前臺應用的進程使用Process.Start()
方法啓動截圖工具,嘗試使用SetForegroundWindow()
將窗口設置到前臺,此時會機率性設置失敗。ui
嘗試了多種方法後,最終使用以下方法解決了該問題:code
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); public const int SWP_NOSIZE = 0x1; public const int SWP_NOMOVE = 0x2; [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hwnd); [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hwnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags); public void StartSnippingTool() { if (!Envronment.Is64BitProcess) { Process.Start(@"C:\Windows\sysnative\SnippingTool.exe"); } else { Process.Start(@"C:\Windows\system32\SnippingTool.exe"); } Thread.Sleep(500); IntPtr snippingToolHandle = FindWindow("Microsoft-Windows-SnipperToolbar", "截圖工具"); if (snippingToolHandle != IntPtr.Zero) { SetForegroundWindowCustom(snippingToolHandle); } } private void SetForegroundWindowCustom(IntPtr hwnd) { IntPtr currentWindow = GetForegroundWindow(); if (currentWindow == hwnd) { Console.WriteLine("應用已在頂層"); return; } SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); bool result = SetForegroundWindow(hwnd); if (result) { Console.WriteLine("置頂應用成功"); } else { Console.WriteLine("置頂應用失敗"); } }