2011-09-03 15 views
5

Estoy intentando llamar a una función en un archivo de PowerShell de la siguiente manera:Problema con llamar a una función PowerShell desde C#

string script = System.IO.File.ReadAllText(@"C:\Users\Bob\Desktop\CallPS.ps1"); 

    using (Runspace runspace = RunspaceFactory.CreateRunspace()) 
    { 
     runspace.Open(); 
     using (Pipeline pipeline = runspace.CreatePipeline(script)) 
     { 
      Command c = new Command("BatAvg",false); 
      c.Parameters.Add("Name", "John"); 
      c.Parameters.Add("Runs", "6996"); 
      c.Parameters.Add("Outs", "70"); 
      pipeline.Commands.Add(c); 

      Collection<PSObject> results = pipeline.Invoke(); 
      foreach (PSObject obj in results) 
      { 
       // do somethingConsole.WriteLine(obj.ToString()); 
      } 
     } 
    } 

La función de PowerShell está en CallPS.ps1:

Function BatAvg 
{ 
    param ($Name, $Runs, $Outs) 
    $Avg = [int]($Runs/$Outs*100)/100 
    Write-Output "$Name's Average = $Avg, $Runs, $Outs " 
} 

I Obteniendo la siguiente excepción:

El término 'BatAvg' no se reconoce como el nombre de un cmdlet, función, archivo de script o programa operable.

Qué estoy haciendo mal, lo admito, sé muy poco sobre PowerShell.

Respuesta

7

Esto parece funcionar para mí:

using (Runspace runspace = RunspaceFactory.CreateRunspace()) 
{ 
    runspace.Open(); 
    PowerShell ps = PowerShell.Create(); 
    ps.Runspace = runspace; 
    ps.AddScript(script); 
    ps.Invoke(); 
    ps.AddCommand("BatAvg").AddParameters(new Dictionary<string, string> 
    { 
     {"Name" , "John"}, 
     {"Runs", "6996"}, 
     {"Outs","70"} 
    }); 

    foreach (PSObject result in ps.Invoke()) 
    { 
     Console.WriteLine(result); 
    } 
} 
1

Como parece que el Runspace debe estar conectado a un Powershell para que funcione - vea el código de muestra en MSDN.

+0

No, todavía obtiene la misma excepción: runspace.Open(); PowerShell ps = PowerShell.Create(); ps.Runspace = espacio de ejecución; ps.AddScript (script); Comando c = new Command ("BatAvg", falso); ps.AddCommand ("BatAvg", falso); ps.AddParameter ("Nombre", "Juan"); ps.AddParameter ("Ejecuciones", "6996"); ps.AddParameter ("Salidas", "70"); foreach (OBObject obj en ps.Invoke()) { // hacer algoConsole.WriteLine (obj.ToString()); } – user577240

1

La solución puede simplificarse aún más, como en este caso no es necesario un espacio de ejecución no predeterminada.

var ps = PowerShell.Create(); 
ps.AddScript(script); 
ps.Invoke(); 
ps.AddCommand("BatAvg").AddParameters(new Dictionary<string, string> 
{ 
    {"Name" , "John"}, {"Runs", "6996"}, {"Outs","70"} 
}); 
foreach (var result in ps.Invoke()) 
{ 
    Console.WriteLine(result); 
} 

Una otra trampa sería utilizar AddScript(script, true) el fin de utilizar un alcance local. Se encontraría la misma excepción (es decir, "El término 'BatAvg' no se reconoce como el nombre de un cmdlet, función, archivo de script o programa operable").

Cuestiones relacionadas