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 (withStart-Process
, you'd have to use-Wait
and-PassThru
and query the.ExitCode
property on theSystem.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,