Home > database >  How to wait for a power shell script completion?
How to wait for a power shell script completion?

Time:09-30

I am invoking the power shell script using the below C# code.

        public bool RunScript(string scriptFile)
        {
           bool b = false;
       
        using (Process process = new Process())
        {
            var startInfo = new ProcessStartInfo()
            {
                FileName = "powershell.exe",
                Arguments = $"-NoProfile -ExecutionPolicy unrestricted -file \"{scriptFile}\"",
                UseShellExecute = false
            };
            process.StartInfo = startInfo;
            process.Exited  = new EventHandler(ProcessFinished);
            process.Start();
            process.WaitForExit();
            b = (process.ExitCode == 0) ? true : false;
        }
        return b;
    }

    private static void ProcessFinished(object sender, EventArgs e)
    {
        Process p = (Process)sender;
        int exitCode = p.ExitCode;
    }

In the power shell script, I am executing the below command:

Start-Process "C:\Program Files\SASHome\SASFoundation\9.4\core\sasexe\sasoact.exe" -ArgumentList "action=Submit datatype=SASFile filename=""C:\MyProject\test.sas"" progid=SAS.Application.940"

I want to wait my C# program to complete the above command. But the process is starting and immediately return with the code 0.

CodePudding user response:

You should be able to use the -Wait option on the Start-Process command.

Personally I would call SAS directly using normal command instead of trying to use the sasoact.exe tool. The sas.exe command should be in the 9.4 directory.

Here is an example showing how powershell waits for the SAS program to finish before running the next command:

PS C:\downloads> date
Thursday, September 29, 2022 3:31:41 PM
PS C:\downloads> Start-Process -FilePath "C:\Program Files\SASHome\SASFoundation\9.4\sas.exe"  -ArgumentList """C:\downloads\10seconds.sas"" -nologo -rsasuser" -Wait -WindowStyle Hidden
>> 
PS C:\downloads> date
Thursday, September 29, 2022 3:31:59 PM
PS C:\downloads>

CodePudding user response:

tl;dr

Change the content of your PowerShell script (.ps1) to the following:

# Note: If sasoact.exe isn't a *console* application, append `| Write-Output`
& 'C:\Program Files\SASHome\SASFoundation\9.4\core\sasexe\sasoact.exe' action=Submit datatype=SASFile filename='C:\MyProject\test.sas' progid=SAS.Application.940
exit $LASTEXITCODE

Typically, external executables that have CLIs are console applications, and, except in unusual circumstances, Start-Process is not the right way to invoke them.

  • The unusual circumstances where Start-Process is needed are: needing to run the program in a new console window (including with elevation) or needing to run with a different user identity.

Invoking console applications directly has the following benefits:

  • synchronous invocation (whereas with Start-Process you'd have to use the -Wait switch)

  • the process exit code is reported in the automatic $LASTEXITCODE variable (with Start-Process, you'd have to use -Wait and -PassThru and query the .ExitCode property on the System.Diagnostics.Process instance that is returned)

  • the process' stdout and stderr streams are directly connected to PowerShell's output streams, allowing the output to be captured and redirected (whereas with Start-Process you can only redirect to files with -RedirectStandardOutput and -RedirectStandardError).

Note that even if the program being invoked isn't a console application, you can still force its synchronous execution and reflection of its exit code in $LASTEXITCODE by simply piping its direct invocation to | Write-Output - see this answer for more information.

Therefore,

  • Related