编者注:这个问题最终是关于如何使用 .NET P/Invoke 功能从 PowerShell 调用 Windows API 函数,例如
SetForegroundWindow
。
$dll=[Runtime.InteropServices.DllImportAttribute]::new("user32.dll")
$dll.EntryPoint='SetForegroundWindow'
$dll.CharSet=1
$dll.ExactSpelling=$true
$dll.SetLastError=$false
$dll.PreserveSig=$true
$dll.CallingConvention=1
$dll.BestFitMapping=$false
$dll.ThrowOnUnmappableChar=$false
$dll.Invoke(
#...
#...
)
如何完成这段代码?我不明白“.Invoke”中的参数。据我了解,其中之一是我的 EntryPoint(HWND)?
System.Runtime.InteropServices.DllImportAttribute
属性:
通常使用 声明式...
... 装饰 .NET 方法,其签名与所调用的非托管函数相匹配。
以这种方式定义 .NET 方法允许您通过称为 P/Invoke 的 .NET 功能调用 非托管(本机)函数,即不是为 .NET 编写的 DLL 中的函数,例如 Windows API 函数(平台调用服务).
您无法直接在 PowerShell 代码中执行此操作,但可以使用带有 Add-Type
参数的
-MemberDefinition
cmdlet 按需编译 C# 代码; -MemberDefinition
自动导入 System.Runtime.InteropServices
命名空间,并自动将传递给它的方法定义包装在以 -Name
参数命名的类中,在以 -Namespace
参数命名的命名空间中。
Add-Type -Namespace Util -Name WinApi -MemberDefinition @'
[DllImport("user32.dll", SetLastError=true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
'@
$hwnd = ... # determine the handle of the target window.
# Now call the unmanaged function.
[Util.WinApi]::SetForegroundWindow($hwnd)
请注意
DllImportAttribute
的声明性使用(在这种情况下,Attribute
后缀是可选的),并且只有源 DLL 名称是构造实例时必需的;为各种属性提供值(例如上面的SetLastError
)是可选。
被修饰的方法(您可以从 PowerShell 代码调用的方法)必须声明为
public static extern
,并且方法签名的其余部分必须与返回类型和参数集(包括它们的类型)匹配,正在调用的非托管 DLL 函数。
EntryPoint
的 DllImportAttribute
属性显式指定要调用的函数的名称。网站 pinvoke.net 是查找 Windows API 函数的预定义定义的有用资源,例如手头的
SetForegroundWindow
函数。