5

Recently I am trying to figure out how to run a dotnet service after my MacOS startup.

On Windows, I can install the NSSM to run the script as a service. This script will be triggered whenever my computer starts up.

Inside the script contains the line of code like dotnet RunMyService

Am I allow to perform the same action in MacOS as well?

1 Answers1

4

Yes, via launchd -- you will have to use launchctl to configure applications on your mac to run via launchd (similar to Linux systemd or the Windows SCM.)

From another post, "There is no requirement that you use any Cocoa/Mac APIs to implement an agent/daemon, you could run any console app under launchd and the above would still remain true." ~ SO#40952619

You only need a plist and a script.

The Script

My advice is to place your script into /usr/local/bin/ or similar, chown to root:wheel, and chmod to 755 making it an executable. Your script should contain the full path to dotnet and cd to the working folder of your service before starting execution. This is only an example:

#!/bin/sh
cd /path/to/your/service/
/usr/local/share/dotnet/dotnet MyService.dll

For the sake of this post, let's assume you saved this as /usr/local/bin/launch-my-service.sh:

sudo chown root:wheel /usr/local/bin/launch-my-service.sh
sudo chmod 755 /usr/local/bin/launch-my-service.sh

If you run this script manually it should successfully launch your service. Once confirmed, kill the process and create the PLIST.

The PLIST

For launchd wants a plist, take this as an example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>localhost.my-service</string>
        <key>Program</key>
        <string>/usr/local/bin/launch-my-service.sh</string>
        <key>RunAtLoad</key>
    </dict>
</plist>

Save this to your home folder, launchctl will make a copy of it anyway. For the sake of this post, let's assume you saved this as localhost.my-service.plist to match the "Label" configured inside the plist (which is what launchctl will display.)

Configure launchd

Now we add the "service" to launchd, and start it:

launchctl load localhost.my-service.plist # here we specify the plist file
launchctl list | grep localhost
launchctl start localhost.my-service # here we specify the "Label" configured in the plist file

It's beyond the scope of this Q&A, but, this creates an "Agent" (rather than a Daemon), which is a macOS/launchd specific concept. An "Agent" is an application which runs in the background whenever a user logs in to the macOS desktop. The Agent runs with the identity of the logged in user. The run state of an Agent may change depending on the logged in state of the user (may stop, tombstone, etc.) It is also possible to install as a "Daemon" which would run in the context of the system (rather than the logged in user), and which can be configured to run whether or not a user logs in. An example plist for configuring an "inetd-compatible daemon" can be found on developer.apple.com "Creating launchd Jobs"

HTH someone else out there. Totally irrelevant if you're using dotnet, java, lua, or python macOS could care less.