Search code examples
batch-fileprocessing

getting right start directory with processing


I'm opening bat file using processing executable file. all it does is start Exe2.exe and then looks for files until they are created. that bat is located in a specific folder which also has Exe2.exe. When I open it by double clicking, it works as intended but whenever I use

try {
      p1 = r.exec("cmd /c start " + Path + "/open.bat");
    }
      catch(Exception c) {
    }

it opens bat file and I get error "Windows cannot find Exe2.exe" and in console this is what it runs C:\Users\syste\Downloads\processing-3.5.4> start Exe2.exe

the starting path is different from where open.bat file is. It's start from where processing is saved. If there's a way to have it start from correct folder or somehow pass the path with processing. I don't want to hardcode path into it manually since i want it to run on different computers

open.bat content:


start Exe2.exe

cls

@ECHO OFF

SET LookForFile="answer.txt"

:CheckForFile
IF EXIST %LookForFile% GOTO FoundIt

GOTO CheckForFile


:FoundIt
echo the number is:
more answer.txt

del "answer.txt"

GOTO CheckForFile

simple sketch to reproduce:

String Path;
Runtime r = Runtime.getRuntime();
Process p1;

void setup(){
   Path = sketchPath()+"/lib";
   try {
    p1 = r.exec("cmd /c start " + Path + "/open.bat");
  }
  catch(Exception c) {
  }

}

There's a folder called "lib" inside sketches folder which has open.bat and Exe2.exe files


Solution

  • Based on your comment, using a file structure like this:

    
    C:.
    │   ExeLauncherSketch.pde
    │
    └───lib
            exe2.cmd
            open.bat
    
    

    Where exe2.cmd is a placeholder for exe2.exe:

    @echo "exe2 placeholder script"
    timeout 10
    

    You could do something like:

    void setup() {
      String path = sketchPath("lib");
      
      try {
        exec(path + "/open.bat", path);
      }catch(Exception ex) {
        ex.printStackTrace();
      }
      
      exit();
    }
    

    This is a workaround where you pass the path to the sketch from the processing sketch to open.bat, you can read/use as the 1st command line argument (%1)

    which would make open.bat:

    @ECHO "path received "
    start %1/Exe2.cmd
    
    cls
    
    @ECHO OFF
    
    SET LookForFile="%1/answer.txt"
    
    :CheckForFile
    IF EXIST %LookForFile% GOTO FoundIt
    
    GOTO CheckForFile
    
    
    :FoundIt
    echo the number is:
    more answer.txt
    
    del "%1/answer.txt"
    
    GOTO CheckForFile
    

    Update Magoo's answer is what I was looking for (but couldn't remember): a way to get the path where the file is located.

    This would simplify the sketch to:

    void setup() {
      try {
        exec(sketchPath("lib/open.bat"));
      }catch(Exception ex) {
        ex.printStackTrace();
      }
      
      exit();
    }
    

    and swapping %1 with %~dp0:

    
    @ECHO "path received "
    start %~dp0Exe2.cmd
    
    cls
    
    @ECHO OFF
    
    SET LookForFile="%~dp0answer.txt"
    
    :CheckForFile
    IF EXIST %LookForFile% GOTO FoundIt
    
    GOTO CheckForFile
    
    
    :FoundIt
    echo the number is:
    more answer.txt
    
    del "%~dp0/answer.txt"
    
    GOTO CheckForFile
    
    

    (Remember there's a difference between start and call (more info here))

    Update The lib folder is a special folder. When you export an application, the Processing .jar files usually live there which means your .bat/.exe files from the original sketch might not make it to the exported application.windows64 folder. You will need to manually copy the .bat/.exe files to the lib folder after the export process completes. May advice is to rename the lib folder to data in the sketch (and update the path to open.bat in the sketch (e.g. exec(sketchPath("data/open.bat")); (or maybe even exec(dataPath("open.bat")); 🤞 ): this way you'd have a cleaner structure with .bat/.exe files on a folder and .jar files in another)