1

I'm currently trying to run a .NET application in PowerShell. I'm using System.Reflection.Assembly to load the bytes in memory of an assembly written in C#.

The .NET application has one method, Main(System.String[] args), and it will list the values passed as argument of the function. Very simple program.

Here's the PowerShell code :

[String] $assemblyPath = "C:\Users\HakkYahud\Desktop\HelloWorld.exe"
[String[]]$parameter_main = @( "test" )

[Byte[]]$assemblyByte = [System.IO.File]::ReadAllBytes($assemblyPath)
$assembly = [System.Reflection.Assembly]::Load($assemblyByte)
$entryPoint = $assembly.EntryPoint
$parameter_invoke = @( $parameter_main )

Write-Host $parameter_main.GetType()
Write-Host $parameter_invoke.GetType()
Write-Host $entryPoint
Write-Host @( "test", "test2" ).GetType()

$entryPoint.Invoke($null, $parameter_invoke)

I know that method Invoke takes 2 parameters Object obj and Object[] parameters.

Once running the code, an error occurs in the function Invoke, it is saying that "it cannot cast System.String to the type System.String[]"

The variable $parameter_main is already System.String[], why does the compiler need to cast from System.String to System.String[]?

Moreover, when I'm putting $parameter_main = @("test", "test2"), I'm receiving another error saying "Wrong number of arguments"

Has anyone already encountered this issue?

0

1 Answer 1

3

PowerShell's pipeline processor loves enumerating output. This means that when you use the array subexpression @(...) like this:

$innerArray = 1,2
$outerArray = @( $innerArray )

... PowerShell evaluates $innerArray, sees that it's an array, enumerates all the items in the array, and the resulting array value stored in $outerArray thus becomes a flat array containing the exact same items as $innerArray.

To prevent this array-flattening, there are two options:

  • Use Write-Output -NoEnumerate to signal that PowerShell should not attempt to enumerate the items from inner array:
    • $parameter_invoke = @( Write-Output $parameter_main -NoEnumerate )
  • Wrap the inner array in another array literal-expression:
    • $parameter_invoke = @( ,$parameter_main )
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you sir ! $parameter_invoke = @( ,$parameter_main ) is working. Quite an annoying behavior that evaluate the element of the array when the entire array is passed as a argument of the function
@SkallZou It's annoying in this particular context (where you need to construct a nested array), but PowerShell would be a nightmare to work with if it didn't behave like this 95% of the time :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.