Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 747113
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T14:10:05+00:00 2026-05-14T14:10:05+00:00

Does anyone know how best to determine the specific underlying cause of this exception?

  • 0

Does anyone know how best to determine the specific underlying cause of this exception?

Consider a WCF service that is supposed to use Powershell 2.0 remoting to execute MSBuild on remote machines. In both cases the scripting environments are being called in-process (via C# for Powershell and via Powershell for MSBuild), rather than ‘shelling-out’ – this was a specific design decision to avoid command-line hell as well as to enable passing actual objects into the Powershell script.

An abridged version of the Powershell script that calls MSBuild is shown below:

function Run-MSBuild
{
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Build.Engine")

    $engine = New-Object Microsoft.Build.BuildEngine.Engine
    $engine.BinPath = "C:\Windows\Microsoft.NET\Framework\v3.5"

    $project = New-Object Microsoft.Build.BuildEngine.Project($engine, "3.5")
    $project.Load("deploy.targets")
    $project.InitialTargets = "DoStuff"

    # Process the input object
    while ($input.MoveNext())
    {
        # Set MSBuild Properties & Item
    }


    # Optionally setup some loggers (have also tried it without any loggers)
    $consoleLogger = New-Object Microsoft.Build.BuildEngine.ConsoleLogger
    $engine.RegisterLogger($consoleLogger)

    $fileLogger = New-Object Microsoft.Build.BuildEngine.FileLogger
    $fileLogger.Parameters = "verbosity=diagnostic"
    $engine.RegisterLogger($fileLogger)


    # Run the build - this is the line that throws a CmdletInvocationException
    $result = $project.Build()

    $engine.Shutdown()
}

When running the above script from a PS command prompt it all works fine. However, as soon as the script is executed from C# it fails with the above exception.

The C# code being used to call Powershell is shown below (remoting functionality removed for simplicity’s sake):

// Build the DTO object that will be passed to Powershell
dto = SetupDTO()

RunspaceConfiguration runspaceConfig = RunspaceConfiguration.Create();
using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfig))
{
    runspace.Open();

    IList errors;
    using (var scriptInvoker = new RunspaceInvoke(runspace))
    {
        // The Powershell script lives in a file that gets compiled as an embedded resource
        TextReader tr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("MyScriptResource"));
        string script = tr.ReadToEnd();

        // Load the script into the Runspace
        scriptInvoker.Invoke(script);

        // Call the function defined in the script, passing the DTO as an input object
        var psResults = scriptInvoker.Invoke("$input | Run-MSBuild", dto, out errors);
    }
}

NOTE: The overload of the Invoke() method allows you to pass in an IEnumerable object and it takes care of instantiating an enumerator to in the Powershell variable ‘$input’ – this then gets passed into the script via the pipeline. Here are some supporting links:

  • http://msdn.microsoft.com/en-us/library/ms569104(VS.85).aspx
  • http://knicksmith.blogspot.com/2007/03/managing-exchange-2007-recipients-with.html (jump to the ‘Passing an Input Object to the Runspace’ section)

Assuming that the issue was related to MSBuild outputting something that the Powershell runspace can’t cope with, I have also tried the following variations to the second .Invoke() call:

var psResults = scriptInvoker.Invoke("$input | Run-MSBuild | Out-String", dto, out errors);
var psResults = scriptInvoker.Invoke("$input | Run-MSBuild | Out-Null", dto, out errors);
var psResults = scriptInvoker.Invoke("Run-MSBuild | Out-String");
var psResults = scriptInvoker.Invoke("Run-MSBuild | Out-String");
var psResults = scriptInvoker.Invoke("Run-MSBuild | Out-Null");
var psResults = scriptInvoker.Invoke("Run-MSBuild");

Note how the underlying issue still occurs irrespective of whether an input object is used.

I’ve also looked at using a custom PSHost (based on this sample: http://blogs.msdn.com/daiken/archive/2007/06/22/hosting-windows-powershell-sample-code.aspx), but during debugging I was unable to see any ‘interesting’ calls to it being made.

Do the great and the good of Stackoverflow have any insight that might save my sanity?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T14:10:05+00:00Added an answer on May 14, 2026 at 2:10 pm

    I can get the following code to work but I get a warning that MSBUILD engine wants to be run on a STA thread. Unfortunately the thread created by the PowerShell engine to execute the script is MTA. That said, my little sample works:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Management.Automation;
    using System.Collections;
    
    namespace RunspaceInvokeExp
    {
        class Program
        {
            static void Main()
            {
                var script = @"
    function Run-MSBuild 
    { 
        [System.Reflection.Assembly]::LoadWithPartialName(""Microsoft.Build.Engine"") 
    
        $engine = New-Object Microsoft.Build.BuildEngine.Engine 
        $engine.BinPath = ""C:\Windows\Microsoft.NET\Framework\v3.5"" 
    
        $project = New-Object Microsoft.Build.BuildEngine.Project($engine, ""3.5"") 
        $project.Load(""deploy.targets"") 
        $project.InitialTargets = ""DoStuff"" 
    
        # Process the input object 
        while ($input.MoveNext()) 
        { 
            # Set MSBuild Properties & Item 
        } 
    
        # Optionally setup some loggers (have also tried it without any loggers) 
        $consoleLogger = New-Object Microsoft.Build.BuildEngine.ConsoleLogger 
        $engine.RegisterLogger($consoleLogger) 
    
        $fileLogger = New-Object Microsoft.Build.BuildEngine.FileLogger 
        $fileLogger.Parameters = ""verbosity=diagnostic"" 
        $engine.RegisterLogger($fileLogger) 
    
        # Run the build - this is the line that throws a CmdletInvocationException 
        $result = $project.Build() 
    
        $engine.Shutdown() 
    } 
    ";
                using (var invoker = new RunspaceInvoke())
                {
                    invoker.Invoke(script);
                    IList errors;
                    Collection<PSObject> results = invoker.Invoke(@"$input | Run-MSBuild", new[] {0}, out errors);
                    Array.ForEach<PSObject>(results.ToArray(), Console.WriteLine);
                }
            }
        }
    }
    

    Which line of your C# code fails? Also, can you post some of the specifics from the exception. You can work around the MTA thread issue by doing something like this:

    using System;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Management.Automation;
    using System.Management.Automation.Runspaces;
    
    namespace RunspaceInvokeExp
    {
        class Program
        {
            [STAThread]
            static void Main()
            {
                var script = @"
    function Run-MSBuild 
    { 
        [System.Reflection.Assembly]::LoadWithPartialName(""Microsoft.Build.Engine"") 
    
        $engine = New-Object Microsoft.Build.BuildEngine.Engine 
        $engine.BinPath = ""C:\Windows\Microsoft.NET\Framework\v3.5"" 
    
        $project = New-Object Microsoft.Build.BuildEngine.Project($engine, ""3.5"") 
        $project.Load(""deploy.targets"") 
        $project.InitialTargets = ""DoStuff"" 
    
        # Process the input object 
        while ($input.MoveNext()) 
        { 
            # Set MSBuild Properties & Item 
        } 
    
        # Optionally setup some loggers (have also tried it without any loggers) 
        $consoleLogger = New-Object Microsoft.Build.BuildEngine.ConsoleLogger 
        $engine.RegisterLogger($consoleLogger) 
    
        $fileLogger = New-Object Microsoft.Build.BuildEngine.FileLogger 
        $fileLogger.Parameters = ""verbosity=diagnostic"" 
        $engine.RegisterLogger($fileLogger) 
    
        # Run the build - this is the line that throws a CmdletInvocationException 
        $result = $project.Build() 
    
        $engine.Shutdown() 
    } 
    
    Run-MSBuild
    ";
    
                Runspace runspace = RunspaceFactory.CreateRunspace();
                Runspace.DefaultRunspace = runspace;
                runspace.Open();
    
                EngineIntrinsics engine = runspace.SessionStateProxy.
                    GetVariable("ExecutionContext") as EngineIntrinsics;
                ScriptBlock scriptblock = 
                    engine.InvokeCommand.NewScriptBlock(script);
                Collection<PSObject> results = scriptblock.Invoke(new[] { 0 });
                Array.ForEach<PSObject>(results.ToArray(), Console.WriteLine);
    
                runspace.Close(); // Really should be in a finally block
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Does anyone know the best solution for this? When i resize my browser some
Does anyone know the best way to create a SQL Server CE (Compact 3.5)
does anyone know the best way to insert a column in a datatable at
Is it possible, or does anyone know the best way to capture MSN chats?
Does anyone know of any best practices or 'standard' techniques for implementing authentication between
Does anyone know of a good Command Prompt replacement? I've tried bash/Cygwin, but that
Does anyone know of any existing packages or libraries that can be used to
Does anyone know a good Java lib that will hook into SVN so I
Does anyone know the best way to deal with concurrent uploads and what todo
Does anyone know the best opensource for .NET controls? With Dev Express, Telerik, they

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.