Best way to achieve Main application to console application and back.

I have a Xamarin.mac application that I would like to trigger another application with command parameters (Console App), that application would be running in the background without UI. That application would then return its output to the original calling application. Reading around I do not see a great way of doing this so far. Any suggestions would be appreciated.

Also, the console application I was considering embedding as a resource of the main application, would this cause issues?

Answers

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai
    edited January 2016

    I believe you need the NSTask API:

    https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTask_Class/

    If you need to communicate to the process beyond stdin/stdout/stderr and arguments you may want to use the NSPort APIs

    https://developer.xamarin.com/samples/mac/NSPortExample/

    In general, you can bundle then into your application with the bundle build actions, or if you want them in a custom location you'll need something like

    https://developer.xamarin.com/samples/mac/UseMSBuildToCopyFilesToBundleExample/

    You need to make sure to code sign the sub-application if you want your bundle code signed.

  • That looks like what I need, so the StdOut from the task would be anything from the console.write line of the launched application?

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    I believe so. Never used that API before myself though.

    Should be easy to test. :)

  • I'll give that a shot. If I were to create a standard OSX application in Xamarin Studio, not a .Net Console app, is there a way to specify command args, I am trying to keep everything natively compiled.

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    I believe you are hitting this:

    https://bugzilla.xamarin.com/show_bug.cgi?id=17757 and or https://bugzilla.xamarin.com/show_bug.cgi?id=11941

    There aren't really any good work arounds, beyond hard coding some hack like this:

     #if DEBUG
            args = new [] {"-myKey", "Foo"};
     #endif
    
  • I am able to execute the application I need, however the output is always empty, I am using Console.Writeline, any suggestions?

  • AaronCoppock.0358AaronCoppock.0358 USMember
    edited February 2016

    Also appears that Task is exiting before the launched application is done running, I tested this by having the launched application throw an alert window as a modal, the alert shows, however the task ends before the alert is closed. I am using the WaitUntilExit(); Any suggestions would be appreciated. Below is my code

                NSPipe pipeOut = new NSPipe();
                NSPipe pipeError = new NSPipe();
    
                NSTask execute =  new NSTask();
                execute.LaunchPath = "/usr/bin/open";
                execute.Arguments = new []{executerPath, "--args", request};
                execute.StandardOutput = pipeOut;
                execute.StandardError = pipeError;
                execute.Launch();
                execute.WaitUntilExit();
    
                executerError = pipeError.ReadHandle.ReadDataToEndOfFile().ToString();
                executerResult = pipeOut.ReadHandle.ReadDataToEndOfFile().ToString();
    
  • Updated the launching of the task and have it now waiting for the close of the tasked application, I still however am not receiving output

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    Hmm. I'm having no trouble with my example:

        bash-3.2$ cat 42.cs 
        public static class EntryPoint
        {
            public static int Main ()
            {
                System.Console.WriteLine ("42");
                return 42;
            }
        }
        bash-3.2$ mcs 42.cs 
        bash-3.2$ mono 42.exe 
        42
    
    
        public override void DidFinishLaunching(NSNotification notification)
        {
    
            var pipeOut = new NSPipe ();
    
            var t =  new NSTask();
            t.LaunchPath = "/usr/local/bin/mono";
            t.Arguments = new[] { "/Users/donblas/tmp/42.exe" };
            t.StandardOutput = pipeOut;
    
            t.Launch ();
            t.WaitUntilExit ();
    
            string r = pipeOut.ReadHandle.ReadDataToEndOfFile ().ToString ();
            System.Console.WriteLine(r);
        }
               // Output - 42
    
  • AaronCoppock.0358AaronCoppock.0358 USMember
    edited February 2016

    Strange, when I attempt this in my Main.cs of the application, I am getting this error, "MainClass.Main(string[]) has the wrong signature to be an entry point

    public static class MainClass
    {
    public static string Main(string[] args)
    {

    }
    

    }

  • Nevermind, had a brain fart

Sign In or Register to comment.