Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[SOLVED] Run, Fortran.bat, Run!

Discussion in 'Scripting' started by AlanMattano, Apr 24, 2018.

  1. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    In my game I'm able to launch an external application by using:

    Code (CSharp):
    1. Process.Start(Application.dataPath + "/StreamingAssets/[S]Forest[/S]Fortran.exe");
    But I'm a novice in about batching, command line & arguments
    I make my first batch file "ForestRunFortran.bat"
    And if I double click it, runs the application perfectly!
    But if I make it run via Unity by using:

    Code (CSharp):
    1. Process.Start(Application.dataPath + "/StreamingAssets/Fortran.bat");
    it does not run :confused: I think it launches but it closes itself without working.
    Any idea why?

    My final gold, if it is possible, is to run it in a separate thread and render this prompt embedded in a texrender inside my game. Or run inside my game the CMD prop but that is not important now.

    Inside the fortran.bat file, there is this argument
    Fortran.exe <Input.txt >output.txt

    Inside Input.txt has the command line for executing inside Fortran.exe
    Fortran.exe can be run via CMD and control via command line.
     
    Last edited: Apr 25, 2018
    hippocoder likes this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,519
    A batch file is a piece of text that by convention the CMD.EXE command processor will open for you, then interpret the instructions inside and try to do them according to its syntax rules.

    In your case, CMD.EXE will launch Forest.exe and take stdin from Input.txt and send stdout to output.txt

    When you launch it from within Unity, CMD.EXE (or COMMAND.COM on older windows systems) isn't involved.

    You can try specifying CMD.EXE FORESTRUN.BAT but that will only work if CMD.EXE is in the path that Unity searches, which I'm not sure what it is. There are probably other workaround ways but in general I don't think this approach is going to result in reliable software: the moment you install on a system that doesn't have CMD.EXE available, or in the path, your batch file won't run.

    As for threading and interprocess communication (a separate program/process communicating with your Unity project), let me just say that is a HUGE undertaking and will require a lot of research into various mechanisms, pretty much all of which will be platform dependent, i.e., Windows or Mac, etc.
     
    AlanMattano likes this.
  3. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Ok, that is a lot of info thank!
    For simplicity in this post, I will change the word Forest to Fortran

    Multi-Threading aside, I wish not to convert this Fortran exe to C#. I need to launch it if is possible. So I will use this game only for Windows standalone, for now(no other platforms). Also, the instructions inside that I need to pass to the Fortran exe are always the same. So Is simple to control.
    I just need to run this bat or execute "
    Fortran.exe <Input.txt >output.txt
    "

    Here is the best example a friend found for my case:
    https://github.com/chfenger/xfoil_call/blob/master/Xfoil_call/main_form.cs
    The main code is in the main_form.cs file. Although all the messages are in Korean, it seems that the program generates for each run a command file named “call.bat”.
    It passes the input command to xfoil.exe placing the special command file on its standard input:
    xfoil.exe <command.dat
    The command.dat file is built “on the fly” by this program.
    In the main_form.cs at line 468 this program calls this “call.bat” command.
    In the next line (p.WaitForExit(12000)) it waits for the xfoil Fortuna results, but no longer than 12s

    ----------------------------------------------------------------------------------------------------------

    And Changing strategy?
    As second option I'm able to open CMD using process variable :

    Code (CSharp):
    1. process.StartInfo.FileName = "C:\\Windows\\system32\\cmd.exe";
    And pass the arguments that run the common line?
    I'm honestly don't know well how to do it
    But I understand from you that is not possible.

    To control it using arguments, these lines are always the same.
    as for example:
    Fortuna.exe that will be in Application.dataPath + "/StreamingAssets/Fortuna.exe"
    command1 (enter)
    command2 (enter)
    quit (enter)
     
    Last edited: Apr 25, 2018
  4. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,519
    I don't but there must be some google-worthy stuff out there. The main difference to note is that those "< input.txt" and "> output.txt" parts are NOT arguments in the strictest sense. They are directives to the shell (CMD or whatever) to redirect file handles prior to launching the process in question. The underlying process you launch will never see those as arguments.
     
  6. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    That makes sense; because as for example this line is not running.
    Process.Start(Application.dataPath + "/StreamingAssets/Fortrun.exe", " <Input.txt");
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,519
    It is probably attempting to pass (literally) the argument "<Input.txt" to fortrun.exe and choking it up.
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,519
  9. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    AlanMattano likes this.
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    It's for escape sequences, such as '\t' = tab, '\n' = newline, '\\' = single '\', '\"' single quotation, etc..
    If the character following the blackslash isn't a recognized escape sequence, you get an error.
    :)

    So, you can write:
    Code (csharp):
    1. string s = @"C:\Whatever";
    2. // or
    3. string s = "C:\\Whatever"; // same thing.
     
    AlanMattano likes this.
  12. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    And when we use '/' ?

    Code (CSharp):
    1. string s = "C:/Whatever";
     
  13. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Doesn't matter, not an escape-related character? :)
     
  14. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Ok, so here: link
    are using /r: and /out: inside the argument
    any idea what is for /r (i presume return or reference) and where to find the explanation or a list?
     
  15. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
  16. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,519
    When you see stuff on any language reference page, try and suss out what is what as far as what objects are being passed to what.

    In the example you link it shows creating a new Process object called compiler, then modifying the .Arguments field within its .StartInfo property.

    Looking up Process.StartInfo, you can see that it is a ProcessStartInfo object within the Process object.

    Ultimately you end up here, where there is some discussion of the properties of that object:

    https://msdn.microsoft.com/en-us/li...ics.processstartinfo.arguments(v=vs.110).aspx

    I'm sure there may be more stuff google-able with that same sleuthing approach.
     
  17. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
  18. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    If you're still looking to get this working, I fumbled around trying to make something similar work.

    I opened a program, and redirect both its stdin and stdout.
    I used Streams (StreamReader/Writer) to read in the text, write it.. snippet to explain my horrible words.
    Code (csharp):
    1. StreamWriter sw = process.StandardInput; // 'process' was my Process type variable.. as you probably guessed.
    2. StreamReader sr = process.StandardOutput;
    3. sw.Write(File.ReadAllText("test.txt"));
    4. string s = sr.ReadToEnd();
    5. using (StreamWriter sw2 = new StreamWriter("test2.txt")) sw2.Write(s);
    Now, I'm sure that's far from perfect ;)

    I'm not sure what's good practice, tbh, as I've never used this (maybe once I tried it before).
     
    AlanMattano likes this.
  19. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Yes, I'm still there googling and experimenting.
    I take out the Output side. I'm trying to run it!
    when I run it, the cmd prompt opens and closes immediately.
    I was able to see that there is a "0" zero.

    FortranPropt.jpg

    At the moment the code is

    Code (CSharp):
    1. private void RunFortranRun()
    2.     {
    3.         UnityEngine.Debug.Log("Run Fortran via call.bat example\n");
    4.  
    5.         try
    6.         {
    7.      
    8.             string path = Application.dataPath + "\\StreamingAssets\\";
    9.  
    10.             // GENERATE call.bat
    11.             FileStream callfile = new FileStream(path + "call.bat", FileMode.OpenOrCreate, FileAccess.ReadWrite);
    12.             StreamWriter callw = new StreamWriter(callfile);
    13.             callw.Write("Fortran.exe <Input.txt");
    14.             callw.Close();
    15.             callfile.Close();
    16.  
    17.      
    18.             // CALL Fortran
    19.             Process p = new Process();
    20.             p.StartInfo.FileName = path + "call.bat";
    21.             p.Start();
    22.             p.WaitForExit(5000);
    23.  
    24.         }
    25.         catch (System.Exception errorMessage)
    26.         {
    27.             UnityEngine.Debug.LogError("ERROR RUNNING FORTRAN: " +
    28.                 "\n Catch Code Exception: " + errorMessage);
    29.         }
    30.     }
    That probably blocks the code. I do not know where is coming from or how to take it out.
    Can "0" be the space between Fortran.exe and <Input.txt at line 13?

    Probably Windows is blocking as Kurt mention in his first answer.
    I will try to understand and experiment with your code. Thanks!
     
    Last edited: Apr 27, 2018
  20. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Okay, couple of small differences. I didn't use a .bat file to launch.
    Also, I didn't directly use the arguments from the command line.

    So my test simulation .. it used Console.Readline.

    I'm not sure if that's helpful extra info, but thought I'd be thorough as you're trying to work it out. :)

    This is the entire code. Complete with a bad/lazy example of having the program call itself, so I didn't have to make 2 programs. Sigh...
    Code (csharp):
    1. namespace Test_Code
    2. {
    3.     class Program
    4.     {
    5.         static void Main(string[] args)
    6.         {
    7.             if (args.Length == 0)
    8.             {
    9.                 Process process = new Process();
    10.                 process.StartInfo.RedirectStandardInput = true;
    11.                 process.StartInfo.RedirectStandardOutput = true;
    12.                 process.StartInfo.UseShellExecute = false;
    13.                 process.StartInfo.FileName = "Test Code.exe";
    14.                 process.StartInfo.Arguments = "test";
    15.  
    16.                 process.Start();
    17.                 StreamWriter sw = process.StandardInput;
    18.                 StreamReader sr = process.StandardOutput;
    19.                 sw.Write(File.ReadAllText("test.txt"));
    20.                 string s = sr.ReadToEnd();
    21.                 using (StreamWriter sw2 = new StreamWriter("test2.txt")) sw2.Write(s);
    22.                 process.WaitForExit();
    23.                 Console.ReadLine();
    24.  
    25.             }
    26.             if (args.Length > 0)
    27.             {
    28.                 string str = "";
    29.                  // Note, there was "end" on the last line of the file. Not necessary, but just what I used.
    30.                 while ((str = Console.ReadLine()) != "end")
    31.                 {
    32.                     Console.WriteLine(str);
    33.                 }
    34.             }    
    35.         }
    36.      
    37.         static void print(string msg)
    38.         {
    39.             Console.WriteLine(msg);
    40.         }
    41.     }
    42. }
    Like you, I could not see the output on the screen. It was in the output text file, though.
     
    AlanMattano likes this.
  21. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Ok! Now your code makes sense for me! I'm a bit confused trying to decode because I'm new to command line & arguments
    • test.txt = Input.txt , the command line?
    • test2.txt?
    • In your code you are giving the input after it runs the program so probably Arguments = "test"; is not used?
    Or test.txt = call.bat and test2.txt = Input.txt?
     
    Last edited: Apr 27, 2018
  22. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Um.. well, since I'm not overly familiar with things, let's see. :)

    arguments 'test' is only useful because of my comment about being lazy. This app runs, then creates a new process with the same .exe (that it is. lol). So, to avoid a loop, i did a conditional arguments branch.

    test.txt is like your input, but it's not read as the program arguments. That's what I was trying to say in my last post. If you look at the code, the program reads the text and writes it to the input of the other where it's read, as if it came from Console.ReadLine.
    So, I'm not sure how useful my example is for you, unfortunately, if that's not possible for you.

    Since I don't have a bat file, the closest comparison that I can draw is:
    test.txt = input and test2.txt = output.
    :)

    Do you need the bat file? It sounds logical to me that you could pass arguments to the 'cmd' process to setup your input/output, but as I said.. because I'm not that familiar with it, it's just a guess.
    If you don't really need it, and the .exe can read (redirected) input, then I think my example may be viable if you skip the .bat file.
     
  23. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    :rolleyes: OK @methos5k IT START AND RUN!
    STOP FORTRAN STOP! :eek: unity crash! I was not able to output and Unity crush probably because of
    process.WaitForExit();

    but I say Fortran running,
    was running from Unity and your C# code was able to pass the correct instructions!

    Since it crashes, there is no output.
    In your test.txt = my output I pass the line command to write save out.txt output and quit
    But Unity stops for some reason and so there is no output.
     
  24. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Oh wow, cool. And I just responded a moment after you. lol.

    Um, I'm not even 100% sure you need to wait for it to exit, if you find it a problem. Just let it run, and ignore that command.
    If you do want to know when it's done, for some reason, there is an event to which you can subscribe (.Exited, I think it's called from yesterday when I was looking around).
     
    AlanMattano likes this.
  25. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Console.ReadLine(); 
    Was freezing my Unity Editor.
    I try to save from Fortran and looks like the text2.txt output is interfering
    The text2.txt file is in Assets better if is in StreamingAssets
    When you save using Fortran "save a file", it saves it automatically in the project file.
    Not in Asset but in the main folder where is the project when you are using the editor.
    I will continue this weekend searching for that useful event
    Thank a lot @methos5k for the help.
    After testing 10 different methods your was the one!!
     
    Last edited: Apr 27, 2018
  26. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I thought you wanted it to go to an output.txt file?

    That's what that was for. If that's not the case, then it's useless to you. :)
     
  27. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Cool, just saw your edit. I hope you get it working perfectly. Sorry, the readline was because I wrote this without Unity. :)
     
  28. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    The Fortran has 2 outputs.
    One is text2.txt output as you mention and returns the result of each command line by line.
    and the other is via command line "SAVE out.txt": Is where is the result of the Fortran operation.
    These two outputs files are different both useful. ;) thx!!!


    THIS DO NOT WORK
    FULL LIST OF FAILS​
    Code (CSharp):
    1. // good
    2. using UnityEngine;
    3. using System;                           // Handles Exception
    4. using System.Diagnostics;               // Process.Start()
    5. using System.IO;                        // messageStream = process.StandardInput;
    6.  
    7. // do I need it?
    8. using System.ComponentModel;
    9. using System.Linq;
    10. using System.Text;
    11. using System.Reflection;
    12. using System.Configuration;
    13. using System.Threading;
    14. using System.Collections;
    15. using System.Collections.Generic;
    16.  
    17.  
    18. /* NOT WORKING
    19. using System.Data;
    20. using System.Drawing;
    21. using System.Windows.Forms;
    22. using System.Data.OleDb;
    23. using ZedGraph;
    24. using Microsoft.Office.Interop.Excel;
    25. */
    26.  
    27.  
    28. /****************************************************
    29. *
    30. *  2018 Alan Mattano
    31. *  SOARING STARS Lab
    32. *  DAD Run xFoil
    33. *    
    34. *      .
    35. *
    36. * **************************************************/
    37.  
    38.  
    39. public class Run_xFoil : MonoBehaviour
    40. {
    41.     public enum LaunchType { ViaExample, ViaExample2, OK_ViaCmd, Ok_Directlly, DirectPlusArgument,
    42.         DirectlyConsoleWindow,  CMD, EXEandCommands, EXEviaPython, RunBat, StratAndTalk, };
    43.  
    44.     [Space]
    45.     [Header("INPUT")]
    46.     [Tooltip("Select the desired method")]
    47.     public LaunchType launchType;
    48.     public bool launch_xFoil = false;
    49.  
    50.     [Space][Header("OUTPUT")][Tooltip("OUTPUT: Error Message.  0 = no errors")]
    51.     public string errorMessage = "No Message";
    52.     public bool xFoilLaunched = false;
    53.  
    54.     private Process process = null;
    55.     private StreamWriter messageStream;
    56.  
    57.     void MyProcess()
    58.     {
    59.         switch (launchType)
    60.         {
    61.             case LaunchType.Ok_Directlly:
    62.                 Launch_xFoil();
    63.                 break;
    64.             case LaunchType.DirectPlusArgument:
    65.                 LaunchArgument_xFoil();
    66.                 break;
    67.             case LaunchType.OK_ViaCmd:
    68.                 LaunchViaConsole_xFoil();
    69.                 break;
    70.             case LaunchType.ViaExample:
    71.                 LaunchViaExample_xFoil();
    72.                 break;
    73.             case LaunchType.ViaExample2:
    74.                 LaunchViaCorExample_xFoil();
    75.                 break;
    76.             case LaunchType.DirectlyConsoleWindow:
    77.                 LaunchViaDirectlyConsoleWindow_xFoil();
    78.                 break;
    79.             case LaunchType.CMD:
    80.                 LaunchViaCMD_xFoil();
    81.                 break;
    82.             case LaunchType.EXEandCommands:
    83.                 LaunchViaEXEandCommands();
    84.                 break;
    85.             case LaunchType.EXEviaPython:
    86.                 LaunchViaEXEviaPython();
    87.                 break;
    88.             case LaunchType.RunBat:
    89.                 LaunchViaBat();
    90.                 break;
    91.             case LaunchType.StratAndTalk:
    92.                 PassInputAfterStart();
    93.                 break;
    94.         }
    95.     }
    96.  
    97.  
    98.  
    99.     void Update()
    100.     {
    101.         if (launch_xFoil)
    102.         {
    103.             launch_xFoil = false;
    104.  
    105.             MyProcess();
    106.         }
    107.     }
    108.  
    109.  
    110.  
    111.     GUIStyle guiStyle = new GUIStyle();
    112.     void OnGUI()
    113.     {
    114.         guiStyle.fontSize = 22;
    115.         guiStyle.normal.textColor = Color.white;
    116.         if (GUILayout.Button("Press Me"))
    117.         {
    118.  
    119.             MyProcess();
    120.         }
    121.     }
    122.  
    123.  
    124.     private void Launch_xFoil()
    125.     {
    126.         UnityEngine.Debug.Log("RUN...xFoil Directlly\n");
    127.  
    128.         xFoilLaunched = true;
    129.  
    130.         Process.Start(Application.dataPath + @"/StreamingAssets/xfoil/xfoil.exe");
    131.  
    132.         xFoilLaunched = false;
    133.     }
    134.  
    135.  
    136.  
    137.     void LaunchArgument_xFoil()
    138.     {
    139.         UnityEngine.Debug.Log("RUN...xFoil Directlly\n");
    140.  
    141.         xFoilLaunched = true;
    142.  
    143.         Process.Start(Application.dataPath + "/StreamingAssets/xfoil/xfoil.exe",
    144.             @"e387.dat");
    145.  
    146.         xFoilLaunched = false;
    147.     }
    148.  
    149.  
    150.  
    151.     void LaunchViaCMD_xFoil()
    152.     {
    153.         UnityEngine.Debug.Log("RUN...xFoil using CMD\n");
    154.  
    155.         Process process = new Process();
    156.         process.StartInfo.FileName = "cmd.exe";// "cmd.exe"   C:\\Windows\\system32\\cmd.exe
    157.         process.StartInfo.CreateNoWindow = true;
    158.         process.StartInfo.RedirectStandardInput = true;
    159.         process.StartInfo.RedirectStandardOutput = true;
    160.         process.StartInfo.UseShellExecute = false;
    161.         process.Start();
    162.         process.StandardInput.WriteLine("ipconfig");
    163.         process.StandardInput.Flush();
    164.         process.StandardInput.Close();
    165.         process.WaitForExit();
    166.         Console.WriteLine(process.StandardOutput.ReadToEnd());
    167.         //UnityEngine.Debug.Log(process.StandardOutput.ReadToEnd());
    168.         Console.ReadKey();
    169.         //UnityEngine.Debug.Log(Console.ReadKey());
    170.     }
    171.  
    172.  
    173.  
    174.     private void LaunchViaDirectlyConsoleWindow_xFoil()
    175.     {
    176.         UnityEngine.Debug.Log("RUN...xFoil using Directly Console Window\n ALAN READ THE LINK!!!! AND FINISH THIS");
    177.         // from: https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.110).aspx
    178.  
    179.         Process compiler = new Process();
    180.         compiler.StartInfo.FileName = Application.dataPath + "\\StreamingAssets\\xfoil\\xfoil.exe";
    181.         //"/r:System.dll /out:sample.exe stdstr.cs";
    182.         compiler.StartInfo.Arguments = "/r:System.dll fss_Input05.txt";
    183.         compiler.StartInfo.UseShellExecute = false;
    184.         compiler.StartInfo.RedirectStandardOutput = true;
    185.         compiler.Start();
    186.  
    187.         Console.WriteLine(compiler.StandardOutput.ReadToEnd());
    188.  
    189.         compiler.WaitForExit();
    190.     }
    191.  
    192.  
    193.  
    194.     private void LaunchViaExample_xFoil()
    195.     {
    196.         UnityEngine.Debug.Log("RUN...xFoil using example\n");
    197.  
    198.         try
    199.         {
    200.             string path_xFoilLocation = Application.dataPath + "\\StreamingAssets\\xfoil\\";
    201.  
    202.  
    203.             //generate Forest.bat.///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    204.             FileStream callfile = new FileStream(path_xFoilLocation + "Forest.bat", FileMode.OpenOrCreate, FileAccess.ReadWrite);
    205.             StreamWriter callw = new StreamWriter(callfile);
    206.             //callw.Write("xfoil.exe <command.dat");
    207.             callw.Write("xfoil.exe <fss_Input05.txt >out/xfoil.log.txt");
    208.             callw.Close();
    209.             callfile.Close();
    210.  
    211.             //RUN XFOIL call xfoil.////////////////////////////////////////////
    212.             Process.Start(Application.dataPath + "/StreamingAssets/xfoil/Forest.bat");
    213.             /*
    214.             Process p = new Process();
    215.             p.StartInfo.FileName = path_xFoilLocation + "Forest.bat";
    216.             p.Start();*/
    217.         }
    218.         catch (System.Exception errorMessage)
    219.         {
    220.             UnityEngine.Debug.Log("ERROR: xFoil Launch Via Example" +
    221.                 "\n Catch Code Exception: " + errorMessage );
    222.         }
    223.     }
    224.  
    225.  
    226.  
    227.     private void LaunchViaCorExample_xFoil()
    228.     {
    229.         UnityEngine.Debug.Log("RUN...xFoil using COR call.bat example\n");
    230.         // form: https://github.com/chfenger/xfoil_call/blob/master/Xfoil_call/main_form.cs
    231.  
    232.  
    233.         try
    234.         {
    235.            
    236.             string path = Application.dataPath + "\\StreamingAssets\\xfoil\\";
    237.  
    238.             //delete polar.txt///////////////////////////////////////////////
    239.             try
    240.             {
    241.                 if (File.Exists(path + "out\\xfoil.polar.txt"))
    242.                 {
    243.                     File.Delete(path + "out\\xfoil.polar.txt");
    244.                 }
    245.             }
    246.             catch (IOException iox)
    247.             {
    248.                 UnityEngine.Debug.LogError("ERROR: There was no polar file to delete or unable to delete it" +
    249.                 "\n Catch Code Exception: " + iox.Message);
    250.             }
    251.  
    252.             //generate call.bat///////////////////////////////////////////////
    253.             FileStream callfile = new FileStream(path + "call.bat", FileMode.OpenOrCreate, FileAccess.ReadWrite);
    254.             StreamWriter callw = new StreamWriter(callfile);
    255.             callw.Write(@"xfoil.exe<fss_Input05.txt");
    256.             callw.Close();
    257.             callfile.Close();
    258.  
    259.            
    260.             //call xFoil//////////////////////////////////////////////////////
    261.             //RUN CALL.BAT
    262.             Process p = new Process();
    263.             p.StartInfo.FileName = path + "call.bat";
    264.             p.Start();
    265.             p.WaitForExit(5000);
    266.  
    267.         }
    268.         catch (System.Exception errorMessage)
    269.         {
    270.             UnityEngine.Debug.Log("ERROR: xFoil Launch Via Example" +
    271.                 "\n Catch Code Exception: " + errorMessage);
    272.         }
    273.     }
    274.  
    275.  
    276.  
    277.     private void LaunchViaConsole_xFoil ()
    278.     {
    279.         UnityEngine.Debug.Log("RUN...xFoil via CMD\n");
    280.  
    281.         xFoilLaunched = true;
    282.  
    283.         Process myProcess = new Process();
    284.  
    285.         try
    286.         {
    287.             //myProcess.StartInfo.UseShellExecute = false;
    288.             // You can start any process, HelloWorld is a do-nothing example.
    289.             myProcess.StartInfo.FileName = Application.dataPath + "\\StreamingAssets\\xfoil\\xfoil.exe";//"U:\\xfoil.exe";
    290.             //myProcess.StartInfo.Arguments= "xfoil.Input01.txt /c <xfoil.Input01.txt";
    291.             string arg1 = @"/c";  // "/c"
    292.             //string arg2 = @"quit";
    293.             myProcess.StartInfo.Arguments = arg1;// + arg2;
    294.             //myProcess.StartInfo.CreateNoWindow = true;
    295.             myProcess.Start();
    296.  
    297.             /*
    298.  
    299.             process = new Process();
    300.             // hide the window
    301.             process.StartInfo.WindowStyle = ProcessWindowStyle.Normal; // change from hiden
    302.             process.StartInfo.CreateNoWindow = true;
    303.             process.StartInfo.RedirectStandardInput = true;
    304.             process.StartInfo.RedirectStandardOutput = true;
    305.            
    306.             process.StartInfo.UseShellExecute = false;
    307.             process.EnableRaisingEvents = true;
    308.  
    309.             //process.StartInfo.FileName = "C:\\Windows\\system32\\cmd.exe";                                  //  C:\\Win...\\cmd.exe
    310.             process.StartInfo.FileName = "U:\\Nota.txt";
    311.             //string applicationPathName = Application.dataPath + "\\StreamingAssets\\xfoil\\xfoil.exe";         //  U:\\READ.txt
    312.             string path = "";         //  U:\\READ.txt
    313.             process.StartInfo.Arguments = "";// "/c" + path;//  U:\\READ.txt
    314.  
    315.             process.StartInfo.RedirectStandardError = true;
    316.             process.OutputDataReceived += new DataReceivedEventHandler(DataReceived);
    317.             process.ErrorDataReceived += new DataReceivedEventHandler(ErrorReceived);
    318.  
    319.             process.Start();
    320.  
    321.             //process.BeginOutputReadLine();
    322.             //messageStream = process.StandardInput;
    323.  
    324.             process.WaitForExit();
    325.             int ExitCode = process.ExitCode;
    326.             UnityEngine.Debug.Log( "Exit Code " + ExitCode + "\n The console is exit!");
    327.             if (ExitCode == 1) errorMessage = "ERROR: The file was not found. Look the path or name";
    328.             if (ExitCode == 0) errorMessage = "OK: The file was found and close";
    329.             */
    330.  
    331.             UnityEngine.Debug.Log("Successfully launched app \n");
    332.         }
    333.         catch (Exception e)
    334.         {
    335.             UnityEngine.Debug.Log(e);
    336.             errorMessage = "ERROR: There was a problem running script RunCmd, run(). Somthing is missing! \n" +
    337.                 " Cmd or xFoil Path | error info :  "  + e;
    338.         }
    339.  
    340.         xFoilLaunched = false;
    341.         //Process.Start(Application.dataPath + "/StreamingAssets/xfoil/xfoil.exe");
    342.     }
    343.  
    344.  
    345.  
    346.     private void LaunchViaEXEandCommands()
    347.     {
    348.         UnityEngine.Debug.Log("RUN...xFoil using EXE and Commands\n");
    349.         // from: https://stackoverflow.com/questions/9334100/process-to-call-fortran-executable-from-c-sharp
    350.  
    351.         Process exeProcess = new Process();
    352.         exeProcess.StartInfo.FileName = "cmd.exe";// "cmd.exe"   C:\\Windows\\system32\\cmd.exe
    353.         exeProcess.StartInfo.CreateNoWindow = true;
    354.         exeProcess.StartInfo.RedirectStandardInput = true;
    355.         exeProcess.StartInfo.RedirectStandardOutput = true;
    356.         exeProcess.StartInfo.UseShellExecute = false;
    357.         exeProcess.Start();
    358.         exeProcess.StandardInput.WriteLine("ipconfig");
    359.         exeProcess.StandardInput.Flush();
    360.         exeProcess.StandardInput.Close();
    361.         exeProcess.WaitForExit();
    362.         Console.WriteLine(exeProcess.StandardOutput.ReadToEnd());
    363.         //UnityEngine.Debug.Log(process.StandardOutput.ReadToEnd());
    364.         Console.ReadKey();
    365.         //UnityEngine.Debug.Log(Console.ReadKey());
    366.     }
    367.  
    368.  
    369.  
    370.     private void LaunchViaBat()
    371.     {
    372.         UnityEngine.Debug.Log("RUN...xFoil using EXE and Commands\n");
    373.         // from: http://www.dreamincode.net/forums/topic/314493-process-handling/
    374.         /*
    375.  
    376.         SHELLEXECUTEINFO ShExecInfo = { 0 };
    377.  
    378.         ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    379.  
    380.         ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    381.  
    382.         ShExecInfo.hwnd = NULL;
    383.  
    384.         ShExecInfo.lpVerb = NULL;
    385.  
    386.         ShExecInfo.lpFile = ("C:/Users/Angelos/Documents/CExperiments/BSplines/run.bat");
    387.    
    388.         ShExecInfo.lpParameters = ("");
    389.    
    390.         ShExecInfo.lpDirectory = NULL;
    391.      
    392.         ShExecInfo.nShow = SW_SHOW;
    393.        
    394.         ShExecInfo.hInstApp = NULL;
    395.        
    396.         ShellExecuteEx(&ShExecInfo);
    397.        
    398.         WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
    399. */
    400.     }
    401.  
    402.  
    403.  
    404.     private void PassInputAfterStart()
    405.     {
    406.         UnityEngine.Debug.Log("RUN...xFoil and pass inputs after\n");
    407.         //from: https://forum.unity.com/threads/run-fortran-bat-run.528317/#post-3476671
    408.  
    409.         string path = Application.dataPath + "\\StreamingAssets\\xfoil\\";
    410.  
    411.         //delete polar.txt///////////////////////////////////////////////
    412.         try
    413.         {
    414.             if (File.Exists(path + "out.txt"))
    415.             {
    416.                 File.Delete(path + "out.txt");
    417.             }
    418.         }
    419.         catch (IOException iox)
    420.         {
    421.             UnityEngine.Debug.LogError("ERROR: There was no polar file to delete or unable to delete it" +
    422.             "\n Catch Code Exception: " + iox.Message);
    423.         }
    424.  
    425.         Process process = new Process();
    426.         process.StartInfo.RedirectStandardInput = true;
    427.         process.StartInfo.RedirectStandardOutput = true;
    428.         process.StartInfo.UseShellExecute = false;
    429.         process.StartInfo.FileName = Application.dataPath + @"/StreamingAssets/xfoil/xfoil.exe";
    430.         process.StartInfo.Arguments = "";
    431.  
    432.         process.Start();
    433.         StreamWriter sw = process.StandardInput;
    434.         StreamReader sr = process.StandardOutput;
    435.         sw.Write(File.ReadAllText(path + "test.txt"));
    436.         UnityEngine.Debug.LogWarning("text.txt");
    437.  
    438.       //string s = sr.ReadToEnd();
    439.       //using (StreamWriter sw2 = new StreamWriter(path + "test2.txt")) sw2.Write(s);
    440.  
    441.         UnityEngine.Debug.LogWarning("test2.txt");
    442.         process.WaitForExit();
    443.         UnityEngine.Debug.LogWarning("Finish THERE WILL BE 2 files, one for editor, one for runtime");
    444.         //Console.ReadLine();
    445.     }
    446.  
    447.  
    448.     void LaunchViaEXEviaPython()
    449.     {
    450.         UnityEngine.Debug.LogWarning("RUN...xFoil using Python EXE IS NOT IMPLEMENTET \n Alan need to finish");
    451.     }
    452.  
    453.  
    454.     void DataReceived(object sender, DataReceivedEventArgs eventArgs)
    455.     {
    456.         // Handle it
    457.     }
    458.  
    459.     void ErrorReceived(object sender, DataReceivedEventArgs eventArgs)
    460.     {
    461.         UnityEngine.Debug.LogError(eventArgs.Data);
    462.     }
    463.  
    464.  
    465.  
    466.     void OnApplicationQuit()
    467.     {
    468.         if (process != null && !process.HasExited)
    469.         {
    470.             if (this.enabled)
    471.             {
    472.                 // Do stuff.
    473.                 // Close open external app
    474.                 process.Kill();
    475.             }
    476.         }
    477.     }
    478. }
    479.  
     
    Last edited: Nov 26, 2018
  29. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ah okay, cool. :) If they're both useful, then keep 'em. heh.
     
  30. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Thanks, @methos5k and @Kurt-Dekker
    the final result is working. Now I will try to understand how to put all that in a big try{
     
  31. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    THIS WAS WORKING

    Code (CSharp):
    1. void OnEnable()
    2.     {
    3.         MakeInputFile(FssInput.txt); // Creates Xfoil instructions
    4.  
    5.         //path = Application.dataPath + "\\StreamingAssets\\xfoil\\";
    6.         // or
    7.         path = xFoilPath;
    8.  
    9.         // Display a message to the user that xFoil is running
    10.         cancelWindow.SetActive(true);
    11.  
    12.         #region RUN XFOIL
    13.         try
    14.         {
    15.             Process process = new Process();
    16.             process.StartInfo.RedirectStandardInput = true;
    17.             process.StartInfo.RedirectStandardOutput = true;
    18.             process.StartInfo.UseShellExecute = false;
    19.  
    20.             // string pathToXfoil = Application.dataPath + @"/StreamingAssets/xfoil/xfoil.exe";
    21.             // or
    22.             string pathToXfoil = xFoilPath + "/xfoil.exe";
    23.          
    24.             process.StartInfo.FileName = pathToXfoil;
    25.             process.StartInfo.Arguments = "";
    26.             process.Start();
    27.             StreamWriter sw = process.StandardInput;
    28.             StreamReader sr = process.StandardOutput;
    29.             sw.Write(File.ReadAllText(path + @"toXfoil/FssInput.txt"));
    30.             string s = sr.ReadToEnd();
    31.             using (StreamWriter sw2 = new StreamWriter(path + @"fromXfoil/log.txt")) sw2.Write(s);
    32.             process.WaitForExit(50000);// 50 sec
    33.         }
    34.         catch (Exception error)
    35.         {
    36.             // XFOIL WAS UNABLE TO START
    37.         }
    38.         #endregion
    39.  
    40.         // xFoil Finish running! We set this game object to disable
    41.         this.enabled = false;
    42.     }
    pane
    oper
    VPAR
    N 9.0
    v2e6
    iter512
    pacc
    pathToXfoil/xfoil/fromXfoil/polar.txt
    aseq -1 6 0.2
    quit
     
    Last edited: Nov 26, 2018