调用 Runtime.InteropServices.DllImportAttribute

Invoke Runtime.InteropServices.DllImportAttribute

编者注:这个问题最终是关于如何从 PowerShell 调用 Windows API 函数,例如 SetForegroundWindow,使用.NET P/Invoke 功能。

$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 方法允许您调用 非托管(本机)函数,即来自不是为 .NET 编写的 DLL 的函数,例如 Windows API 函数,通过名为 P/Invoke (Platform Invocation Services).

的 .NET 功能

你不能直接在PowerShell代码中这样做,但你可以使用Add-Type cmdlet 和-MemberDefinition 参数来按需编译C#代码; -MemberDefinition 自动导入 System.Runtime.InteropServices 命名空间,并自动将传递给它的方法定义包装在以 -Name 参数命名的 class 中,在以 [=] 命名的命名空间中17=] 参数。

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)提供值是 optional.

  • 被修饰的方法——您将能够从 PowerShell 代码调用的方法——必须声明为 public static extern,方法签名的其余部分必须与 return 正在调用的非托管 DLL 函数的类型和参数集,包括它们的类型。

    • 默认情况下,假定非托管函数与方法同名,尽管您可以使用不同的方法命名并指定要使用 EntryPoint [=77= 显式调用的函数的名称] DllImportAttribute.
  • 网站 pinvoke.net is a helpful resource for finding predefined definitions for Windows API functions, such as for the SetForegroundWindow 功能可用。