98
Views
15
Comments
My code works in .NET console app but not in integration studio.
Application Type
Reactive

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? 

2024-03-22 09-17-23
Chandra Vikas Sharma

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;

   

UserImage.jpg
M Kr

Hi @Chandra Vikas Sharma 

How am I supposed to initialize ProcessEXE_OutputDataReceived? Or is it an argument?

2024-03-22 09-17-23
Chandra Vikas Sharma

Hi,

below is code for ProcessEXE_OutputDataReceived 


 void ProcessEXE_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)

        {

            try

            {

                StringBuilder sb = new StringBuilder(string.Empty);

                if (e == null) return;


                if (e.Data == null)

                {

                    //No processing

                }

                else

                {

                    // 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

            }

        }

UserImage.jpg
M Kr

Thank you for your answer @Chandra Vikas Sharma 

What am I supposed to pass for the arguments sender and e from Service Studio?

2024-03-22 09-17-23
Chandra Vikas Sharma

In my case i am passing

UserImage.jpg
M Kr

@Chandra Vikas Sharma 

With every solution, including yours I get the same exception: The system cannot find the file specified 

2024-03-22 09-17-23
Chandra Vikas Sharma

Hi,

 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. 

UserImage.jpg
M Kr

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.


UserImage.jpg
Alexandre Yip

Hi M Kr, 

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 

UserImage.jpg
M Kr

@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.

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.

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 


UserImage.jpg
Alexandre Yip

Hi M Kr, 

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. 

Hope that it helps you 

UserImage.jpg
M Kr

Hi @Alexandre Yip 

Thank you for your answer!

How can I install / Place the executable and dlls in the outsystems server?


UserImage.jpg
Alexandre Yip

Hi M Kr, 

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. 

Hope that it helps you 

2024-03-22 09-17-23
Chandra Vikas Sharma

Hi M Kr,

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/


 

UserImage.jpg
M Kr

Hi @Chandra Vikas Sharma 

Thank you for the extension. This is the error message I am getting: No process is associated with this object. 

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.