How to launch and communicate with a window-less and console-less process from a cocoa app? - objective-c

I am working with the QuickTime API and need to perform a few lengthy (as in hours) operations in the background. Unfortunately, it is not multi-thread friendly, so I am falling back to perform the tasks in a separate process, so all QuickTime related calls can happen in its main thread.
After launching it, I need a way of getting feedback on its progress, since the operations can take very long.
I am unsure of how to do this, specifically:
Should the separate process be compiled as another cocoa app or a command line tool?
How to launch it from the main cocoa app?
How to periodically get an object from it to get status information?
How to determine when it finished?
How to avoid showing a window/console when called?
How to have it part of the .app bundle so that it does not appear as a separate executable to the user?
These are really 6+ questions, but they are very related and very specific, and I think anyone needing to launch external processes (instead of spawning worker threads) can benefit from their answers. Generic code examples would be very helpful.

If it is possible, then implement the functionality in a command line tool, or another form of GUI-less application. For Cocoa applications it is possible to prevent them appearing on the Dock or in the Force Quit dialog, however a command line tool is a single binary file which does that anyway, so that would probably be a better way.
In terms of launching the tool, NSTask & NSPipe are your friends in this endeavour. The tool can definitely be kept inside your main Application's bundle, inside the Resources directory or some such, and then launched when needed. You can use the pipe to communicate back and forth.
I don't have any example code to hand, and its been a long while since I've had occasion to use either of these classes so the information I can give is limited, but it should be enough to point you in the right direction.

Related

How can I use a UWP Class Library for scripting?

I have a UWP Class Library project (written in C#) with some useful utility classes and functions. I want to create a script that uses these classes and functions and runs a few times a day automatically. What is the best way to achieve this?
Should I create an app? If so how can I make it run a few times a day?
Should I create a classic console exe program and run it using a script? If yes, can console apps use UWP class libraries?
Should I create a Windows Runtime Component with background task?
Or some other solution?
Assuming that you're definition of "scripting" can be stretched to mean "run an app" there's lots you can do. If you want something that will be seen as a more traditional script then the best you can do is compile the code in a standard .Net class library (not a UWP one) and then call it from a PowerShell script. If you can run apps then there are a few options and the most appropriate will probably depend on the device they're running on, how often you want them to run, and what they actually do.
As you're talking about a UWP app we should allow for it running on different "device families". The easiest way to run on different devices (desktop & phone, etc.) is to have a periodic background task. At time intervals defined by you it will try and run. Subject to connectivity, power, etc.
Because you said a console app was an option then you're probably really only interested in a desktop/PC environment. That's where there's the most options.
Firstly, if your code uses UWP/Win10 specific APIs then compiling into a console app probably isn't possible without changing the code. I do many things like you describe in the question and use console apps for this as I find them the simplest to work with.
If you're going to change code, consider moving to using Portable Class Libraries as you'll then be able to link to that code from many different types of app--including traditional desktop and UWP apps.
I'd avoid creating a runtime component unless you really need to as there are lots of potential gotchas.
You can run any app from the Task Scheduler but launching UWP apps is tricky.
You can launch a regular app or script by setting the action of the task to be the exe. (or the exe and passing the script file as a parameter.)
Apps from the store don't have an EXE you can just launch so you need to do a bit more. They can only be launched by the Windows Shell. But, fortunately, there's a way to do this. Have your task start explorer.exe (You'll find it in C:\Windows) and then add the argument shell:AppsFolder\[app-PFN]!App.
Where [app-PFN] is the Product Family Name of the app. You can find the values of all the installed apps on your machine by looking at "C:\Users[username]\AppData\Local\Packages\"
So, you can use this to launch the store app.
shell:AppsFolder\Microsoft.WindowsStore_8wekyb3d8bbwe!App

Cocoa: Launch Agent with Objects?

TLDR; is it possible to send/receive objects between an app and a 3rd party launch agent?
I'm writing an extension for an existing app (A). It's packaged and I do not have access to the source - but I can write simple plug-ins that can do some basic Cocoa and host a UI. Read: very limited options.
Ideally, what I'd like to do is have the plugin in app (A) message an external service (B) [sending objects], have (B) do some heavy lifting, then respond back to (A) so the UI can update.
I've been reading up on Launch Agents and they look promising, but I noted the examples all use basic types - no objects. I found one post discussing how to use Distributed Objects, but that's about it. It looks great, but what worries me is I'm not seeing a whole lot of current information on DO and I can't tell if it's something Apple will continue to support going forward.
Does anyone have any suggestions on options for a scenario like this? Maybe I'm just approaching this the wrong way?
Another option is I just completely split this out - write a separate full app and have (A) open it up with AppleScript. The UX wouldn't be as nice, but it would also work.
Thank you,
Eric
NOTE: I can't use NSTask. Or at least I've failed utterly to get it to work in this specific situation. Due to issues with app (A) it breaks when some of the methods run within the process. If I could somehow spawn NSTask so it was executing completely outside of (A) that might be an option. Which is actually what prompted me to look at Launch Agents...

VB 2013 Embedded resources

I just wanted to get clarification on the approach I'm taking with my program. I'm making a program with custom interface for achiving folders. I would like to use 7zip if possible. In the past I have written batch scripts to that use 7zip command line for archiving. If I want to use my VB tool on a system that doesn't have this available, I would like for this to be embedded in my app.
My question is that know how to embed an exe in a VB app, but does this make it immediately available for use in the program no matter where I use it? Or it make the exe available to be deployed somewhere on the station, then I would have to call it from the disk and then possibly delete it when I'm done?
I've done some searching online for similar applications, but am still unsure of how to use embedded files. I'm not looking for example code. Just clarification on whether I can immediately call the exe from within my app, or I embedding just means I can place that file somewhere on the station that I move my app to and then use it? Clarification on this would be most welcome. Thanks!!!

Is calling a Process.Start on a Web App thread-safe?

Today I've been working with wkhtmltopdf.exe in a web app and I was wondering whether I should use a lock (or the singleton pattern) in order to call Process.Start in a thread-safe manner.
My concern is that multiple users will do GETs simultaneously on the page that calls the exe file mentioned above. It's my understanding that each Request is created on its own thread, does this mean that calling an exe file (with Process.Start) is thread-safe in a web application?
Process.Start has nothing to do with thread safety. It is a thread safe call - you can call it as many times you want from as many threads you want. The problem that comes with this is that you are depending on an external process to do the job. Spawning multiple processes in an intensively used web application is not a good idea as you will be consuming more and more resources. So while this could be fine if your site doesn't have a big load, it is not recommended if you expect to start scaling.
Yeah, I know that converting HTML to PDF in a reliable and performant way which doesn't involve spawning processes and be happy with the final result costs money. But scalability of a web application usually comes at a cost.

Cocoa Objective-C main loop

I'm building an application in C, which is a client/server sharing app. This application is command line based which uses TCP sockets, libcurl and some fork(). It should run in an infinite loop without any input.
My professor at the university said that we have to implement a GUI, and because I'm on Mac, I learned Object-C and I have done it in cocoa.
Now I'm asking myself if could be possible to merge the two applications, the cocoa GUI and the real application written in C. Of course I need the two "apps" to run in parallel.
Can I add it to my cocoa app? Where I have to put the code in order to have it always running? Not in awakeFromNib right?
I know that the question is kind of vague.
Thanks.
You could run the command line app as an NSTask and write the appropriate code so that they can commnicate via pipes. This way they will run asynchronously.
Alternatively you could definitely 'merge' them as c code will run just fine in an ObjC progam. The infinite loop could live in a different thread. Although this solution may require more re-writing than the previous solution.