【问题标题】:Powershell Reflection Invoke with Parameters带参数的 Powershell 反射调用
【发布时间】:2021-11-19 04:27:16
【问题描述】:

我目前正在使用 PowerShell 学习反射,我正在努力寻找如何使用反射将参数传递给测试 DLL 中的静态 void 函数,已经在这几个小时并且很可能在谷歌或这里跑过了答案在 StackOverflow 上?如果这里的大师可以帮助我,那会很棒吗?

示例 DLL 代码:

using System;
using System.Diagnostics;

namespace ExampleProject
{
    public class Class1
    {
        public static void RunProcess(string fullFileName)
        {
            var p = new Process
            {
                 StartInfo =
                 {
                     FileName = fullFileName
                 }
            }.Start();
        }  
    }
}

当前的 Powershell 代码:

$data = "C:\temp\mytestlib.dll')
$assem = [System.Reflection.Assembly]::Load($data)
$class = $assem.GetType("ExampleProject.Class1")
$method = $class.GetMethod("RunProcess")
$fullName = "C:\\Windows\\System32\\calc.exe"
$method.Invoke($null,$fullName)

收到错误:

Exception calling "Invoke" with "2" argument(s): "Parameter count mismatch."
At line:6 char:1
+ $method.Invoke($null,$fullName)

但添加 $method.Invoke($null,$null) 允许执行 PowerShell 脚本,尽管出现静默失败?

【问题讨论】:

    标签: c# powershell


    【解决方案1】:

    在 PowerShell 中,您不需要反射即可从动态加载的程序集中访问类型及其成员 - 只需使用 PowerShell 的常规语法

    # Load the assembly
    Add-Type -LiteralPath C:\temp\mytestlib.dll
    
    # Use its types and access its members as you normally would in PowerShell.
    [ExampleProject.Class1]::RunProcess('C:\Windows\System32\calc.exe')
    

    作为一种解释语言,all 类型(类)和成员访问在 PowerShell 中实际上是基于反射的,在幕后。

    只需要用户代码中的反射技术

    • 如果您不知道要提前访问的类型和/或成员的名称
    • 如果您需要访问非公开类型和成员

    即使通过变量或表达式提供名称,也并不严格要求在 PowerShell 中进行反射;一个简单的例子:

    # The following:
    [string]::Concat('foo', 'bar') # -> 'foobar'
    
    # ... can also be expressed as:
    $type = [type] 'string'
    $method = 'Concat'
    $type::$method('foo', 'bar')
    

    如果您确实想使用反射

    # Load the assembly
    $assembly = [System.Reflection.Assembly]::LoadFrom('C:\temp\mytestlib.dll')
    
    # Get a reference to the type.
    # Use .GetTypes() to enumerate all types.
    $type = $assembly.GetType('ExampleProject.Class1')
    
    # Get a reference to the method.
    # Use .GetMethods() to enumerate all methods.
    $method = $type.GetMethod('RunProcess')
    
    # Invoke the method:
    # * $null as the first argument means that no instance is to be
    #   to be targeted, implying a *static* method call.
    # * the second argument is an array containing the arguments
    #   to pass to the methods.
    $method.Invoke($null, @('C:\Windows\System32\calc.exe'))
    

    【讨论】:

    • 最佳答案,非常感谢您详细解释它非常有帮助,非常感谢您,我看到了思考和使用的错误,所以这很长。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 2012-06-16
    相关资源
    最近更新 更多