JavaScript is one of the most popular entries application development framework. At VectoScalar, it’s one of the preferred choice of enterprise clients.
In a project, sometime there is a need to detect applications running in the background that requires some particular applications to be open/closed while your project is running. In this article, I am going to show you how to detect background applications using Terminal commands on MacOS and Windows in Javascript.
We basically have two commands for both platforms:
MacOS:
osascript -e ‘tell application “System Events” to return name of processes whose background only is false’
Windows:
for /f "tokens=1 delims=," %F in ('tasklist /fi "SESSIONNAME eq Console" /fi "STATUS eq RUNNING" /fo CSV') do @echo %~F
Running these commands in their respective terminals would give us the list of background applications currently running. But the real task is fetching the list of applications in our project for future manipulation.
Here is the code for the detection of background applications:
import { exec } from 'child_process'; import { promisify } from 'util'; const MAC_COMMAND = `osascript -e 'tell application "System Events" to return name of processes whose background only is false'`; const WIN_COMMAND = `for /f "tokens=1 delims=," %F in ('tasklist /fi "SESSIONNAME eq Console" /fi "STATUS eq RUNNING" /fo CSV') do @echo %~F`; const isMacOs = process.platform === 'darwin'; export const getBackgroundApps = async () => { const command = isMacOs ? MAC_COMMAND : WIN_COMMAND; const execPromise = promisify(exec); const { stdout, stderr } = await execPromise(command); if (stderr) { return stderr; } const splitChar = isMacOs ? ', ' : '\r\n'; const runningApps = stdout.trim().split(splitChar); return runningApps; };
util
library implements the Node.js util
module for environments that do not have it, like browsers.
util.promisify
takes a function following the common error-first callback style, i.e. taking a (err, value) => ...
callback as the last argument, and returns a version that returns promises.
exec
creates a shell then executes the command
within that shell, buffering any generated output, thus returning stdout
which is the required output and stderr
which is the error generated.
But wait, there’s more.
You can’t import a module from the Node.js core into a React app which in this case happens to be child_process
library.
In that case, we need to create a server where we can easily call the above function and get the results. And it’s really easy. Just type these commands in your terminal to begin.
mkdir app-server cd app-server npm init -y touch index.js
In the index.js
file of your app-server
folder, paste the following code snippet:
import express from "express"; import cors from "cors"; import { getBackgroundApps } from "./get-background-apps.js"; const app = express(); app.use(cors()); app.use(express.json()); app.get("/appList", async (req, res) => { const appList = await getBackgroundApps(); res.json({ status: 200, appList }); }); app.listen(8000, () => { console.log(`Server is running on port 8000.`); });
Run the command node index.js
on your terminal to start the server. You will get the server message on your terminal.
Server is running on port 8000.
For the client side, create a react app and paste the following code snippet into your App.js
file.
import React, { useState } from "react"; import "./App.css"; export default function App() { const [appList, setAppList] = useState([]); const getBackgroundApps = async() => { await fetch("http://localhost:8000/appList") .then((res) => res.json()) .then((data) => setAppList([...data.appList])); } return ( <div className="App"> <button onClick={getBackgroundApps}>Press to detect apps</button> <h1>List of background applications</h1> <ul> {appList.map((app) => ( <li key={Date.now()}>{app}</li> ))} </ul> </div> ); }
And that’s it. You are now able to detect the background applications running in your system. Do give it a try and let me know if any improvements can be made.