我有一个像这样的简单DotNet DLL
namespace ClassLibrary1
{
public class Class1
{
public static void Test()
{
Process.Start("CMD.exe", "/C calc");
}
}
}
当我尝试使用Powershell加载此DLL
$Path = "c:\\test\\ClassLibrary1.dll";
$Namespace = "ClassLibrary1";
$ClassName = "Class1";
$Method = "Test";
$Arguments = $null
$Full_Path = [System.IO.Path]::GetFullPath($Path);
$AssemblyName = [System.Reflection.AssemblyName]::GetAssemblyName($Full_Path)
$Full_Class_Name = "$Namespace.$ClassName"
$Type_Name = "$Full_Class_Name, $($AssemblyName.FullName)"
$Type = [System.Type]::GetType($Type_Name)
$MethodInfo = $Type.GetMethod($Method)
$MethodInfo.Invoke($null, $Arguments)
它不起作用,因为[System.Type]::GetType($Type_Name)
返回了$null
有什么想法吗?
答案 0 :(得分:1)
使用 Add-Type -Path
加载程序集。
加载后,要通过 string变量以[ClassLibrary1.Class1]
实例的形式引用该程序集的[Type]
类型(用于反射),只需< strong>广播到[Type]
。
以下经过更正和注释的代码版本演示了该方法:
# Compile the C# source code to assembly .\ClassLibrary1.dll
Add-Type -TypeDefinition @'
namespace ClassLibrary1
{
public class Class1
{
public static void Test()
{
System.Diagnostics.Process.Start("CMD.exe", "/C calc");
}
}
}
'@ -OutputAssembly .\ClassLibrary1.dll
# Define the path to the assembly. Do NOT use "\\" as the path separator.
# PowerShell doesn't use "\" as the escape character.
$Path = ".\ClassLibrary1.dll"
$Namespace = "ClassLibrary1"
$ClassName = "Class1"
$Method = "Test"
$Arguments = $null
# Load the assembly by its filesystem path, using the Add-Type cmdlet.
# Use of relative paths works.
Add-Type -Path $Path
$Full_Class_Name = "$Namespace.$ClassName"
# To get type [ClassLibrary1.Class1] by its full name as a string,
# simply cast to [type]
$Type = [type] $Full_Class_Name
$MethodInfo = $Type.GetMethod($Method)
$MethodInfo.Invoke($null, $Arguments)
关于您尝试过的事情:
PetSerAl指出,[System.Type]::GetType()
仅在以下情况下才能找到给定类型:
mscorlib
程序集或 GAC (全局程序集缓存)中的程序集的-in 类型。
虽然您可以先调用[System.Reflection.Assembly]::LoadFile($Full_Path)
才能通过其文件系统路径加载程序集,然后[System.Type]::GetType($Type_Name)
成功了,但最终使用{ {1}}加载程序集(具有不需要完整(绝对)文件路径的附加优势),并且在加载后仅使用类型完整的Add-Type -Path
名称(不再需要引用程序集)。