SkallZou
SkallZou

Reputation: 11

PowerShell issue: Invoke method "Cannot cast object of type ‘System.String’ to type ‘System.String[]’

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?

Upvotes: 1

Views: 1552

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174485

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 )

Upvotes: 3

Related Questions