title: Passing and invoking System.Action<> from powershell to c#
body: <p>I am working on a c# program using <code>System.Speech.Recognition</code> to recognize speech and run PowerShell commands according to what is said. </p>
  
  <p>I have the following powershell script that represents a macro for creating a speech command:</p>
  
  <pre><code>Add-Type -Path ".\GAVPI.Lib.dll"
  Add-Type -Path ".\GAVPI.Lib.Logging.dll"
  
  [Action[GAVPI.Lib.Logging.Parameter]]$speechRecognized = {
      param($i) 
      [System.Windows.MessageBox]::Show("test")
  }
  
  $parameter = New-Object -TypeName GAVPI.Lib.Logging.Parameter -ArgumentList 
  ("parameter", "value")
  
  $phrase = New-Object -TypeName GAVPI.Lib.Core.Triggers.Phrase -ArgumentList 
  ("default","test", $speechRecognized, $parameter)
  
  return $phrase
  </code></pre>
  
  <p>This phrase object is used to tell what commands can be said and recognized.  It successfully is passed to c# like this:</p>
  
  <pre><code> var list = new List&lt;Phrase&gt;();
  
          var ps = PowerShell.Create();
          var run = RunspaceFactory.CreateRunspace();
          ps.Runspace = run;
          run.Open();
  
          var script = ps.AddScript(".\\PowershellTemplate.ps1", true);
          var result = ps.Invoke();
  
          foreach (var psObject in result)
          {
              if (psObject.BaseObject is Phrase)
              {
                  list.Add((Phrase)psObject.BaseObject);
              }
          }
          return list;
  </code></pre>
  
  <p>When a command is recognized,the Phrase class invokes the Action:</p>
  
  <pre><code>public override void Run(Parameter selectedparameter)
  {
  
      if (parAction != null)
      {
          parAction.Invoke(selectedparameter);
      }
  }
  private Action&lt;Parameter&gt; parAction;
  </code></pre>
  
  <p>When the program is run, if you say "test parameter" it invokes the <code>action&lt;parameter&gt;</code> in the phrase class, which invokes the script block in powershell.</p>
  
  <p>I get the following exception at the <code>parAction.Invoke(selectedparameter);</code> line:</p>
  
  <blockquote>
    <p>There is no Runspace available to run scripts in this thread. You can
    provide one in the DefaultRunspace property of the
    System.Management.Automation.Runspaces.Runspace type. The script block
    you attempted to invoke was: </p>
  
  <pre><code>param($i)...w("test")
  </code></pre>
  </blockquote>
  
  <p>How do I pass the runspace to the <code>Sysem.Action&lt;Parameter&gt;</code> so that it can run the PowerShell script block?</p>