Batch File to Start Software application if it's not already running

2

1

I've figured out how to test if a specific instance of software is running using Tasklist.

@echo off Title - FTView Client Application Finder

TASKLIST /FI "WINDOWTITLE EQ Grain*"

I get a response that looks something like this.

Image Name PID Session Name Session# Mem Usage ========================= ======== ================ =========== ============ DisplayClient.exe 3768 Console 4 62,476 K

Is there a way to use this information to start an application if it is not found?

My intention is to create a scheduled task to run every 15-30 Minutes to run this a batch file that will look for this specific instance of software and launch the software if it is not already running. I can't use the Task Image name because there are multiple instances of the same software running on this machine, so I have to look for a specific instance.

With Damian L.'s help I've made some progress on this using Powershell instead of Command Line. Still have one hitch at line #17 (2nd Else) the script launches the application requested, but doesn't set the $LoggingResult variable correctly. It just outputs the last known $LoggingResult.

#Script Looks for FTView Logging Application
#If Found - Logs that the application is Running to the Log Text File
#If Not Found - Launches the production logging client and Logs appropriate message to the Log Text File
#If Multiple Instances are found - Notifies the operator to close one down.
$Time = Get-Date  #variable for the current date string
$Logfile = [string] 'c:\Shared Folder\LoggerLaunchLog.txt'  #variable Log File Path
$WindowLookup = [string] 'Grain*'    #variable for what window title you are looking for.
$TargetApp = [string]'C:\Users\Public\Documents\RSView Enterprise\SE\Client\GGCLA-WWMill.cli' #Variable for defining the application to launch
#
#
$process = Get-Process | Where-Object -Like MainWindowTitle -Value $windowlookup   #Looks for running process with matching window title
#evaluation & action depending on result
If ($process.count -gt 0){ 
    If ($process.count -gt 1) {$LoggingResult = "Multiple Instances of Logging Application Are Running - Please Close 1"}
    else {$LoggingResult = "Logging Application is Running"}
    }   
else {Start-Process $TargetApp{$LoggingResult = "Logging Application not found - Loading Application"}}
Write-Output "$Time $LoggingResult"  #Command Line output for Powershell Visual display - optional
Add-content $Logfile -value "$Time $LoggingResult"  #Writes the results & actions to the Log Text File
#pause #for testing to visually see output

Final Edit - Thanks again to Damian T. for the assist, it's all working properly now...

#Script Looks for FTView Logging Application
#If Found - Logs that the application is Running to the Log Text File
#If Not Found - Launches the production logging client and Logs appropriate message to the Log Text File
#If Multiple Instances are found - Notifies the operator to close one down.

$Time = Get-Date  #variable for the current date string
$Logfile = [string] 'c:\Shared Folder\LoggerLaunchLog.txt'  #variable Log File Path
$WindowLookup = [string] 'Grain*'    #variable for what window title you are looking for.
$TargetApp = [string]'C:\Users\Public\Documents\RSView Enterprise\SE\Client\GGCLA-WWMill.cli' #Variable for defining the application to launch

$process = Get-Process | Where-Object -Like MainWindowTitle -Value $windowlookup   #Looks for running process with matching window title
#evaluation & action depending on result
If ($process.count -gt 0){ 
    If ($process.count -gt 1) {$LoggingResult = "Multiple Instances of Logging Application Are Running - Please Close 1"
    Write-Output "$Time $LoggingResult"
    pause}
    else {$LoggingResult = "Logging Application is Running"}
    }   
else {Start-Process $TargetApp
$LoggingResult = "Logging Application not found - Loading Application"}
Write-Output "$Time $LoggingResult"  #Command Line output for Powershell Visual display - optional
Add-content $Logfile -value "$Time $LoggingResult"  #Writes the results & actions to the Log Text File
#pause #for testing to visually see output

Bludeuce

Posted 2018-01-16T21:53:19.883

Reputation: 25

3

Hint: findstr - Search for strings in files.

– DavidPostill – 2018-01-16T22:13:46.530

Answers

1

Honestly, I'd recommend using PowerShell instead for something of this nature. PS v5.1 can be installed on anything since Windows 7 (including 7).

But, if you are constrained to only using basic Command Prompt, here is a sample batch file that should work.

Batch

@echo off
:: Title - FTView Client Application Finder

:: This what is said if it's not running
set TESTSTR=INFO: No tasks are running which match the specified criteria.
set /A NOTRUNNING=0

:: Iterate over all of the lines produced by the command.
for /F "delims=" %%a in ('tasklist /fi "WINDOWTITLE EQ Grain*"') do (
    :: If a line matches the test string, then the program isn't running.
    if "%%a"=="%TESTSTR%" (
       set /A NOTRUNNING=1
   )
)

if %NOTRUNNING%==1 (
    echo It is NOT running.
) else (
    echo It is running.
)

PowerShell

However, PowerShell is a lot more extensive. The advantages would be:

  • Tighter criteria for matching the desired process
  • More extensive options for executing processes
  • Better error-handling
  • Better flow-control

Since I don't have the program that you're trying to match, it'll be hard for me to come up with a prototype PowerShell solution. However, I can share the process I would take to go about writing it.

> Get-Process

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
     19       5     2764       3752       0.00  12188   1 cmd
    824      41   109200     123184      14.46  12520   1 powershell

Only listed a couple processes for brevity.

With the FTView Client running, get the Process ID (in my examples, I'll be using the powershell.exe process) and then run the following command:

> Get-Process -Id 12520 | Format-List *

Name                       : powershell
Id                         : 12520
PriorityClass              : Normal
FileVersion                : 10.0.14409.1005 (rs1_srvoob.161208-1155)
HandleCount                : 950
WorkingSet                 : 137814016
PagedMemorySize            : 123269120
PrivateMemorySize          : 123269120
VirtualMemorySize          : 696459264
TotalProcessorTime         : 00:00:15.3192982
SI                         : 1
Handles                    : 950
VM                         : 696459264
WS                         : 137814016
PM                         : 123269120
NPM                        : 42680
Path                       : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Company                    : Microsoft Corporation
CPU                        : 15.3192982
ProductVersion             : 10.0.14409.1005
Description                : Windows PowerShell
Product                    : Microsoft® Windows® Operating System
__NounName                 : Process
BasePriority               : 8
ExitCode                   :
HasExited                  : False
ExitTime                   :
Handle                     : 3492
SafeHandle                 : Microsoft.Win32.SafeHandles.SafeProcessHandle
MachineName                : .
MainWindowHandle           : 919266
MainWindowTitle            : Administrator: Windows PowerShell
MainModule                 : System.Diagnostics.ProcessModule (powershell.exe)
MaxWorkingSet              : 1413120
MinWorkingSet              : 204800
Modules                    : {System.Diagnostics.ProcessModule (powershell.exe), System.Diagnostics.ProcessModule
                             (ntdll.dll), System.Diagnostics.ProcessModule (aswhooka.dll),
                             System.Diagnostics.ProcessModule (kernel32.dll)...}
NonpagedSystemMemorySize   : 42680
NonpagedSystemMemorySize64 : 42680
PagedMemorySize64          : 123269120
PagedSystemMemorySize      : 527352
PagedSystemMemorySize64    : 527352
PeakPagedMemorySize        : 193662976
PeakPagedMemorySize64      : 193662976
PeakWorkingSet             : 206139392
PeakWorkingSet64           : 206139392
PeakVirtualMemorySize      : 711643136
PeakVirtualMemorySize64    : 711643136
PriorityBoostEnabled       : True
PrivateMemorySize64        : 123269120
PrivilegedProcessorTime    : 00:00:07.3320470
ProcessName                : powershell
ProcessorAffinity          : 255
Responding                 : True
SessionId                  : 1
StartInfo                  : System.Diagnostics.ProcessStartInfo
StartTime                  : 1/17/2018 20:45:30
SynchronizingObject        :
Threads                    : {9812, 14088, 924, 14064...}
UserProcessorTime          : 00:00:08.0184514
VirtualMemorySize64        : 696459264
EnableRaisingEvents        : False
StandardInput              :
StandardOutput             :
StandardError              :
WorkingSet64               : 137814016
Site                       :
Container                  :

This will show you all of the properties you can filter on. The reason I mention this step is because the information here is slightly different than what was used in the batch file. Let's look at MainWindowTitle.

MainWindowTitle            : Administrator: Windows PowerShell

It contains exactly what is displayed in the window title bar. If we wanted to filter our selection based on this, we would use the command:

> Get-Process | Where-Object -Filter-Object MainWindowTitle -Like "*PowerShell*"

And this would be how you determine if that process is running. In order to use this in a conditional statement, you can do:

> $process = Get-Process | Where-Object -Filter-Object MainWindowTitle -Like "*PowerShell*"

> $process.Count
1

> If ($process.Count -gt 0) { Write-Host Yes } Else { Write-Host No }
Yes

You can then launch the application using Start-Process.

By using PowerShell, your script will be more robust and will only be two lines of code.

$process = Get-Process | Where-Object -Filter-Object MainWindowTitle -Like "Grain*"
If ($process.Count -eq 0) { Start-Process FTView.exe }

If you use Get-Help Start-Process, you will see that it has a bunch of options you can use to start the process, such as passing arguments, using credentials, making the window hidden, etc.

Damian T.

Posted 2018-01-16T21:53:19.883

Reputation: 265

Yea that's the ticket - With a little modification to launch the program it works perfectly.

It's on a W10 machine so Powershell is already installed & available. I'm not really familiar with syntax rules, honestly in either program, but I tried to run this script in PS, after enabling scripts. It came back with some errrors. I could probably work through it, but is there really any advantage, if it's already working from Command Prompt? – Bludeuce – 2018-01-18T01:10:56.003

@Bludeuce I'm not sure why it would cause errors running in a PowerShell prompt, but I tested it on a Windows 10 Command Prompt. The reason I recommended PowerShell is because commands can be chained together to pass and manipulate objects without having to "hack" together solutions that parse text. I'll come up with a PS solution and add it to my answer. – Damian T. – 2018-01-18T01:45:17.000

I've probably spent entirely too much time on this, but I'm getting closer, thanks to your assistance. I have it working now in PowerShell & I've added some features to make it more readily portable and also to provide a log file of what it is doing. Still having one hitch that seems to be giving me some issues. Line #17 (2nd Else) it's starting the process correctly, but it doesn't change the $LoggingResult properly. It just logs the last known result when it goes into that else condition. – Bludeuce – 2018-01-18T21:50:53.973

Updated PowerShell Code posted at end of original question.... – Bludeuce – 2018-01-18T21:57:31.857

@Bludeuce I'm not sure why you have another set of braces on line 17. Right after Start-Process $TargetApp, there should be a carriage return instead of an open brace. – Damian T. – 2018-01-18T23:02:59.380

Cause i'm a noob. That fixed it, thanks again for all the help. I'd mark the question answered, but I don't have enough Rep. to do so... I fixed this up & added another twist. Should I repost the final? – Bludeuce – 2018-01-18T23:14:54.380

@Bludeuce Honestly, I'd update the question with the working script and call it good. The answer was already marked as an answer, so it's all good. I'm glad I was able to help! – Damian T. – 2018-01-18T23:17:24.763