Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run script on OSX when doing fast user switching

Tags:

macos

Is it possible to setup a script to run when users switch through fast user switching on OSX (El Capitan)? Earlier on, one could use a thing like this: http://www.radiotope.com/content/os-x-how-perform-action-during-fast-user-switch - but this method has not been possible for years now.

like image 556
Per Erik Gransøe Avatar asked Sep 06 '25 03:09

Per Erik Gransøe


1 Answers

After some tries in wrong directions I came up with this quite elegant solution. My aim was to start and stop VPN connection only for specific Mac user. You can add final binary to User's login items or create a user agent in ~/Library/LaunchAgents More info: https://www.launchd.info/

You will need to be familiar with Swift and Xcode.

Create MacOS, Command line Tool project in Xcode and paste the following into main.swift

import AppKit

class VPNManager {
    init() {
        NSWorkspace.shared.notificationCenter.addObserver(
            self,
            selector: #selector(becameActive),
            name: NSWorkspace.sessionDidBecomeActiveNotification,
            object: nil
        )
        NSWorkspace.shared.notificationCenter.addObserver(
            self,
            selector: #selector(becameInactive),
            name: NSWorkspace.sessionDidResignActiveNotification,
            object: nil
        )
    }

    @objc func becameActive() {
        print("Workspace became active... starting VPN")
        let task = Process()
        task.launchPath = "/usr/sbin/networksetup"
        task.arguments = ["-connectpppoeservice","PrivateVPN (L2TP)"]
        let pipe = Pipe()
        task.standardOutput = pipe
        task.standardError = pipe
        task.launch()
        task.waitUntilExit()
        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        let output = String(data: data, encoding: .utf8)
        print("start result:", output ?? "empty")
    }

    @objc func becameInactive() {
        print("Workspace became inactive... stopping VPN")
        let task = Process()
        task.launchPath = "/usr/sbin/networksetup"
        task.arguments = ["-disconnectpppoeservice","PrivateVPN (L2TP)"]
        let pipe = Pipe()
        task.standardOutput = pipe
        task.standardError = pipe
        task.launch()
        task.waitUntilExit()
        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        let output = String(data: data, encoding: .utf8)
        print("stop result:", output ?? "empty")
    }
}

let vpnManager = VPNManager()

print("VPNManager initialized")
RunLoop.current.run()
print("VPNManager exiting")
like image 134
Matej Ukmar Avatar answered Sep 08 '25 00:09

Matej Ukmar