tags:

views:

92

answers:

2

EDIT: I figured out how to solve the specific code broken part of my question (see my answer bellow), but I'm still looking for resources on integrating powershell and C# so please still feel free to comment or answer!

I found a simple example of making your C# objects visible to powershell scripts and I've been playing around with it.

Using the following code:

  public partial class MainWindow : Window
        {
            public string MyName = "Evan";

            public MainWindow()
            {
                InitializeComponent();
                MessageBox.Show(RunScript("$DemoForm | Get-Member"));
                MessageBox.Show(RunScript("$DemoForm.MyName"));
                MessageBox.Show(RunScript("$DemoForm.Title"));
            }

            private string RunScript(string scriptText)
            {
                // create Powershell runspace

                Runspace runspace = RunspaceFactory.CreateRunspace();

                // open it

                runspace.Open();
                runspace.SessionStateProxy.SetVariable("DemoForm", this);
                // 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

                runspace.Close();

                // convert the script result into a single string

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

                return stringBuilder.ToString();
            }


}

I get the expected results from these two lines:

MessageBox.Show(RunScript("$DemoForm | Get-Member"));
MessageBox.Show(RunScript("$DemoForm.Evan"));

But this line doesn't work (no error, it just returns an empty string):

MessageBox.Show(RunScript("$DemoForm.Title"));

Any idea why the first two work but not the third? Does it have something to do with threading (Having to access certain gui things from an sta thread?)? It seems like similar functionality was working with WindowsForms for the poster of the sample code.

Also, besides that example I linked to and this one here I haven't been able to find many resources online about linking c# and powershell. Ultimately I'm trying to create an application that will be scriptable via powershell - does anyone know of other good online resources or a good book that covers this?

Thanks!!!!

+1  A: 

Shouldn't it be .Text instead of .Title?

MessageBox.Show(RunScript("$DemoForm.Text"));
Andy
I changed it from Text to Title in my code since I'm using wpf not windforms, but both $DemoForm.Text and $DemoFrom.Title return empty strings. Thanks for your answer thought!
Evan
+2  A: 

I got it! (with help from this video). The above code needs this line to work

runspace.ThreadOptions = PSThreadOptions.UseCurrentThread

Which makes sense to me, I've always had trouble with STA threads and all that jaz :).

Evan
You should mark this as the answer.
JasonMArcher