I am using integration studio to write my custom .NET code. My requirement is to have an application that executes FFMpeg commands in the command line.
For that purpose, I created a new extension and in it I created a public static method that returns string (the output of the console command). Here is my code:
public static string ffmpegCommandNewNewNew(string commandToBeExecuted)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.WorkingDirectory = "c:\\ffmpeg\\bin";
startInfo.FileName = @"ffmpeg.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "/C -h";
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
Process exeProcess = Process.Start(startInfo);
// string error = exeProcess.StandardError.ReadToEnd();
string output = exeProcess.StandardOutput.ReadToEnd();
exeProcess.WaitForExit();
return output;
}
When I'm running my application in service studio that uses this code (it's a simple app I created only for testing purposes of this logic, it has a button and on click of the button the displayed above action is called and it is supposed to display on the screen the output the action returns), I get the following error: The system cannot find the file specified.
I am assuming this refers to the 'startInfo.FileName = @"ffmpeg.exe";' line of my code, but I ran this exact code in a .NET console application and it returns the expected output, so now I have a hard time exploring what exactly is the cause of my issue.
I tried placing my FFMpeg folder in the folder structure of the extension and changed the working directory to the new location, however that didn't work.
Any suggestions on what might be causing this issue?
Hi M Kr,
use below code in your extension and also try to add my created extensions in forge so you can directly use from there
ssExitCode = 0;
ssErrorMessage = "";
System.Diagnostics.Process ProcessEXE = new System.Diagnostics.Process();
ssErrorMessage = "ssErrorMessage 1 " + ssErrorMessage;
try
ssErrorMessage = "ssErrorMessage 2" + ssErrorMessage;
ProcessEXE.StartInfo.FileName = ssCommandName;
// Set UseShellExecute to false for redirection.
// false if the process should be created directly from the executable file
ProcessEXE.StartInfo.UseShellExecute = false;
//ProcessEXE.StartInfo.WorkingDirectory = System.Environment.CurrentDirectory;
//EnableRaisingEvents property indicates whether the component should be notified when the operating system has shut down a process
ProcessEXE.StartInfo.Arguments = ssArguments;
ProcessEXE.StartInfo.RedirectStandardOutput = true;
ProcessEXE.StartInfo.RedirectStandardError = true;
ProcessEXE.EnableRaisingEvents = true;
ProcessEXE.StartInfo.CreateNoWindow = true;
ProcessEXE.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ProcessEXE_OutputDataReceived);
ProcessEXE.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(ProcessEXE_OutputDataReceived);
// logger.DebugFormat("Process Started.");
ProcessEXE.Start();
// Start the asynchronous read of the sort output stream.
ProcessEXE.BeginErrorReadLine();
ProcessEXE.BeginOutputReadLine();
//The WaitForExit overload is used to make the current thread wait until the associated process terminates
// logger.DebugFormat("Process Waiting for exit.");
ProcessEXE.WaitForExit();
if (ProcessEXE.ExitCode == 0)
//logger.Debug(string.Format("Shell Process exited with exit code {0}", ProcessEXE.ExitCode));
else
// throw error here if required - check the return error code
//logger.Warn(string.Format("Shell Process exited with exit code {0}", ProcessEXE.ExitCode));
catch (Exception ex)
ssErrorMessage = "ssErrorMessage final" + ssErrorMessage;
ssExitCode = ProcessEXE.ExitCode;
Hi @Chandra Vikas Sharma
How am I supposed to initialize ProcessEXE_OutputDataReceived? Or is it an argument?
Hi,
below is code for ProcessEXE_OutputDataReceived
void ProcessEXE_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
StringBuilder sb = new StringBuilder(string.Empty);
if (e == null) return;
if (e.Data == null)
//No processing
// your logic to detect error msg out from output - if at all required
if (sb.ToString().ToUpper().IndexOf("ERROR") > 0)
string smessage = "Error text found in output.";
// do your error response action here .
catch (Exception exp)
//logger.ErrorFormat("Error in ProcessEXE_OutputDataReceived Message:{0}", exp.Message);
//logger.ErrorFormat("Error in ProcessEXE_OutputDataReceived Data Received:{0}", e.Data);
// either throw error msg or kill the process
finally
// Not throwing the exception
Thank you for your answer @Chandra Vikas Sharma
What am I supposed to pass for the arguments sender and e from Service Studio?
In my case i am passing
@Chandra Vikas Sharma
With every solution, including yours I get the same exception: The system cannot find the file specified
this error generally occurs if file is not in the specified directory or it not able to access the file can you debug you OS code and also check the service center log.
I checked service center logs. There isn't much helpful info, just the same exception reiterated
What is really confusing for me is that when I check in file explorer the file is there.
Additionally, when I test this exact same code, with that exact same location (c:\ffmpeg\bin\ffmpeg.exe) in a .NET console application, it works without any issues.
Make sure that you have the c:\ffmpeg\bin\ffmpeg.exe installed in server in that location otherwise it won't work, when you are testing in the console yours tests are being done in local machine.
Hope that it helps you
@Alexandre Yip How can I make sure of that? As far as I know it is installed in that location. When I check in file explorer the file is there.
But here, this is the result I get when trying it in integration studio and service studio:
Executing "C:\FFmpeg\bin\ffmpeg.exe" with arguments "-h". exception: The system cannot find the file specified
That error is indeed because the file is missing in the server.
" As far as I know it is installed in that location"
do you have access to the server where outsystems is installed?
when you publish the extension using the integration Studio, the runtime code is deployed in the outsystems server. So every paths that you refer to is relative to where the code is deployed.
For that executable to work you need to install / Place the executable and dlls in the outsystems server in known location.
Hi @Alexandre Yip
Thank you for your answer!
How can I install / Place the executable and dlls in the outsystems server?
If you don't have access to the server, other option is to add the executable and dlls as resources to the module where you are using the extension
check this link
https://success.outsystems.com/documentation/11/developing_an_application/use_data/use_resources/
Choose deploy on target directory
You will need to add an extra argument Working Directory to the extension
Use the filesystem extension to get the application directory path plus the module name and
"The resource is deployed to the sub-directory set in the Target Directory property, which is created under the deploy directory of the module."
provide this path to your extension.
I Upload the the extension in forge you can download and integrate with OS code and check what
Exitcode and Errormessage return
https://www.outsystems.com/forge/component-overview/14792/executeprocessutility/
Thank you for the extension. This is the error message I am getting: No process is associated with this object.