63

What is the proper way to close/exit programs from command line, similar to pressing the "X" close button in the corner of the window?

Im trying to close chrome under 3 different versions of windows: win7 ultimate, win7 home, winXP

Under Ultimate and XP: TSKILL chrome

Under Home: TASKKILL /IM chrome.exe


TSKILL chrome:

(It closes chrome, no cmd errors,
but chrome error restore when relaunch it)


TASKKILL /IM chrome.exe:

(It closes chrome, no chrome errors when relaunch it,
but errors in cmd: "impossible to terminate child processes(about 4-5), only by force with /F")


Should I ignore cmd child errors if on relaunch chrome show me no errors?

6
  • @MosheKatz: Can you show me some example of exit code please? I would like to know what happens when I hit the X button..
    – neoDev
    Mar 11, 2014 at 21:01
  • 6
    Taskkill sends WM_CLOSE message to the target program unless /F (forced termination) is specified, to allow the program to have chances to clean up itself. Test this with Notepad - open a notepad and type something there, and enter "taskkill /im notepad.exe". You will see a prompt to save the data.
    – Scott Rhee
    Mar 11, 2014 at 21:01
  • @ScottRhee: I already tried to run it without /F, but seems to be an unproper close... Am I wrong?
    – neoDev
    Mar 11, 2014 at 21:07
  • @ScottRhee: Im trying with Chrome too! Sometimes, when I relaunch it says "restore tabs" in a yellow line under the URL similar to this: backroom.bostonproductions.com/wp-content/uploads/2012/07/…
    – neoDev
    Mar 11, 2014 at 21:17
  • @Roger That's strange as I don't get that message with Taskkill /IM chrome.exe. Anyway, I believe you did the right thing. I wrote an answer below so please try that instead.
    – Scott Rhee
    Mar 11, 2014 at 21:32

5 Answers 5

54

The proper way to close/exit a program ultimately depends upon the software. However, generally the best practice is for Windows programs to close whenever they receive the WM_CLOSE message. Properly releasing memory and closing handles. There are other messages that can signal the close of the application, but it is up to the author of the software how each message is handled.

taskkill /IM process.exe

taskkill sends the WM_CLOSE message and it is then up to the application whether to properly close. You may also want to use the /T option to also signal child processes.

Only use the /F option if you want to force the termination of the process.

Other options would include sending the Alt+F4 keys, using PowerShell, or 3rd party applications.

Update to Updated Question

Ignore, the errors. Chrome generates many processes. The errors are caused when an process does not acknowledge the WM_CLOSE message that TASKKILL sends. Only processes with a message loop will be able to receive the message, therefore, the processes that do not have a message loop will generate that error. Most likely, these processes are the chrome extensions and plugins.

To hide the errors capture the output

taskkill /IM chrome.exe >nul

Summary: TASKKILL is the proper way via command line to close applications per its WM_CLOSE implementation and the Microsoft KB that I linked.

4
  • I updated my question, please have a look at it
    – neoDev
    Mar 11, 2014 at 23:17
  • @Roger updated my answer. Mar 11, 2014 at 23:46
  • what does it mean >nul?
    – neoDev
    Mar 11, 2014 at 23:46
  • 10
    > is the redirect operator for the cmd.exe and nul is the void of space where things go to never be heard from again. Mar 11, 2014 at 23:48
10

Try NirCmd (Download: x86 x64)

It has "closeprocess" command which is designed to close processes gracefully. As per its document, it does not terminate apps but sends WM_CLOSE to all top-level windows of the target process.

usage example:

nircmd closeprocess chrome.exe

If this doesn't work, I bet your application has an unusual cleanup procedure. I would like to see what happens inside so please let me know what your target application is.

2
  • I updated my question, please have a look at it
    – neoDev
    Mar 11, 2014 at 23:16
  • 1
    I found this to work better: nircmd win close title "My process title"
    – driedler
    Aug 23, 2019 at 13:20
4
What is the proper way to close/exit programs from command line,
similar to pressing the "X" close button in the corner of the window?

The answer to that question can be found here(Microsoft link).

You can send WM_CLOSE messages to any window you wish to close. Many windows handle WM_CLOSE to prompt the user to save documents.

A tool that does this correctly is @Kill. Look also SendMsg.


I do not know how to do this in batch, but you could use the vbscript for this. Simulating the Alt + F4 keys (equates to signal WM_CLOSE).

Run and look at the behavior of this script below.

Set WshShell = WScript.CreateObject("WScript.Shell")

' Start Notepad.exe
WshShell.Run "%windir%\notepad.exe"

' Select, or bring Focus to a window named `Notepad`
WshShell.AppActivate "Notepad"

' Wait for 4 seconds
WScript.Sleep 4000

WshShell.SendKeys "Foo"
WshShell.SendKeys "{ENTER}"
WshShell.SendKeys "Bar"
WshShell.SendKeys "{ENTER}"
WshShell.SendKeys "{CAPSLOCK}"
WshShell.SendKeys "baz"
WshShell.SendKeys "%{F4}"

Here is the list key names for SendKeys.

When you run the script, the notepad is open, some words are written and then a signal to close the program is delivered, see picture below.


Additional Questions

Can I start a program minimized, or background with vbscript?

Yes. Use the following code:

WshShell.Run "%windir%\notepad.exe", 2

For more information check the Run Method.

Can chrome go to some url in vbscript?

Dim iURL  
Dim objShell iURL = "www.google.com"
set objShell = CreateObject("Shell.Application") 
objShell.ShellExecute "chrome.exe", iURL, "", "", 1

If chrome is the default, use:

set objShell = CreateObject("WScript.Shell")
objShell.run(iURL)

Source

Is there a way to bring focus to specific application (chrome.exe)?

Here in an example.

I want to send alt+f4 ONLY to chrome, independently of i'm doing with other windows.

The following code works on Windows 8.

Dim objShell

iURL = "www.google.com.br"

Set WshShell = WScript.CreateObject("WScript.Shell")

WshShell.Run(iURL)

' Select, or bring Focus to Google Chrome
WshShell.AppActivate "Google Chrome"

' Wait for 5 seconds
WScript.Sleep 5000

WshShell.SendKeys "%{F4}"
9
  • Can I start a program minimized, or background with vbscript?
    – neoDev
    Mar 11, 2014 at 23:43
  • 1
    @Roger If interested, see my answer here on how to combine Batch + JScript into a single file. JScript can do most anything VBScript can do and in a more structured C style. Mar 11, 2014 at 23:54
  • and can chrome go to some url in vbscript?
    – neoDev
    Mar 11, 2014 at 23:57
  • is there a way to bring focus to specific application (chrome.exe)?
    – neoDev
    Mar 12, 2014 at 0:34
  • Yes I'm trying with it, but if after some delay (WScript.Sleep 5000) i have (WshShell.AppActivate "google chrome"), if during this period i click on some other window, google chrome doesn't come to front, i can see its focus only on the toolbar....
    – neoDev
    Mar 12, 2014 at 1:12
3

There are some command-line utilities that can send a suitable WM_SYSCOMMAND message (with SC_CLOSE as the command) to a program's top-level window. I'm sure that at least one will be mentioned shortly. (Then someone will mention AutoIt. Then there'll be an answer showing how to do it with PowerShell and CloseMainWindow().)

The command-line utility that comes as a built-in command in JP Software's TCC, a command interpreter and command script processor for Windows, is called TASKEND.

1
  • I updated my question, please have a look at it
    – neoDev
    Mar 11, 2014 at 23:16
2

Alright, Not going to lie. I saw this on stackoverflow and thought it was a challenging question. Soooo I just spent the last 2 hours writing some code. And here it is....

After following the steps below, you can type "TaskClose notepad.exe" after hitting "Start" and it will auto save all undocumented notepad files into desktop. It will auto-close chrome.exe and save the restoration settings.

You can add and remove additional settings for other applications under the if conditions. For instance:

If InStr(SINGLECLOSEAPPS, WScript.arguments(0)) Then
    SmartSendKeys strOutput,"bypass","%{F4}"

ElseIf InStr(AUTOCLOSEAPPS, WScript.arguments(0)) Then
    SmartSendKeys strOutput,"","%{F4}|%s|{autoname}.txt|%s"

'Example 1: =============================================
ElseIf InStr(WScript.arguments(0), "outlook") Then
    SmartSendKeys strOutput,"","%{F4}" 'Activate Alt+4
'========================================================

'Example 2: =============================================
ElseIf InStr(WScript.arguments(0), "notepad") Then 'I know, already in my autoapps
    SmartSendKeys strOutput,"","%{F4}|%s|{autosave}.txt" 'Activate Alt+4 + Save File + {AutoSave} = autoincrement filename
'========================================================

Else
    SmartSendKeys strOutput,"bypass","%{F4}"
End If

The vbs and batch files performs the following procedures:

  • Collects the executable.
  • Queries the executable application names off of the tasklist.
  • Performs an "Alt+TAB(x)" procedure until it has verified the window is open.
  • Then Executes the rolling commands whether it be "Alt+F4" or even in extreme cases
  • Alt+F4
  • Activate Save
  • AutoIncrememnt Filename
  • Exit application.

ReturnAppList.bat : install in "C:\windows\system32\"

for /f "tokens=10 delims=," %%F in ('tasklist /v /fi "imagename eq %1" /fo csv') do @echo %%~F >>result.txt

TaskClose.bat : install in "C:\windows\system32\" AND "C:\Users\YourUserName\"

C:\windows\system32\wscript.exe c:\windows\system32\taskclose.vbs %1

TaskClose.vbs : install in "C:\windows\system32\"

Set WshShell = CreateObject("WScript.Shell")
Const SINGLECLOSEAPPS = "chrome.exe|iexplore.exe|firefox.exe"
Dim DEFAULTSAVELOCATION : DEFAULTSAVELOCATION = wshshell.SpecialFolders("Desktop")
Const AUTOCLOSEAPPS = "notepad.exe"

Const WshFinished = 1
Const WshFailed = 2
strCommand = "returnapplist.bat "
Set WshShellExec = WshShell.Exec(strCommand & WScript.Arguments(0))

WScript.sleep 2000

Select Case WshShellExec.Status
    Case WshFinished
    strOutput = LoadStringFromFile("result.txt")
    Case WshFailed
    strOutput = LoadStringFromFile("result.txt")
End Select


'SmartSendKeys(application_name_array, bypassclause, additionalcommands)
'========================
If InStr(SINGLECLOSEAPPS, WScript.arguments(0)) Then
    SmartSendKeys strOutput,"bypass","%{F4}"
ElseIf InStr(AUTOCLOSEAPPS, WScript.arguments(0)) Then
    SmartSendKeys strOutput,"","%{F4}|%s|{autoname}.txt|%s"
Else
    SmartSendKeys strOutput,"bypass","%{F4}"
End If




'SmartSendKeys(application_name_array, bypassclause, additionalcommands)
'========================
Function SmartSendkeys(fArr, LoopCount, RollCommands) 
    Dim x 
    Dim splt : splt = Split(farr, vbCrLf)
    If loopcount = "bypass" Then 
        x = 0
    Else
        x = UBound(splt)
    End If
    a = 0
    For s=0 To x
        If Len(splt(s)) > 1 Then
            Set objShell = WScript.CreateObject("WScript.Shell")
            c = 1 : tabs = ""
            Success = False
            Do Until Success = True
                Success = objShell.AppActivate(Trim(splt(s)))
                If success <> True Then
                    If c = 1 Then 
                        tabs = "{TAB}"
                    Else
                        tabs = "{TAB " & c & "}"
                    End If
                    'wscript.echo "Activating: " & "%" & tabs
                    WshShell.SendKeys "%" & tabs
                    WScript.Sleep 5000
                    c = c + 1
                    If c = 100 Then 
                        WScript.echo "App not found"
                        Exit Function
                    End If
                End If
            Loop
            Dim cmds : cmds = Split(rollcommands, "|")

            For Each cm In cmds
                If InStr(cm, "{autoname}") Then
                    Dim file_ext : file_ext = Split(cm, ".") 
                    cm = DEFAULTSAVELOCATION & "autosave" & a & "." & file_ext(1)
                    a = a + 1
                End If
                WshShell.SendKeys cm
                WScript.sleep 500

            Next
        End If
    Next
End Function

Function LoadStringFromFile(filename)
    Const fsoForReading = 1
    Const fsoForWriting = 2
    Dim fso, f
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f = fso.OpenTextFile(filename, fsoForReading)
    Dim fulltext : fulltext = f.ReadAll
    LoadStringFromFile = fulltext
    f.Close
    fso.DeleteFile(filename)
End Function

This was alot of fun to write and I'm more happy about finishing it than actually showing the answer. Have a great week!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .