• C#执行PowserShell 脚本


    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 下找到:

    2010-11-09_113358

     

     

     

     

     

     

     

     

    添加相关引用:

       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:      }

    执行脚本方法:

            /// <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*

    2010-11-09_114559

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

    2010-11-09_115148

    对于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  
       4:   

    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:                  };
      17:   
      18:                  if (File.Exists(pspath))
      19:                  {
      20:                      RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); 
      21:                      Runspace newspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
      22:   
      23:                      newspace.Open();
      24:                      Pipeline newline = newspace.CreatePipeline();
      25:                      RunspaceInvoke scriptInvoker = new RunspaceInvoke(newspace); 
      28:                      Command getcmd = new Command(pspath);
      29:                      newline.Commands.Add(getcmd);
      30:   
      31:                      //注入脚本一个.NEt对象 这样在powershell脚本中就可以直接通过$key访问和操作这个对象
      32:                      //newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);
      33:                      newspace.SessionStateProxy.SetVariable("Result", newconvert);
      34:   
      35:                     //执行
      36:                     var gettakeres=newline.Invoke();
      38:                     foreach (var getstr in gettakeres)
      39:                     {
      40:                         Console.WriteLine(getstr.ToString());
      41:                     }
      42:   
      43:                     Console.WriteLine("计算结果:" + newconvert.FirstNum.ToString() + "加上" 
      44:                         + newconvert.SecondNum.ToString() + "等于" + newconvert.Sum.ToString());
      45:                     Console.WriteLine("对象的值已经修改:"+newconvert.Sum.ToString());
      46:                  }
      48:                  
      49:              }
      50:              catch (Exception se)

    执行结果:

    2010-11-09_152053

    当把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中对象交互一次简单操作.

    本次操作源码下载: /Files/chenkai/CallPowerShellDemo.rar

  • 相关阅读:
    Hack The Box——Traverxec
    Hack The Box——AI
    Hack The Box——Json
    BZOJ1036 树的统计Count
    BZOJ1036 树的统计Count
    BZOJ1036 树的统计Count
    BZOJ1036 树的统计Count
    .net 面试题
    .net 面试题
    .net 面试题
  • 原文地址:https://www.cnblogs.com/chenkai/p/1872471.html
Copyright © 2020-2023  润新知