- Home /
System.Diagnostics.Process on iOs and Android
Hi! I am just curios and wanted to ask if anyone knows, Would the System.Diagnostic.Process in C# for calling out process (e.g. build ffmpeg) work on iOs and Android Platform? If not are there any work arounds?
Answer by JeremyF · 2 days ago
This is old but I found my way here so to provide an answer: The short answer is no. IL2CPP doesn't support the Process class and you must use IL2CPP to generate 64 bit build which you must do to upload your AAB to the Play store. If you were using mono backend, it would work. So for Android you need to use java.lang.ProcessBuilder . Also, as of API level 29+, you can no longer execute programs in your app's files directory (context.getFilesDir). The way I found to get it to work was to put your executable in the libs folder under Plugins/Android. The folder structure should look like this:
- Assets/Plugins/Android/libs
- arm64-v8a
- libMYPROGRAM.so
- armeabi-v7a
- libMYPROGRAM.so
Your program must contain the prefix lib and the extension .so and must be nested under subdirectories for each of the architectures you want to generate a build for. Then when your app is installed, the programs you had in the libs folder should be added with it and they'll be in the nativeLibraryDir. Firing up a process on android from C# might look like this:
var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
var context = activity.Call<AndroidJavaObject>("getApplicationContext");
// If you wanted it, this is how you get your filesDir
string filesDir = context.Call<AndroidJavaObject>("getFilesDir").Call<string>("getAbsolutePath");
// This is the one you really want to execute your program from
string nativeLibraryDir = context.Call<AndroidJavaObject>("getApplicationInfo").Get<string>("nativeLibraryDir");
var pb = new AndroidJavaObject("java.lang.ProcessBuilder", new string[] { path });
var nativeDir = new AndroidJavaObject("java.io.File", nativeLibraryDir);
pb.Call<AndroidJavaObject>("directory", nativeDir);
var p = pb.Call<AndroidJavaObject>("start");
var ostream = p.Call<AndroidJavaObject>("getOutputStream");
var istream = p.Call<AndroidJavaObject>("getInputStream");
var isr = new AndroidJavaObject("java.io.InputStreamReader", istream);
var br = new AndroidJavaObject("java.io.BufferedReader", isr, 16384);
// Write line to program
var javaString = new AndroidJavaObject("java.lang.String", "Send this to engine");
ostream.Call("write", javaString.Call<AndroidJavaObject>("getBytes"));
ostream.Call("flush");
// Read line from program - you could try bufferedReader.Call<string>("readLine") instead
// But I'm not sure it works. I can't remember but I think I did it this way for a reason
var readLine = bufferedReader.Call<AndroidJavaObject>("readLine");
// Make sure line's not null and its pointer is not null. I think if readLine returns
// a null string, Unity will still return a non-null AndroidJavaObject representing it,
// but its pointer will be zero. So check for that.
string readLineString = null;
if (readLine != null && readLine.GetRawObject().ToInt32() != 0)
{
readLineString = AndroidJNI.GetStringChars(readLine .GetRawObject());
}
I don't know about IOS but I think it's the same way. I think I read somewhere you need an IL2CPP build to upload to store. Not 100% on that. I began looking into what the IOS process class was, but no longer having a Mac VM to build it, I couldn't test it anyway, so I didn't look that deep into it. From what I found the class you may want is NSTask. I think that's what you'd use to run an external process. Also not 100% sure on that.
Your answer
Follow this Question
Related Questions
How to display a video behind gui on mobile 2 Answers
XR Descriptor not found 1 Answer
Scriptable object doesn't load in the build of the project 1 Answer
Button as a child of a button 0 Answers
Disable/enable local notifications on Android and iOS 0 Answers