Start programs via command-line, but only if not already running

I came up with the batch file below, and it is working great. However, I would like to know if there is a way to code it so that if a program is already running, it would skip it and launch the next one. I hope this makes sense. Any advice would be greatly appreciated.

@echo off    
pushd    
start "" cmd /c cscript "C:\Users\User\Desktop\Work.vbs"    
start "C:\Program Files\Microsoft Office\Office15" Outlook.exe    
start "C:\Program Files\Microsoft Office\Office15" Lync.exe    
start "C:\Program Files (x86)\Google\Chrome\Application" chrome.exe    
runas /savecred /user:"DOMAIN\User_Adm" "C:\Program Files (x86)\VMware\Infrastructure\Virtual Infrastructure Client\Launcher\VpxClient.exe"    
runas /savecred /user:"DOMAIN\User_Adm" "mmc.exe \"My_Tools.msc\"

Solution 1:

Here is a example using tasklist to check all running applications for a given name.
Otherwise it starts the program. I'm sure you can adapt it to your needs

tasklist /nh /fi "imagename eq notepad.exe" | find /i "notepad.exe" > nul ||
(start notepad.exe)

Solution 2:

I implemented tasklist into my script and its working like a charm.
Here it is for anyone else having the same questions as I had.

@echo off
pushd
tasklist /nh /fi "imagename eq iexplore.exe" | find /i "iexplore.exe" > nul ||(start Work.vbs)
tasklist /nh /fi "imagename eq outlook.exe" | find /i "outlook.exe" > nul ||(start outlook.exe)
tasklist /nh /fi "imagename eq lync.exe" | find /i "lync.exe" > nul ||(start lync.exe)
tasklist /nh /fi "imagename eq chrome.exe" | find /i "chrome.exe" > nul ||(start chrome.exe)
tasklist /nh /fi "imagename eq VpxClient.exe" | find /i "VpxClient.exe" > nul || runas /savecred /user:"DOMAIN\User_Adm" "C:\Program Files (x86)\VMware\Infrastructure\Virtual Infrastructure Client\Launcher\VpxClient.exe"
tasklist /nh /fi "imagename eq mmc.exe" | find /i "mmc.exe" > nul || runas /savecred /user:"DOMAIN\User_Adm" "mmc.exe \"My_Tools.msc\"

Solution 3:

@echo off      
tasklist /FI "IMAGENAME eq outlook.exe" | find /i "outlook.exe"      

IF ERRORLEVEL 2 GOTO LOOP2
IF ERRORLEVEL 1 GOTO LOOP1 

:LOOP1 
  start notepad.exe
goto EXIT     

:LOOP1 
  start outlook.exe 
goto EXIT 

:EXIT

Solution 4:

Here is a PowerShell version (instead of CMD).

(You can run powershell from CMD by calling "powershell.exe".

This script does the following:

  1. Checks the process list for a specific process, and if the process is not found in the list...
  2. It will search for the executable in a specific location (like program files), and run it.

In this example, I am starting Skype for Business (AKA "lync").

Here is a 1 liner:

if (!((Get-Process | select ProcessName).ProcessName | where {$_ -like "*lync*"})){&(where.exe /R "C:\Program Files (x86)\Microsoft Office" "lync.exe")}

Here is a commented version:

# If there isn't a running process that contains "lync"...
if (!((Get-Process | select ProcessName).ProcessName | where {$_ -like "*lync*"}))
{
    # Find the executable somewhere in program files (x86), and run it.
    &(where.exe /R "C:\Program Files (x86)\Microsoft Office" "lync.exe")
}

(You don't have to actually search for the executable, you could instead run it directly - however searching for the executable allows for MS Office updates which can sometimes change the install directory)

Solution 5:

I followed nixda's answer which worked great however I had an issue where multiple copies of my application was still starting!!

This was due to the length of my .exe name so I thought I would add a tweaked version of nixda's answer here just in case others have the same issue.

If your .exe name is long such as: "SomeReallyVerySuperLongProgram.exe" then tasklist truncates its output which means when you pipe the output to the find command it fails and opens a 2nd instance of your application.

For Example:

enter image description here

So instead of using tasklist I used the wmic command to find out of the process was already running.

Here is my tweaked version:

wmic process where "name='win32calc.exe'" get ProcessID | find /i "ProcessId" > nul || (start /min win32calc.exe)