1

I have the below code snippet which runs from a C# file in the backend.

using (Process process = new Process())
{
    process.StartInfo.FileName = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
    String cmd = "C:\\Users\\xyz\\AppData\\Local\\Temp\\2\\Demo.ps1";
    process.StartInfo.Arguments = cmd;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = false;
    process.StartInfo.RedirectStandardError = true;
    StringBuilder error = new StringBuilder();

    process.Start();

    while (true)
    {
        bool hasExited = process.HasExited;

        String errorStr = null;
        while ((errorStr = process.StandardError.ReadLine()) != null)
            error.AppendLine(errorStr);

        if (hasExited)
            break;

        Thread.Sleep(100);
    }

    if (process.ExitCode != 0 || error.Length > 0)
        throw new Exception(error.ToString());
}

Demo.ps1

write-host "Working Properly now! "

I want the string to be printed in the same PowerShell window which is open, but somehow it's not showing any output to the opened PowerShell window. If I redirect output to a text file then it is clearly visible.

2
  • 2
    If you want to run PowerShell code from C#, a better option (especially if you want easy access to the output) is to use the PowerShell Class Commented Nov 1, 2023 at 8:06
  • Three bogus answers, with at least one generated by ChatGPT? If that is the case, it is a really sad state of Stack Overflow. Commented Nov 2, 2023 at 23:31

1 Answer 1

0

This is a better approach in my opinion. It is avoiding the hassle of trying to manage by hand the output (std/err).

There is a functionality directly in C#. It is simplifying the interaction and easier for debugging as well.

try
{
    ScriptBuilder script = new ScriptBuilder();
    script.LoadScript(File.ReadAllText(@"some.ps1"));
    script.AddParameters(new Dictionary<string, string>
    {
        {"param1", "param1" }
    });
    script.Run();
    System.Console.WriteLine("Hit any key to exit.");
    System.Console.ReadKey();
}
catch (Exception ex)
{
    System.Console.WriteLine(ex.Message);
}

This is a simple wrapper used

public class ScriptBuilder
{
    private readonly PowerShell powerShellScript;

    public ScriptBuilder()
    {
        powerShellScript = PowerShell.Create();
    }

    public void LoadScript(string script)
    {
        powerShellScript.AddScript(script);
    }

    public void AddParameters(Dictionary<string, string> parameters)
    {
        foreach (var parameter in parameters)
        {
            powerShellScript.AddParameter(parameter.Key, parameter.Value);
        }
    }

    public void Run()
    {
        var output = new PSDataCollection<PSObject>();
        output.DataAdded += Output_DataAdded;

        powerShellScript
            .BeginInvoke<PSObject, PSObject>(null, output)
            .AsyncWaitHandle
            .WaitOne();

        powerShellScript.Invoke();
    }

    private static void Output_DataAdded(object? sender, DataAddedEventArgs e)
    {
        if (sender == null)
        {
            return;
        }
        PSObject newRecord = ((PSDataCollection<PSObject>)sender)[e.Index];
        Console.WriteLine(newRecord);
    }
}

This example is passing arguments to the script and executing the script.

These are some links which could help with further extending the code:

powershell-host

system.management.automation.powershell

PowerShell output

Sign up to request clarification or add additional context in comments.

3 Comments

@mklement0 Thanks for pointing out. I forgot there was a wrapper. It was an old project. Answer updated.
How does this answer the question? It doesn't seem to be tailored to the question at all.
@PeterMortensen it shows a better approach. Facilitating the work with the output, replacing the raw string with objects. At least it is an alternative.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.