2009-12-13 20 views
5

J'ai le fichier batch suivant, qui termine le programme iTunes de sorte que si je connecte mon iPod, il ne va pas le synchroniser. (Je sais que vous pouvez configurer cela dans iTunes.)Tuer un processus dans Batch et faire un rapport sur le succès

@echo off 
:kill 
cls 
taskkill /F /IM itunes.exe >nul 
if %errorlevel%==1 { 
echo iTunes not found. 
} else { 
echo iTunes is killed. 
} 
goto kill 

Cependant, la >nul ne répond pas à la commande; donc il donne juste le texte de la commande par défaut. Alors oui, ce que je veux faire:

Si iTunes ne se trouve pas, comme indiqué par la commande, il devrait afficher

iTunes ne trouve pas

Si elle se trouve et se termine,

iTunes est tué

Aide? le errorlevel ne fonctionne pas, cela semble être la faute du nul ne fonctionne pas.

Répondre

11

Works pour moi au moins:

> taskkill /f /im powershell.exe && echo worked || echo not worked 
SUCCESS: The process "powershell.exe" with PID 3228 has been terminated. 
worked 

> taskkill /f /im powershell.exe && echo worked || echo not worked 
ERROR: The process "powershell.exe" not found. 
not worked

Alors taskkillest retourner un code de sortie approprié. La redirection de sa sortie n'a rien à voir avec ça. Mais le niveau d'erreur pour l'échec est 128. Vous devriez vraiment utiliser l'idiome approprié pour vérifier les erreurs.

Il semble également que taskkill est l'impression à stderr afin que vous voyez sa sortie encore, lors de la redirection juste stdout. Vous pouvez envisager de réécrire le code ci-dessus pour:

taskkill /F /IM itunes.exe >nul 2>&1 
if errorlevel 1 (echo iTunes not found.) else (echo iTunes is killed.) 

Le 2>&1 redirige la sortie d'erreur standard dans le vaste néant. if errorlevel 1 vérifie errorlevel étant au moins une qui devrait fonctionner à ce moment:

nombre ERRORLEVEL Indique un état vrai si la dernière exécution du programme retourne un code de sortie égal ou supérieur au nombre spécifié. - help if

En général, la vérification errorlevel avec if %errorlevel%== est une idée tout à fait mauvais, à moins que vous comparez à 0. La sémantique des codes de sortie sont que l'absence anything de signaux non nuls. Votre hypothèse ici était juste que taskkill retournerait 1 en cas d'échec.

Ans puis-je demander gentiment pourquoi vous faites cela dans une boucle sans fin? taskkill tue déjà tous instances de itunes.exe. Et vous courez dans une boucle serrée sans aucun retard ainsi vos fichiers séquentiels consomment probablement un noyau de CPU pendant qu'il s'exécute.

ETA: Surligné votre montage: Pourquoi des accolades sur terre? Les blocs dans les fichiers batch sont délimités par des parenthèses rondes.

+0

«Pourquoi sur les accolades? Bien, je les utilise aussi longtemps que je travaillais avec eux. Je ne sais pas; j'aime juste ça. C'est plus joli je suppose. –

+2

Eh bien, si vous les utilisez dans des fichiers batch, alors attendez-vous à ce que les choses tournent mal. Si vous écrivez du code dans une langue, vous devez utiliser la grammaire du langage, peu importe ce qui vous semble le plus agréable. Les accolades ne fonctionnent pas comme délimiteurs de bloc en série. – Joey

+0

je pensais qu'ils l'ont fait. Au moins, ils ont travaillé pour les codes que j'ai utilisés. Je travaille avec batch depuis plus de 1 an maintenant, et j'ai développé avec des accolades, encore et encore, et ça marche bien. Mes clients (aka youtubers;)) disent que cela fonctionne bien pour eux. –

0

une solution de rechange, en vbscript, sauf sous le code comme mykill.vbs

Set objArgs = WScript.Arguments 
strProcess = objArgs(0) 
strComputer = "." 
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process Where Name ='" & strProcess & "'") 

If colProcesses.Count = 0 Then 
    Wscript.Echo strProcess & " is not running." 
Else 
    Wscript.Echo strProcess & " is running." 
    'Kill the process 
    For Each objProcess in colProcesses 
     r=objProcess.Terminate() 
     WScript.Echo "r is " & r 
     If r = 0 Then 
      WScript.Echo strProcess & " killed" 
     End If 
    Next   
End If 

sur la ligne de commande

c:\test> cscript //nologo mykill.vbs "itunes.exe" 
0

Pourquoi ne pas utiliser PowerShell?

try 
{ 
    Stop-Process -Name itunes -ErrorAction Stop 
    "iTunes is killed" 
} 
catch 
{ 
    "iTunes not found" 
}