Windows PowserShell能夠很簡潔 快速通過Script腳本方式獲得我們想要執行效果. 如何在C#中任意執行PowerShell腳本.?類似目前我要在做一個程序管理工具. 通過PowerShell腳本方式擷取目前系統程序調用的詳細資訊. C#如何執行Shell Script:
步驟如下:
<1>前提:安裝PowerShell SDK.
<2>建立Console Application項目 命名:CallPowerShellDemo .添加引用:System.Management.Automation 這個命名空間需要引用PowerShell SDK中System.Management.Automation.dll. 如果已經PowerShell SDK可以在目錄:C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 下找到:
<a href="http://blog.51cto.com/attachment/201201/230957910.jpg" target="_blank"></a>
添加相關引用:
//導入引入
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Management;
using CallPowerShellDemo.EntityModel;
封裝參數實體:
/// <summary>
/// 定義一個封裝Shell腳本指令參數實體類
/// Author:chenkai Date:2010年11月9日10:27:55
/// </summary>
public class ShellParameter
{
public string ShellKey { get; set; }
public string ShellValue { get; set; }
}
執行腳本方法:
/// <summary>
/// 執行PowserShell 腳本核心方法
/// </summary>
/// <param name="getshellstrlist">Shell腳本集合</param>
/// <param name="getshellparalist">腳本中涉及對應參數</param>
/// <returns>執行結果傳回值</returns>
public static string ExecuteShellScript(List<string> getshellstrlist, List<ShellParameter> getshellparalist)
{
string getresutl = null;
try
{
//Create Runspace
Runspace newspace = RunspaceFactory.CreateRunspace();
Pipeline newline = newspace.CreatePipeline();
//open runspace
newspace.Open();
if (getshellstrlist.Count > 0)
{
foreach (string getshellstr in getshellstrlist)
{
//Add Command ShellString
newline.Commands.AddScript(getshellstr);
}
}
//Check Parameter
if (getshellparalist != null && getshellparalist.Count > 0)
int count = 0;
foreach (EntityModel.ShellParameter getshellpar in getshellparalist)
//Set parameter
//注入腳本一個.NEt對象 這樣在powershell腳本中就可以直接通過$key通路和操作這個對象
//newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);
CommandParameter cmdpara = new CommandParameter(getshellpar.ShellKey, getshellpar.ShellValue);
newline.Commands[count].Parameters.Add(cmdpara);
//Exec Restult
var getresult = newline.Invoke();
if (getresult != null)
StringBuilder getbuilder = new StringBuilder();
foreach (var getresstr in getresult)
getbuilder.AppendLine(getresstr.ToString());
getresutl = getbuilder.ToString();
//close
newspace.Close();
}
catch (Exception se)
//catch Excetption
return getresutl;
}
Main方法中調用:
static void Main(string[] args)
Console.WriteLine("請輸入你要執行的PowserShell命名:");
string gettakeresult = Console.ReadLine();
//Main Method Get All Process
List<string> getshellcmdlist = new List<string>();
List<EntityModel.ShellParameter> getpatalist = new List<ShellParameter>
new ShellParameter{ ShellKey="Name",ShellValue="QQ*"}
};
if (!string.IsNullOrEmpty(gettakeresult))
getshellcmdlist.Add(gettakeresult);
//Execu Cmd
string getresult = Program.ExecuteShellScript(getshellcmdlist, getpatalist);
//Output ExecuteResult
Console.WriteLine("執行結果:");
Console.WriteLine(getresult);
Program.OperatorObjectShell();
執行結果: 擷取以Ca作為開頭名稱系統程序資訊 ShellScript :get-process Ca*
<a href="http://blog.51cto.com/attachment/201201/231005607.jpg" target="_blank"></a>
則利用PowerShell腳本輕松擷取程序名稱以Ca開頭所有程序名稱. 類似我們輕松在擷取360在本地系統詳細的版本資訊:get-process 360* –fileversioninfo
<a href="http://blog.51cto.com/attachment/201201/231013705.jpg" target="_blank"></a>
<3>Windows PowerShell 與C#之間互動.
PowerShell對.NET對象是無縫支援的, 在Windows PowerShell腳本程式設計中也提出面向對象的概念. 對于Shell腳本中對象和C#語言對象是否具有互相可操作性. ?答案是肯定的. 類似我們現在要做一個運算, 運算邏輯定義以及執行則有Shell腳本. 隻需在C#中以對象的方式傳給Shell腳本中對象相關的參數.值. 自動計算.
先定義一個計算操作對象:
/// 計算操作的對象
/// Author:chenkai Date:2010年11月9日13:54:49
public class ConvertPatameter
{
public int FirstNum { get; set; }
public int SecondNum { get; set; }
public int Sum { get; set; }
}
當我們頂一個操作對象. 初始化FirstNum和SecondNum,然後把值傳入到Shell腳本中執行加法運算并把結果賦給Sum參數.Shell Script中定義加法執行規則:
$a=$Result.FirstNum
$b=$Result.SecondNum
$Result.Sum=$a+$b
C#調用對象處理Shell腳本執行方法:
try
{
//zaiShell 執行方法參數
List<string> getlist = new List<string>();
getlist.Add("Set-ExecutionPolicy RemoteSigned");//先執行啟動安全政策,,使系統可以執行powershell腳本檔案
string pspath = System.IO.Path.Combine(Environment.CurrentDirectory, "PSDoc1.ps1");
getlist.Add(pspath);
//定義一個操作的實體對象
ConvertPatameter newconvert = new ConvertPatameter
{
FirstNum=200,
SecondNum=80,
Sum=0 16: };
if (File.Exists(pspath))
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace newspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
newspace.Open();
Pipeline newline = newspace.CreatePipeline();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(newspace);
Command getcmd = new Command(pspath);
newline.Commands.Add(getcmd);
//注入腳本一個.NEt對象 這樣在powershell腳本中就可以直接通過$key通路和操作這個對象
//newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);
newspace.SessionStateProxy.SetVariable("Result", newconvert);
//執行
var gettakeres=newline.Invoke();
foreach (var getstr in gettakeres)
{
Console.WriteLine(getstr.ToString());
}
Console.WriteLine("計算結果:" + newconvert.FirstNum.ToString() + "加上"
+ newconvert.SecondNum.ToString() + "等于" + newconvert.Sum.ToString());
Console.WriteLine("對象的值已經修改:"+newconvert.Sum.ToString());
}
}
catch (Exception se)
執行結果:
<a href="http://blog.51cto.com/attachment/201201/231021191.jpg" target="_blank"></a>
當把C#中實體對象ConvertPatameter賦給Shell腳本中對象$Result. 注意核心注冊語句:
//注入腳本一個.NEt對象 這樣在powershell腳本中就可以直接通過$key通路和操作這個對象
//newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);
newspace.SessionStateProxy.SetVariable("Result", newconvert);
在腳本注冊一個.NET對象并賦給Shell對象$Result,則在ShellScript腳本中利用加法運算 修改原來對象的Sum的屬性.并傳回給.NET對象中.這是一次關于.NEt對象和Shell Script中對象互動一次簡單操作.
源代碼下載下傳見附件。
<a href="http://down.51cto.com/data/2359673" target="_blank">附件:http://down.51cto.com/data/2359673</a>
本文轉自chenkaiunion 51CTO部落格,原文連結:http://blog.51cto.com/chenkai/764150