调用Runtime.InteropServices.DllImportAttribute

问题描述:

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

Editor's note: This question is ultimately about how to call a Windows API function such as SetForegroundWindow from PowerShell, using the .NET P/Invoke feature.

$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(
    #...
    #...    
)

如何完成此代码?我不了解".调用"中的参数.据我了解,其中之一是我的 EntryPoint (HWND)?

How to finish this code? I don't understand parameters in ".Invoke". As i understand, one of them is for my EntryPoint(HWND)?

System.Runtime.InteropServices.DllImportAttribute 属性:

  • 通常以声明方式使用 ...

... 装饰一个.NET方法,该方法的签名与正在调用的非托管函数相匹配.

... to decorate a .NET method that has a signature matching the unmanaged function being invoked.

通过这种方式定义.NET方法,您可以调用 unmanaged (本机)函数,即通过.NET功能调用不是为.NET编写的DLL中的函数,例如Windows API函数.称为 P/Invoke (平台调用服务).

Defining .NET methods this way allows you to call unmanaged (native) functions, i.e. functions from DLLs that weren't written for .NET, such as Windows API functions, via a .NET feature called P/Invoke (Platform Invocation Services).

您不能直接在PowerShell代码中执行此操作,但是可以使用 添加类型 cmdlet和 -MemberDefinition 参数可按需编译C#代码; -MemberDefinition 自动导入 System.Runtime.InteropServices 命名空间,并自动将传递给它的方法定义包装在以 -Name 命名的类中>参数,在以 -Namespace 参数命名的命名空间中.

You cannot directly do this in PowerShell code, but you can use the Add-Type cmdlet with the -MemberDefinition parameter to compile C# code on demand; -MemberDefinition automatically imports the System.Runtime.InteropServices namespace and automatically wraps the method definition(s) passed to it in class named for the -Name argument, in the namespace named for the -Namespace argument.

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名称是 required 构造实例;为各种属性(例如上面的 SetLastError 等)提供值是可选.

    • Note the declarative use of the DllImportAttribute (in which case the Attribute suffix is optional) and that only the source DLL name is required to construct the instance; supplying values to the various properties (such as SetLastError above) is optional.

      要修饰的方法-您将能够从PowerShell代码中调用的方法-必须声明为 public static extern ,并且方法签名的其余部分必须与返回值匹配的类型和一组参数(包括它们的类型)被调用的非托管DLL函数.

      The method being decorated - the one you'll be able to call from PowerShell code - must be declared as public static extern, and the rest of the method signature must match the return type and the set of parameters, including their types, of the unmanaged DLL function being invoked.

      • 默认情况下,假定非托管函数与该方法具有相同的名称,尽管您可以使用不同的方法命名该方法并使用 EntryPoint 属性的 DllImportAttribute .

      网站 pinvoke.net 是查找Windows API函数的预定义定义的有用资源,例如 SetForegroundWindow 函数,例如手.

      Website pinvoke.net is a helpful resource for finding predefined definitions for Windows API functions, such as for the SetForegroundWindow function at hand.