Is there a way to allow multiple instances of an application on macOS? - process

Is there a way to allow multiple instances of an application on macOS?
My app requires the main process and a helper process. On launch, it uses NSTask to launch another copy of itself with a command line parameter to become the helper process.
If the main App crashes, and the helper app is still running, it's impossible for the user to launch the main app again because macOS only allows one instance to run at a time.
Is there any way around this? Either to allow multiple instances in general or to make Finder think the helper process isn't the same as the original process?

Related

How should I design a portable (one executable) WinForm GUI app and Windows Service?

I want to develop an application with VB.NET 4.7.2 Framework, using WinForms. The application must run like a service, that is, ran at Windows startup (after boot, before login). It's intended to run only on a local enviroment, and play some sound files while the local user hasn't logon yet.
My first aproach to this problem was developing a WinForm app that accepted command line args, so when it was executed without args, the GUI appeared to let the user customize some of the features of the program, and when it was executed with args, then no GUI is shown and music is played.
However, the method for detecting when login/logouts and other NT Session Events happened was by hooking a script onto the Windows Scheduler, which ended up being a bad idea, because half of the times, the program would lock up (as the Windows Scheduler would try to execute multiple times) or didn't even execute the program (because it didn't even fire up correctly the login event).
Now, I've considered remaking my code into two programs, a service that runs the code, and a GUI app that sets up the settings for the service program. My idea is to embed an executable inside the main GUI app executable, so it automatically extracts it to a folder in order to run the service program.
However, I can imagine this isn't a pretty clean solution; more so if it triggers by error an antivirus.
I would appreciate some kind of help to get this working on a much clean and safe way.
Note: The main goal of this question is to preserve the all-in-one executable format, if possible. If not, either design a way to run a WinForm app like a system service (run at Windows startup, before login), or two individual programs, one as a service and the other as the GUI program.

How do programs run in background?

When coming across malicious Windows executable files, I noticed that some .exe files are able to run without opening a window of any kind. However, when running executables written in languages like C or C++, they always open up a console window at the very least.
How are malicious Windows executables able to run without having a window or showing up in the taskbar?
Is it a certain language or API that allows them to do this?
Lots of ways. The simplest is that they can run as a Windows subsystem process (instead of a Console subsystem - i.e. command-line one), and just not bother to ever create and show a window. They can run as a service process, or as a child of a service process (via injection into the service); those don't show UI. They can run on a different desktop (though there's no reason to do this, unless they want to show a window but don't want other processes to see that window). There's probably many others.

Can a non-root user kill an OS X "login item" launched with ServiceManagement Framework?

I am deciding between using a login item and launch agent.
In this respect I have few questions:
Is it possible for a non root user to quit a login item helper if it is launched with service management framework using SMLoginItemSetEnabled? Will the helper app be reloaded by launchD if it is killed by user or in some cases OS?
Why does apple not recommend presenting a UI with an app that can be executed via a LaunchAgent? Is there a problem if we present a minimal UI?
A login item as a helper application requires the main application to call SMLoginItemSetEnabled. This implies that the main app must be called at least once to enable the login item. This differentiates it from a launch agent which can be loaded as soon as the plist is installed on the system. Can we execute the helper login item irrespective if the user has opened the main app or not?
Any help would be appreciable
LaunchAgents that are configured using SMJobBless are intended to be non-gui services. They run without UI in the background, and don't run as the logged in user.
If you want a gui, you're going to have to use SMLoginItemSetEnabled, or manually install a user LaunchAgent via a .plist with the "LimitLoadToSessionType" = "Aqua" property.
Helpers launched by SMLoginItemSetEnabled run as the current user, so they can be terminated by that user. The process will get relaunched if launchd detects that the agent went away because of a signal or due to an abnormal termination. If it terminates due to a clean termination it will not be restarted until the next login of the user (by clean termination we mean terminating with an exit code of 0, which will not happen if the program is killed e.g. via the activity monitor. If the helper has an option to quit, and that option causes it to exit with a 0 return code, then it will not be restarted, which would be considered good form by the application.
It's a stylistic thing - a user cannot disable the agent without interacting with the command line which would be considered poor standing. There is no issue displaying a UI from a LaunchAgent. As long as it's registered with the appropriate keys, it will be launched in the user's gui login context which means that it can be fully interactive. I have several applications which act like that - TunnelBlick, 1Password (this is via the LaunchAgent plist) and they only put up a menu bar item on startup.
If you're just shipping an application - e.g. via the app store, then there's no way to have anything automatically start without some interaction by the user - you have to launch the main app to get the helper to be enabled. The helper login item can be launched manually without ever launching the main application; but it won't have the 'launch at startup' magic enabled. If you can register a LaunchAgent plist, then you can get the launch at startup & starting it up immediately behaviour.
For uninstallation, however, LaunchAgents require the removal of the .plist, and interacting with launchd to disable it, items registered with the Service Mangement framework will naturally vanish once the app is dragged to the trash.
IMHO, (bit soapboxy, bit opinionated) If you're shipping a standard app with a helper, then rely on first launch before configuring such things as helper start on login; primarily because it keeps the user in control. Autoinstalling startup items is one of my pet peeves with windows applications (so many status bar items...).
The docs for SMLoginItemSetEnabled state the login item will be "kept running", which seems to indicate it will be relaunched if it is killed:
The Boolean enabled state of the helper application. This value is effective only for the currently logged in user. If true, the helper application will be started immediately (and upon subsequent logins) and kept running. If false, the helper application will no longer be kept running.
https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled

how to use privileged helper tool(installed using SMJobless) to launch other application in root privileges on osx

I have a application inside which i have kept other applications.I want to launch other application in root privilege through main application.As we know AuthorizationExecuteWithPrivileges() has been deprecated, so that i have created a privileged helper tool. I am using Main application to install this helper tool through SMJobBless() function , and communicate through XPC mechanism. Every thing is working fine, Main application sending message(Path of application to be launch) to helper tool that is already running in root mode. The helper tool is able to launch that application provided in path, but the problem is, launched application doesn't have root privilege. Can anyone tell me how i can use this helper tool to launch another application in root privilege.Or is there any other mechanism to achieve it, i will ever thankful for this.

how to load injection lib in mac applications at application start?

I have a dynamic library, I intent to inject in running application & newly launched applications.
I can inject it in running applications with the help of a process running with root user permissions.
Now I am trying that library should get loaded as soon as application is launched. I know one such library capable of doing this called, application enhancer. I am looking for similar behavior.
Does anyone has an Idea how can this be achieved?
Look at SIMBL agent code. It adds a observer to application launch notification and then injects. You can follow the same approach.