I'm trying to write some Powershell to make in-memory calls to the Win32API. For this I need to pass the Win32API function prototype as well as the actual arguments. To make the code more neat I figured I'll only pass the arguments as an array and extract the types from there to create the prototype. For this to work I need to be able to 'explode' an array into separate function arguments. I'm new to Powershell so I've no idea if this is possible. If it is the question is: How can you 'explode' an array into seperate function arguments?
Below I've added the relevant part of the code.
function CallWin32API(
[String] $ModuleName,
[String]$FunctionName,
[array]$Arguments,
[Type]$ReturnType=[Void]
) {
$Prototype = @()
foreach ($Argument in $Arguments) {
$Prototype += $Argument.GetType()
}
# ...
# Using the $Prototype here somewhere & creating the delegate
# ...
$Delegate = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($FunctionAddr, $DelegateType)
# This is what I need but does not work
$Delegate.Invoke($Arguments)
# This is not what I need but does work
$Delegate.Invoke([IntPtr]::Zero,"Hello World","This is My MessageBox",0)
}
CallWin32API user32.dll MessageBoxA @([IntPtr]::Zero,"Hello World","This is My MessageBox",0) ([int])
EDIT: I'm trying to dynamically call Win32API functions. This means that the arguments of the $Delegate.Invoke depend on the function that is being called.
Hard to tell without having complete information but using
MessageBoxAas example you can always use.InvokefromPSMethodto bind the array of arguments:Following comment from Mathias, if you have the delegate from
GetDelegateForFunctionPointermethod you can also callPSMethod.InvokeonDelegate.Invoke: