当 MainWindowHandle 为 0 时将 Window 置于前台
Bring Window To Foreground When MainWindowHandle Is 0
如果 MainWindowHandle
不为 0,则以下代码将 window 置于前台。
我怎样才能把 window 放在前面 MainWindowHandle
= 0?
这适用于 Microsoft Excel - 兼容性检查器 window,它显示 GUI 但在任务栏中没有图标并且 MainWindowHandle
= 0。
我没有 Excel 运行.
的其他实例
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"@
$excel = (Get-Process | Where-Object { $_.ProcessName -eq 'EXCEL' }).MainWindowHandle
[void] [Tricks]::SetForegroundWindow($excel)
在 Windows 任务管理器中,我可以右键单击 'Microsoft Excel - Compatibility Checker',然后单击 "Bring To Front",这样就可以了。我如何在 Powershell 中模拟此功能?
感谢 IInspectable 为我指明了正确的方向。
此代码获取真实的 MainWindowHandle
值:
$TypeDef2 = @"
using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Api
{
public class WinStruct
{
public string WinTitle {get; set; }
public int MainWindowHandle { get; set; }
}
public class ApiDef
{
private delegate bool CallBackPtr(int hwnd, int lParam);
private static CallBackPtr callBackPtr = Callback;
private static List<WinStruct> _WinStructList = new List<WinStruct>();
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumWindows(CallBackPtr lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
private static bool Callback(int hWnd, int lparam)
{
StringBuilder sb = new StringBuilder(256);
int res = GetWindowText((IntPtr)hWnd, sb, 256);
_WinStructList.Add(new WinStruct { MainWindowHandle = hWnd, WinTitle = sb.ToString() });
return true;
}
public static List<WinStruct> GetWindows()
{
_WinStructList = new List<WinStruct>();
EnumWindows(callBackPtr, IntPtr.Zero);
return _WinStructList;
}
}
}
"@
Add-Type -TypeDefinition $TypeDef2 -Language CSharpVersion3
$excelInstance = [Api.Apidef]::GetWindows() | Where-Object { $_.WinTitle.ToUpper() -eq "Microsoft Excel - Compatibility Checker".ToUpper() }
所以现在使用这个正确的值,我可以调用 SetForegroundWindow()
函数:
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"@
[void] [Tricks]::SetForegroundWindow($excelInstance.MainWindowHandle)
我在 website 上写了一篇关于此的详细博客。
我已经在 GitHub 上提供了一个完整的示例,说明如何创建 Excel 文件、编辑它以及 运行 上面的代码在您必须的不同线程中这样做是因为 Excel 弹出窗口阻塞了主线程。
如果 MainWindowHandle
不为 0,则以下代码将 window 置于前台。
我怎样才能把 window 放在前面 MainWindowHandle
= 0?
这适用于 Microsoft Excel - 兼容性检查器 window,它显示 GUI 但在任务栏中没有图标并且 MainWindowHandle
= 0。
我没有 Excel 运行.
的其他实例Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"@
$excel = (Get-Process | Where-Object { $_.ProcessName -eq 'EXCEL' }).MainWindowHandle
[void] [Tricks]::SetForegroundWindow($excel)
在 Windows 任务管理器中,我可以右键单击 'Microsoft Excel - Compatibility Checker',然后单击 "Bring To Front",这样就可以了。我如何在 Powershell 中模拟此功能?
感谢 IInspectable 为我指明了正确的方向。
此代码获取真实的 MainWindowHandle
值:
$TypeDef2 = @"
using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Api
{
public class WinStruct
{
public string WinTitle {get; set; }
public int MainWindowHandle { get; set; }
}
public class ApiDef
{
private delegate bool CallBackPtr(int hwnd, int lParam);
private static CallBackPtr callBackPtr = Callback;
private static List<WinStruct> _WinStructList = new List<WinStruct>();
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumWindows(CallBackPtr lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
private static bool Callback(int hWnd, int lparam)
{
StringBuilder sb = new StringBuilder(256);
int res = GetWindowText((IntPtr)hWnd, sb, 256);
_WinStructList.Add(new WinStruct { MainWindowHandle = hWnd, WinTitle = sb.ToString() });
return true;
}
public static List<WinStruct> GetWindows()
{
_WinStructList = new List<WinStruct>();
EnumWindows(callBackPtr, IntPtr.Zero);
return _WinStructList;
}
}
}
"@
Add-Type -TypeDefinition $TypeDef2 -Language CSharpVersion3
$excelInstance = [Api.Apidef]::GetWindows() | Where-Object { $_.WinTitle.ToUpper() -eq "Microsoft Excel - Compatibility Checker".ToUpper() }
所以现在使用这个正确的值,我可以调用 SetForegroundWindow()
函数:
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"@
[void] [Tricks]::SetForegroundWindow($excelInstance.MainWindowHandle)
我在 website 上写了一篇关于此的详细博客。
我已经在 GitHub 上提供了一个完整的示例,说明如何创建 Excel 文件、编辑它以及 运行 上面的代码在您必须的不同线程中这样做是因为 Excel 弹出窗口阻塞了主线程。