2017-01-17 2 views
0

Очень новая для C#, поэтому глобальные переменные по-прежнему остаются загадкой и проблемой для меня.Настройка глобальной переменной из ComboBox

Я пытаюсь создать динамическую переменную с помощью Combobox, но мне не нравится что-то, что я пытаюсь бросить на нее.

Я надеюсь Кто-то и увидит мою ошибку и покажу мне, что я делаю неправильно.

Я попытался разместить операторы if в разных местах, например, на кнопке click и SelectedIndexChanged, но все еще не работает правильно.

Когда я нажимаю на кнопку, чтобы запустить скрипт, он говорит, что не смог найти файл, а переменная ScriptName указала, что он нигде не используется.

using System; 
using System.Text; 
using System.Windows.Forms; 
using System.Collections.ObjectModel; 
using System.Management.Automation; 
using System.Management.Automation.Runspaces; 
using System.ComponentModel; 
using System.Threading; 
using System.IO; 



namespace ServerStatusChecks 
{ 
    public partial class Form1 : Form 
    { 
     private BackgroundWorker bw = new BackgroundWorker(); 
     public string ScriptName { get; set; } 
     static string RunScriptResult; 
     public Form1() 
     { 
      InitializeComponent(); 
      bw.WorkerReportsProgress = true; 
      bw.WorkerSupportsCancellation = true; 
      bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
      bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
     } 


     private string LoadScript(string filename) 
     { 

      try 
      { 
       // Create an instance of StreamReader to read from our file. 
       // The using statement also closes the StreamReader. 
       using (StreamReader sr = new StreamReader(filename)) 
       { 


        // use a string builder to get all our lines from the file 
        StringBuilder fileContents = new StringBuilder(); 

        // string to hold the current line 
        string curLine; 

        // loop through our file and read each line into our 
        // stringbuilder as we go along 
        while ((curLine = sr.ReadLine()) != null) 
        { 
         // read each line and MAKE SURE YOU ADD BACK THE 
         // LINEFEED THAT IT THE ReadLine() METHOD STRIPS OFF 
         fileContents.Append(curLine + "\n"); 
        } 

        // call RunScript and pass in our file contents 
        // converted to a string 
        return fileContents.ToString(); 
       } 
      } 
      catch (Exception e) 
      { 
       // Let the user know what went wrong. 
       string errorText = "The file could not be read:"; 
       errorText += e.Message + "\n"; 
       return errorText; 

      } 
     } 

     public void button1_Click(object sender, EventArgs e) 
     { 

      if (bw.IsBusy != true) 
      { 
       bw.RunWorkerAsync(); 
      } 
      // run our script and put the result into our textbox 
      // NOTE: make sure to change the path to the correct location of your script 

     } 

     private void bw_DoWork(object sender, EventArgs e) 
     { 

      RunScriptResult = RunScript(LoadScript(ScriptName)); 
     } 

     // Takes script text as input and runs it, then converts 
     // the results to a string to return to the user 
     private string RunScript(string scriptText) 
     { 
      get { 
       return ScriptName; 
      } 
      set { 
       if (comboBox1.SelectedIndex == 0) 
       { 
        string ScriptName = @"c:\utils\Script1.ps1"; 
       } 
       if (comboBox1.SelectedIndex == 1) 
       { 
        string ScriptName = @"c:\utils\Script2.ps1"; 
       } 
       if (comboBox1.SelectedIndex == 2) 
       { 
        string ScriptName = @"c:\utils\Script3.ps1"; 
       } 
      } 
      // create Powershell runspace 
      Runspace runspace = RunspaceFactory.CreateRunspace(); 

      // open it 
      runspace.Open(); 

      // create a pipeline and feed it the script text 
      Pipeline pipeline = runspace.CreatePipeline(); 
      pipeline.Commands.AddScript(scriptText); 

      // add an extra command to transform the script output objects into nicely formatted strings 
      // remove this line to get the actual objects that the script returns. For example, the script 
      // "Get-Process" returns a collection of System.Diagnostics.Process instances. 
      pipeline.Commands.Add("Out-String"); 

      // execute the script 
      Collection<PSObject> results = pipeline.Invoke(); 

      // close the runspace 
      pipeline.Dispose(); 
      runspace.Close(); 

      // convert the script result into a single string 
      StringBuilder stringBuilder = new StringBuilder(); 
      foreach (PSObject obj in results) 
      { 
       stringBuilder.AppendLine(obj.ToString()); 

      } 

      // return the results of the script that has 
      // now been converted to text 
      return stringBuilder.ToString(); 
     } 

     // helper method that takes your script path, loads up the script 
     // into a variable, and passes the variable to the RunScript method 
     // that will then execute the contents 
     private void Form1_Load(object sender, EventArgs e) 
     { 
      DirectoryInfo dinfo = new DirectoryInfo(@"C:\utils"); 
      FileInfo[] Files = dinfo.GetFiles("*.ps1"); 
      foreach (FileInfo file in Files) 
      { 
       comboBox1.Items.Add(file.Name); 
      } 
     } 

     private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      textBox1.Text = RunScriptResult; 
     } 
     private void textBox1_TextChanged(object sender, EventArgs e) 
     { 
      Thread.Sleep(1000); 
     } 

     private void label1_Click(object sender, EventArgs e) 
     { 

     } 

     private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
     { 

     } 
    } 

} 

EDIT: Рабочий скрипт

using System; 
using System.Text; 
using System.Windows.Forms; 
using System.Collections.ObjectModel; 
using System.Management.Automation; 
using System.Management.Automation.Runspaces; 
using System.ComponentModel; 
using System.Threading; 
using System.IO; 



namespace ServerStatusChecks 
{ 
    public partial class Form1 : Form 
    { 
     private BackgroundWorker bw = new BackgroundWorker(); 
     public string ScriptName { get; set; } 
     static string RunScriptResult; 
     public Form1() 
     { 
      InitializeComponent(); 
      bw.WorkerReportsProgress = true; 
      bw.WorkerSupportsCancellation = true; 
      bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
      bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
     } 


     public void button1_Click(object sender, EventArgs e) 
     { 

      if (bw.IsBusy != true) 
      { 
       bw.RunWorkerAsync(); 
      } 
      // run our script and put the result into our textbox 
      // NOTE: make sure to change the path to the correct location of your script 

     } 

     private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      switch (comboBox1.SelectedIndex) 
      { 
       case 1: 
        ScriptName = @"c:\utils\Script1.ps1"; 
        break; 
       case 2: 
        ScriptName = @"c:\utils\Script2.ps1"; 
        break; 
       default: 
        ScriptName = @"c:\utils\Script3.ps1"; 
        break; 
      } 
     } 

     private void bw_DoWork(object sender, EventArgs e) 
     { 
      var loadScript = LoadScript(ScriptName); 

      if (string.IsNullOrWhiteSpace(loadScript)) return; 

      RunScriptResult = RunScript(loadScript); 
     } 

     private static string LoadScript(string filename) 
     { 
      if (!File.Exists(filename)) return ""; 

      var fileContents = new StringBuilder(); 

      var lines = File.ReadAllLines(filename); 

      foreach (var line in lines) 
      { 
       fileContents.Append(line + "\n"); 
      } 

      return fileContents.ToString(); 
     } 

     private static string RunScript(string scriptText) 
     { 
      //should start from this line 
      // create Powershell runspace 
      Runspace runspace = RunspaceFactory.CreateRunspace(); 
      runspace.Open(); 

      // create a pipeline and feed it the script text 
      Pipeline pipeline = runspace.CreatePipeline(); 
      pipeline.Commands.AddScript(scriptText); 

      // add an extra command to transform the script output objects into nicely formatted strings 
      // remove this line to get the actual objects that the script returns. For example, the script 
      // "Get-Process" returns a collection of System.Diagnostics.Process instances. 
      pipeline.Commands.Add("Out-String"); 

      // execute the script 
      Collection<PSObject> results = pipeline.Invoke(); 

      // close the runspace 
      pipeline.Dispose(); 
      runspace.Close(); 


      StringBuilder stringBuilder = new StringBuilder(); 
      foreach (PSObject obj in results) 
      { 
       stringBuilder.AppendLine(obj.ToString()); 

      } 

      // return the results of the script that has 
      // now been converted to text 
      return stringBuilder.ToString(); 
     } 

     // helper method that takes your script path, loads up the script 
     // into a variable, and passes the variable to the RunScript method 
     // that will then execute the contents 
     private void Form1_Load(object sender, EventArgs e) 
     { 
      DirectoryInfo dinfo = new DirectoryInfo(@"C:\utils"); 
      FileInfo[] Files = dinfo.GetFiles("*.ps1"); 
      foreach (FileInfo file in Files) 
      { 
       comboBox1.Items.Add(file.Name); 
      } 
      comboBox1.SelectedIndex = 0; 
     } 

     private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      textBox1.Text = RunScriptResult; 
     } 
     private void textBox1_TextChanged(object sender, EventArgs e) 
     { 
      Thread.Sleep(1000); 
     } 

    } 

} 

ответ

0

Это то, что я хотел бы сделать:

  1. Это свойство: private string RunScript(string scriptText) не должно быть собственностью. Это должен быть метод. Удалите get и set. И, вероятно, вам нужно будет сделать это static. Кроме того, я бы не использовал одно и то же имя для метода, как свойство сверху.

  2. Добавить эту логику:

    if (comboBox1.SelectedIndex == 0) 
    { 
        ScriptName = @"c:\utils\Script1.ps1"; 
    } 
    if (comboBox1.SelectedIndex == 1) 
    { 
        ScriptName = @"c:\utils\Script2.ps1"; 
    } 
    if (comboBox1.SelectedIndex == 2) 
    { 
        ScriptName = @"c:\utils\Script3.ps1"; 
    } 
    

    к comboBox1_SelectedIndexChanged. Обратите внимание, что я удалил объявления с несколькими переменными. Вы должны иметь доступ к тому, который находится сверху.

  3. Измените StreamReader на простой File.ReadAllLines(ScriptName); Это вернет массив каждой строки в файле. Если вам действительно нужно пройти через каждую строку и добавить \n, вы можете это сделать. Это упрощает код.

Итак, моя версия будет выглядеть так:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    switch (comboBox1.SelectedIndex) 
    { 
     case 1: 
      ScriptName = @"c:\utils\Script2.ps1"; 
      break; 
     case 2: 
      ScriptName = @"c:\utils\Script3.ps1"; 
      break; 
     default: 
      ScriptName = @"c:\utils\Script1.ps1"; 
      break; 
    } 
} 

private void bw_DoWork(object sender, EventArgs e) 
{ 
    var loadScript = LoadScript(ScriptName); 

    if (string.IsNullOrWhiteSpace(loadScript)) return; 

    RunScriptResult = RunScript(loadScript); 
} 

private static string LoadScript(string filename) 
{  
    if (!File.Exists(filename)) return ""; 

    var fileContents = new StringBuilder(); 

    var lines = File.ReadAllLines(filename); 

    foreach (var line in lines) 
    { 
     fileContents.Append(line + "\n"); 
    } 

    return fileContents.ToString(); 
} 

private static string RunScript(string scriptText) 
{   
    //should start from this line 
    // create Powershell runspace 
    Runspace runspace = RunspaceFactory.CreateRunspace(); 
    //bla bla bla bla 
    return "something"; 
} 

Все остальное, должно быть таким же

+0

Я установил логику в SelectedIndexChanged Однако удаление свойство, как предположил бы также остановить фонового работника, не так ли? в частности RunScriptResult = RunScript (LoadScript (ScriptName)); – Ericrs

+0

Да, но эта логика не должна находиться внутри свойства. Фоновый работник и связанная с ним логика должны запускаться только после нажатия кнопки –

+0

Если вы хотите использовать это свойство как метод, удалите 'get' и' set'. Вам, вероятно, понадобится сделать его «статическим», а также –

Смежные вопросы