Windows PowserShell能够很简洁 快速通过Script脚本方式获得我们想要执行效果. 如何在C#中任意执行PowerShell脚本.?类似目前我要在做一个进程管理工具. 通过PowerShell脚本方式获取当前系统进程调用的详细信息. C#如何执行Shell Script:

步骤如下:

<1>前提:安装PowerShell SDK.

要在C#执行Power Shell 脚本.需要在PowerShell的SDK添加相关引用. Windows 7系统自动集成Windows PowerShell 2.0版本.如果尚未请点击下载安装

<2>新建Console Application项目 命名:CallPowerShellDemo .添加引用:System.Management.Automation 这个命名空间需要引用PowerShell SDK中System.Management.Automation.dll. 如果已经PowerShell SDK可以在目录:C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 下找到:

添加相关引用:

 
  
  1. //导入引入     
  2. using System.Management.Automation;     
  3. using System.Management.Automation.Runspaces;     
  4. using System.Management;     
  5. using CallPowerShellDemo.EntityModel; 

封装参数实体:

 
  
  1. /// <summary>     
  2. /// 定义一个封装Shell脚本命令参数实体类     
  3. /// Author:chenkai Date:2010年11月9日10:27:55     
  4. /// </summary>     
  5.  public  class ShellParameter     
  6.    {     
  7.      public string ShellKey { get; set; }     
  8.      public string ShellValue { get; set; }     
  9.    } 

执行脚本方法:

 
  
  1. /// <summary>  
  2.         /// 执行PowserShell 脚本核心方法  
  3.         /// </summary>  
  4.         /// <param name="getshellstrlist">Shell脚本集合</param>  
  5.         /// <param name="getshellparalist">脚本中涉及对应参数</param>  
  6.         /// <returns>执行结果返回值</returns>  
  7.         public static string ExecuteShellScript(List<string> getshellstrlist, List<ShellParameter> getshellparalist)  
  8.         {  
  9.             string getresutl = null;  
  10.             try  
  11.             {  
  12.                 //Create Runspace  
  13.                 Runspace newspace = RunspaceFactory.CreateRunspace();  
  14.                 Pipeline newline = newspace.CreatePipeline();  
  15.  
  16.                 //open runspace  
  17.                 newspace.Open();  
  18.  
  19.                 if (getshellstrlist.Count > 0)  
  20.                 {  
  21.                     foreach (string getshellstr in getshellstrlist)  
  22.                     {  
  23.                         //Add Command ShellString  
  24.                         newline.Commands.AddScript(getshellstr);  
  25.                     }  
  26.                 }  
  27.  
  28.                 //Check Parameter  
  29.                 if (getshellparalist != null && getshellparalist.Count > 0)  
  30.                 {  
  31.                     int count = 0;  
  32.                     foreach (EntityModel.ShellParameter getshellpar in getshellparalist)  
  33.                     {  
  34.                         //Set parameter  
  35.                         //注入脚本一个.NEt对象 这样在powershell脚本中就可以直接通过$key访问和操作这个对象  
  36.                         //newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);  
  37.                         CommandParameter cmdpara = new CommandParameter(getshellpar.ShellKey, getshellpar.ShellValue);  
  38.                         newline.Commands[count].Parameters.Add(cmdpara);  
  39.                     }  
  40.                 }  
  41.  
  42.                 //Exec Restult  
  43.                 var getresult = newline.Invoke();  
  44.                 if (getresult != null)  
  45.                 {  
  46.                     StringBuilder getbuilder = new StringBuilder();  
  47.                     foreach (var getresstr in getresult)  
  48.                     {  
  49.                         getbuilder.AppendLine(getresstr.ToString());  
  50.                     }  
  51.                     getresutl = getbuilder.ToString();  
  52.                 }  
  53.  
  54.                 //close   
  55.                 newspace.Close();  
  56.             }  
  57.             catch (Exception se)  
  58.             {  
  59.                 //catch Excetption   
  60.             }  
  61.             return getresutl;  
  62.         } 

Main方法中调用:

 
  
  1. static void Main(string[] args)  
  2.         {  
  3.             Console.WriteLine("请输入你要执行的PowserShell命名:");  
  4.             string gettakeresult = Console.ReadLine();  
  5.  
  6.             //Main Method Get All Process  
  7.             List<string> getshellcmdlist = new List<string>();  
  8.             List<EntityModel.ShellParameter> getpatalist = new List<ShellParameter>   
  9.             {  
  10.                 new ShellParameter{ ShellKey="Name",ShellValue="QQ*"}  
  11.             };  
  12.  
  13.  
  14.             if (!string.IsNullOrEmpty(gettakeresult))  
  15.             {  
  16.                 getshellcmdlist.Add(gettakeresult);  
  17.             }  
  18.             //Execu Cmd  
  19.             string getresult = Program.ExecuteShellScript(getshellcmdlist, getpatalist);  
  20.  
  21.             //Output ExecuteResult  
  22.             Console.WriteLine("执行结果:");  
  23.             Console.WriteLine(getresult);  
  24.  
  25.             Program.OperatorObjectShell();  
  26.         } 

执行结果: 获取以Ca作为开头名称系统进程信息 ShellScript :get-process Ca*

则利用PowerShell脚本轻松获取进程名称以Ca开头所有进程名称. 类似我们轻松在获取360在本地系统详细的版本信息:get-process 360* –fileversioninfo

对于C#执行Shell脚本方式. 是通过Runspace类 ,Runspace主要作用是分配一块独立空间,在空间之上建立一个独立为执行Shell命令唯一通信通道,Runspace同时也为创建通道环境参数进行配置. Runspace主要用来构建对象和配置通信环境相关参数. Shell脚本命令通过管道内的运行空间主机应用程序执行,但RunSpace并没有提供对执行结果输出. 如果需要输出则需要pipeline.类支持

<3>Windows PowerShell 与C#之间交互. 
PowerShell对.NET对象是无缝支持的, 在Windows PowerShell脚本编程中也提出面向对象的概念. 对于Shell脚本中对象和C#语言对象是否具有相互可操作性. ?答案是肯定的. 类似我们现在要做一个运算, 运算逻辑定义以及执行则有Shell脚本. 只需在C#中以对象的方式传给Shell脚本中对象相关的参数.值. 自动计算.

先定义一个计算操作对象:

 
  
  1. /// <summary>     
  2. /// 计算操作的对象     
  3. /// Author:chenkai Date:2010年11月9日13:54:49     
  4. /// </summary>     
  5.     public class ConvertPatameter     
  6.     {     
  7.       public int FirstNum { get; set; }     
  8.       public int SecondNum { get; set; }     
  9.       public int Sum { get; set; }    
  10.     } 

当我们顶一个操作对象. 初始化FirstNum和SecondNum,然后把值传入到Shell脚本中执行加法运算并把结果赋给Sum参数.Shell Script中定义加法执行规则:

 
  
  1. $a=$Result.FirstNum       
  2. $b=$Result.SecondNum       
  3. $Result.Sum=$a+$b 

C#调用对象处理Shell脚本执行方法:

 
  
  1. try     
  2. {     
  3.     //zaiShell 执行方法参数     
  4.     List<string> getlist = new List<string>();     
  5.     getlist.Add("Set-ExecutionPolicy RemoteSigned");//先执行启动安全策略,,使系统可以执行powershell脚本文件       
  6.  
  7.     string pspath = System.IO.Path.Combine(Environment.CurrentDirectory, "PSDoc1.ps1");     
  8.     getlist.Add(pspath);     
  9.  
  10.     //定义一个操作的实体对象    
  11.     ConvertPatameter newconvert = new ConvertPatameter     
  12.     {    
  13.           FirstNum=200,    
  14.          SecondNum=80,    
  15.          Sum=0  16:                  };    
  16.  
  17.     if (File.Exists(pspath))    
  18.     {    
  19.         RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();     
  20.         Runspace newspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);    
  21.  
  22.         newspace.Open();    
  23.         Pipeline newline = newspace.CreatePipeline();    
  24.         RunspaceInvoke scriptInvoker = new RunspaceInvoke(newspace);     
  25.         Command getcmd = new Command(pspath);    
  26.         newline.Commands.Add(getcmd);    
  27.  
  28.         //注入脚本一个.NEt对象 这样在powershell脚本中就可以直接通过$key访问和操作这个对象    
  29.         //newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);    
  30.         newspace.SessionStateProxy.SetVariable("Result", newconvert);    
  31.  
  32.        //执行    
  33.        var gettakeres=newline.Invoke();    
  34.        foreach (var getstr in gettakeres)    
  35.        {    
  36.            Console.WriteLine(getstr.ToString());    
  37.        }    
  38.  
  39.            Console.WriteLine("计算结果:" + newconvert.FirstNum.ToString() + "加上"     
  40.            + newconvert.SecondNum.ToString() + "等于" + newconvert.Sum.ToString());    
  41.            Console.WriteLine("对象的值已经修改:"+newconvert.Sum.ToString());    
  42.     }    
  43.         
  44. }    
  45. catch (Exception se) 

执行结果:

当把C#中实体对象ConvertPatameter赋给Shell脚本中对象$Result. 注意核心注册语句:

 
  
  1. //注入脚本一个.NEt对象 这样在powershell脚本中就可以直接通过$key访问和操作这个对象     
  2. //newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);     
  3. newspace.SessionStateProxy.SetVariable("Result", newconvert); 

在脚本注册一个.NET对象并赋给Shell对象$Result,则在ShellScript脚本中利用加法运算 修改原来对象的Sum的属性.并返回给.NET对象中.这是一次关于.NEt对象和Shell Script中对象交互一次简单操作.

源代码下载见附件。