題 從命令行關閉程序(Windows)


從命令行關閉/退出程序的正確方法是什麼,類似於按下窗口一角的“X”關閉按鈕?

我試圖在3種不同版本的Windows下關閉chrome:win7 ultimate,win7 home,winXP

在Ultimate和XP下: TSKILL chrome

在家裡: TASKKILL /IM chrome.exe


TSKILL chrome

(它關閉了chrome,沒有cmd錯誤,
但鉻錯誤 恢復 重新啟動時)


TASKKILL /IM chrome.exe

(關閉鍍鉻,重新啟動時沒有鉻錯誤,
但是cmd中的錯誤:“無法終止子進程(大約4-5),只能強制使用 /F“)


我是否應該忽略cmd子錯誤,如果重新啟動chrome沒有顯示錯誤?


45
2018-03-11 20:25


起源


@MosheKatz:你能告訴我退出代碼的一些例子嗎?我想知道當我按下X按鈕時會發生什麼.. - neoDev
除非指定了/ F(強制終止),否則Taskkill會向目標程序發送WM_CLOSE消息,以允許程序有機會自行清理。使用記事本測試 - 打開記事本並在那裡輸入內容,然後輸入“taskkill / im notepad.exe”。您將看到保存數據的提示。 - Scott Rhee
@ScottRhee:我已經嘗試在沒有/ F的情況下運行它,但似乎是一個不合適的關閉...我錯了嗎? - neoDev
@ScottRhee:我也在嘗試使用Chrome!有時,當我重新啟動時,它會在URL下面的黃色行中顯示“恢復標籤”,類似於: backroom.bostonproductions.com/wp-content/uploads/2012/07/... - neoDev
@Roger這很奇怪,因為我沒有使用Taskkill / IM chrome.exe獲得該消息。無論如何,我相信你做對了。我在下面寫了一個答案,所以請試試。 - Scott Rhee


答案:


關閉/退出程序的正確方法最終取決於軟件。但是,通常最佳做法是Windows程序在收到WM_CLOSE消息時關閉。正確釋放內存和關閉句柄。還有其他消息可以指示應用程序的關閉,但是軟件的作者應該如何處理每個消息。

taskkill /IM process.exe

taskkill發送WM_CLOSE消息,然後由應用程序決定是否正確關閉。您可能還想使用 /T 選項也表示子進程。

只使用 /F 如果要強制終止進程,請執行選項。

其他選項包括使用PowerShell發送Alt + F4鍵或第三方應用程序。

更新到更新的問題

忽略,錯誤。  Chrome會生成許多流程。當進程不確認TASKKILL發送的WM_CLOSE消息時,會導致錯誤。只有具有消息循環的進程才能接收消息,因此,沒有消息循環的進程將生成該錯誤。最有可能的是,這些進程是chrome擴展和插件。

隱藏錯誤捕獲輸出

taskkill /IM chrome.exe >nul

摘要: TASKKILL是通過命令行根據其WM_CLOSE實現關閉應用程序的正確方法 我鏈接的Microsoft KB


39
2018-03-11 21:51



我更新了我的問題,請看一下 - neoDev
@Roger更新了我的回答。 - David Ruhmann
這是什麼意思> nul? - neoDev
> 是重定向運算符 對於cmd.exe和 nul 是空間的空白,永遠不會再聽到任何事情。 - David Ruhmann


嘗試 的NirCmd (下載: 86  64位

它具有“closeprocess”命令,旨在優雅地關閉進程。根據其文檔,它不會終止應用程序但會發送 WM_CLOSE 到目標進程的所有頂級窗口。

用法示例:

nircmd closeprocess chrome.exe

如果這不起作用,我打賭你的應用程序有一個不尋常的清理程序。我想看看裡面發生了什麼,請告訴我你的目標應用是什麼。


5
2018-03-11 21:21



我更新了我的問題,請看一下 - neoDev


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?

可以找到該問題的答案 here微軟鏈接)。

你可以發送 WM_CLOSE 消息到您要關閉的任何窗口。許多窗戶處理 WM_CLOSE提示用戶保存文檔。

正確執行此操作的工具是 @Kill。還看 SENDMSG


我不知道如何批量執行此操作,但您可以使用vbscript。模擬 Alt鍵 + F4 鍵(等於信號 WM_CLOSE)。

運行並查看下面此腳本的行為。

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 是SendKeys的列表鍵名。

當你運行腳本時, 記事本 打開,寫下一些單詞,然後發出關閉程序的信號,見下圖。


其他問題

我可以使用vbscript啟動程序最小化或背景嗎?

是。使用以下代碼:

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

有關更多信息,請查看 Run Method

chrome可以在vbscript中找到一些url嗎?

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

如果chrome是默認值,請使用:

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

Source

有沒有辦法把重點放在特定的應用上(的chrome.exe)?

Here 在一個例子中。

我想將alt + f4僅發送給chrome,而不管我正在使用其他窗口。

以下代碼適用於 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}"

4
2018-03-11 23:22



我可以使用vbscript啟動程序最小化或背景嗎? - neoDev
@Roger如果有興趣,請參閱 我的答案在這裡 關於如何將Batch + JScript組合到單個文件中。 JScript可以執行VBScript可以執行的任何操作,並且可以採用更結構化的C風格。 - David Ruhmann
並且可以在vbscript中使用chrome進入某個URL? - neoDev
有沒有辦法把焦點帶到特定的應用程序(chrome.exe)? - neoDev
是的我正在嘗試使用它,但如果經過一段時間的延遲(WScript.Sleep 5000)我有(WshShell.AppActivate“谷歌瀏覽器”),如果在此期間我點擊其他窗口,谷歌瀏覽器不會出現在前面,我只能在工具欄上看到它的焦點.... - neoDev


有一些命令行實用程序可以發送合適的 WM_SYSCOMMAND 消息(帶 SC_CLOSE 作為命令)到程序的頂級窗口。我相信很快就會提到至少一個。 (然後有人會提到AutoIt。然後會有一個答案顯示如何使用PowerShell和 CloseMainWindow()。)

作為內置命令的命令行實用程序 JP Software的TCC,調用Windows的命令解釋器和命令腳本處理器 TASKEND


3
2018-03-11 21:18



我更新了我的問題,請看一下 - neoDev


好吧,不要撒謊。我在stackoverflow上看到了這個,並認為這是一個具有挑戰性的問題。 Soooo我花了最近2個小時寫了一些代碼。在這裡......

按照以下步驟操作後,您可以在點擊“開始”後鍵入“TaskClose notepad.exe”,它會自動將所有未記錄的記事本文件保存到桌面。它將自動關閉chrome.exe並保存恢復設置。

您可以在if條件下為其他應用程序添加和刪除其他設置。例如:

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

vbs和批處理文件執行以下過程:

  • 收集可執行文件。
  • 關閉可執行應用程序名稱 任務列表。
  • 執行“Alt + TAB(x)”過程直到它有 驗證窗口是否打開。
  • 然後執行滾動命令,無論是“Alt + F4”還是極端情況
  • ALT + F4
  • 激活保存
  • AutoIncrememnt文件名
  • 退出申請。

ReturnAppList.bat:安裝在“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:安裝在“C:\ windows \ system32 \”和“C:\ Users \ YourUserName \”中

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

TaskClose.vbs:安裝在“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

這寫起來很有趣,而且我對完成它比實際顯示答案更開心。祝你度過愉快的一周!


2
2018-03-12 01:37