如何从PowerShell调用C#脚本并传递参数

如何从PowerShell调用C#脚本并传递参数,c#,powershell,C#,Powershell,我想用3个参数调用PowerShell脚本 第一个参数是C#脚本文件的路径 在PowerShell脚本中,我希望在C#脚本中执行一个方法,并将所有参数传递给它 # RunBackup.ps1 $csharp = Get-Content -Path $args[0] $job = Start-Job -ScriptBlock { Add-Type -TypeDefinition "$csharp" $obj = New-Object Main $resu

我想用3个参数调用PowerShell脚本

第一个参数是C#脚本文件的路径

在PowerShell脚本中,我希望在C#脚本中执行一个方法,并将所有参数传递给它

# RunBackup.ps1
$csharp = Get-Content -Path $args[0]
$job = Start-Job -ScriptBlock {
    Add-Type -TypeDefinition "$csharp"
    $obj = New-Object Main
    $result = $obj.Execute($args)
    $result
}
Wait-Job $job
Receive-Job $job

// Main.cs
using System;

public class Main
{
    public int Execute(string[] args)
    {
        Console.WriteLine(args[0]);
        return 0;
    }
}
但是,当我使用
/RunBackup Main.cs 1 2 3
运行PS脚本时,出现了以下错误

Cannot bind argument to parameter 'TypeDefinition' because it is an empty string.
    + CategoryInfo          : InvalidData: (:) [Add-Type], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.AddTypeCommand
    + PSComputerName        : localhost
 
Cannot find type [Main]: verify that the assembly containing this type is loaded.
    + CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException
    + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
    + PSComputerName        : localhost

You cannot call a method on a null-valued expression.
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
    + PSComputerName        : localhost

您试图访问
$csharp
变量,但它不在子
ScriptBlock
的范围内,因此根据PowerShell默认的变量初始化和引用lax规则,它会自动设置为
$null
。您可以通过使用
Set StrictMode
来验证这一点,以防止并警告此默认行为:

$csharp=获取内容-路径$args[0]
$job=开始作业-脚本块{
设置StrictMode-最新版本
添加类型-TypeDefinition$csharp
$obj=新对象主目录
$result=$obj.Execute($args)
$result
}
等待作业$Job
接收Job$Job
输出:

无法检索变量“$csharp”,因为它尚未设置。
+CategoryInfo:InvalidOperation:(csharp:String)[],运行时异常
+FullyQualifiedErrorId:变量未定义
+PSComputerName:localhost
找不到类型[Main]:请验证是否加载了包含此类型的程序集。
+CategoryInfo:InvalidType:(:)[New Object],pArgumentException
+FullyQualifiedErrorId:TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
+PSComputerName:localhost
无法检索变量“$obj”,因为尚未设置该变量。
+CategoryInfo:InvalidOperation:(对象:字符串)[],运行时异常
+FullyQualifiedErrorId:变量未定义
+PSComputerName:localhost
无法检索变量“$result”,因为尚未设置该变量。
+CategoryInfo:InvalidOperation:(结果:字符串)[],RuntimeException
+FullyQualifiedErrorId:变量未定义
+PSComputerName:localhost
要修复此问题,需要将
$csharp
的值显式传递给
脚本块

$csharp=获取内容-路径$args[0]
$job=开始作业-脚本块{
添加类型-TypeDefinition$input#由InputObject提供的powershell隐式参数
$obj=新对象主目录
$result=$obj.Execute($args)
$result
}-InputObject$csharp
等待作业$Job
接收Job$Job

当然,现在会出现不同的错误,但这些错误超出了这个问题的范围

您试图访问
$csharp
变量,但它不在子
ScriptBlock
的范围内,因此根据PowerShell默认的变量初始化和引用lax规则,它会自动设置为
$null
。您可以通过使用
Set StrictMode
来验证这一点,以防止并警告此默认行为:

$csharp=获取内容-路径$args[0]
$job=开始作业-脚本块{
设置StrictMode-最新版本
添加类型-TypeDefinition$csharp
$obj=新对象主目录
$result=$obj.Execute($args)
$result
}
等待作业$Job
接收Job$Job
输出:

无法检索变量“$csharp”,因为它尚未设置。
+CategoryInfo:InvalidOperation:(csharp:String)[],运行时异常
+FullyQualifiedErrorId:变量未定义
+PSComputerName:localhost
找不到类型[Main]:请验证是否加载了包含此类型的程序集。
+CategoryInfo:InvalidType:(:)[New Object],pArgumentException
+FullyQualifiedErrorId:TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
+PSComputerName:localhost
无法检索变量“$obj”,因为尚未设置该变量。
+CategoryInfo:InvalidOperation:(对象:字符串)[],运行时异常
+FullyQualifiedErrorId:变量未定义
+PSComputerName:localhost
无法检索变量“$result”,因为尚未设置该变量。
+CategoryInfo:InvalidOperation:(结果:字符串)[],RuntimeException
+FullyQualifiedErrorId:变量未定义
+PSComputerName:localhost
要修复此问题,需要将
$csharp
的值显式传递给
脚本块

$csharp=获取内容-路径$args[0]
$job=开始作业-脚本块{
添加类型-TypeDefinition$input#由InputObject提供的powershell隐式参数
$obj=新对象主目录
$result=$obj.Execute($args)
$result
}-InputObject$csharp
等待作业$Job
接收Job$Job

当然,现在会出现不同的错误,但这些错误超出了这个问题的范围

你为什么用这种方式运行程序?使类名为'Program',入口点函数名为
Main
,然后编译应用程序。然后,您将获得一个exe或dll,然后可以使用
dotnet file.dll参数运行该文件
@LukeParker谢谢您的评论。我可以更改类名,但它是否允许我运行C#源代码,或者我仍然需要编译它?我的要求是运行C#源代码。@LukeParker我意识到我可以使用
dotnet运行app args
,它将从源代码构建和运行。那将符合我的要求。谢谢。你为什么用那种方式运行程序?使类名为'Program',入口点函数名为
Main
,然后编译应用程序。然后,您将获得一个exe或dll,然后可以使用
dotnet file.dll参数运行该文件
@LukeParker谢谢您的评论。我可以更改类名,但它是否允许我运行C#源代码,或者我仍然需要编译它?我的要求是运行C#源代码。@LukeParker我意识到我可以使用
dotnet运行app args
,它将从源代码构建和运行。那将符合我的要求