Может ли командный файл указать, запущена ли программа? [Дубликат]

Это означает, что указанная переменная не указана ни на что. Я мог бы сгенерировать это так:

SqlConnection connection = null;
connection.Open();

Это вызовет ошибку, потому что, пока я объявил переменную «connection», она не указала ни на что. Когда я пытаюсь вызвать член «Open», для его устранения нет ссылки, и он будет вызывать ошибку.

Чтобы избежать этой ошибки:

  1. Всегда инициализируйте свои объекты, прежде чем пытаться что-либо с ними делать.
  2. Если вы не уверены, что объект имеет значение null, проверьте его с помощью object == null.

Инструмент Resharper JetBrains определит каждое место в вашем коде, которое имеет возможность ошибки нулевой ссылки, позволяя вам ввести нулевую проверку. Эта ошибка является источником ошибок номер один, IMHO.

220
задан Keng 2 October 2008 в 15:45
поделиться

14 ответов

Предложение npocmaka использовать QPROCESS вместо TASKLIST велико, но его ответ настолько большой и сложный, что я чувствую себя обязанным опубликовать довольно упрощенную версию, которая, я думаю, решит проблему большинства неусовершенствованных пользователи:

QPROCESS "myprocess.exe">NUL
IF %ERRORLEVEL% EQU 0 ECHO "Process running"

. Вышеописанный код был протестирован в Windows 7 с пользователем с административными настройками.

12
ответ дан aldemarcalazans 1 September 2018 в 04:11
поделиться
  • 1
    Я просто использовал эту идею, чтобы остановить автоматический процесс стрельбы дважды, и это сработало, как шарм! – Davy C 14 March 2018 в 11:23
  • 2
    Должен сказать, что в отличие от этой команды решения tasklist не только выглядят слишком сложными для такого простого запроса, но они также запускают секунду или около того и используют тонны процессора! Это намного лучше, также работало без прав администратора (Windows Server 2012). – Eugene Marin 21 June 2018 в 15:36

На основе ответа vtrz и ответ Самуэля Ренкерта по другой теме я придумал следующий скрипт, который запускает только %EXEC_CMD%, если он еще не запущен :

@echo off
set EXEC_CMD="rsync.exe"
wmic process where (name=%EXEC_CMD%) get commandline | findstr /i %EXEC_CMD%> NUL
if errorlevel 1 (
    %EXEC_CMD% ...
) else (
    @echo not starting %EXEC_CMD%: already running.
)

Как уже было сказано, для этого требуются административные привилегии.

6
ответ дан Community 1 September 2018 в 04:11
поделиться
  • 1
    @Sebastian: Здесь добавлена ​​небольшая дополнительная информация, поэтому я склонен оставить это в качестве ответа. – Bill the Lizard 16 October 2010 в 04:55
  • 2
    не работает для меня, и я использую учетную запись администратора. Появится окно DOS с Node - (computer name) ERROR: Description = Invalid query – khaverim 12 May 2014 в 20:14
  • 3
    Это работает для Win 2008. +1 для Нет задач, которые соответствуют указанным критериям. – Mangesh Pimpalkar 10 December 2014 в 02:04
  • 4
    Для меня все отлично. – Mark Duncan 6 March 2015 в 13:57

Просто отметив, что если ваше имя задачи действительно длинное, то оно не будет отображаться полностью в результате tasklist, поэтому может быть безопаснее (кроме локализации) проверять обратное.

Вариация этого ответа :

:: in case your task name is really long, check for the 'opposite' and find  the message when it's not there
tasklist /fi "imagename eq yourreallylongtasknamethatwontfitinthelist.exe" 2>NUL | find /I /N "no tasks are running">NUL
if "%errorlevel%"=="0" (
    echo Task Found
) else (
    echo Not Found Task
)
1
ответ дан drzaus 1 September 2018 в 04:11
поделиться

Ответ TrueY казался самым изящным решением, однако мне пришлось немного поработать, потому что я не понимал, что именно происходит. Позвольте мне прояснить ситуацию, надеюсь, сэкономить некоторое время для следующего человека.

Изменено TrueY Ответ:

::Change the name of notepad.exe to the process .exe that you're trying to track
::Process names are CASE SENSITIVE, so notepad.exe works but Notepad.exe does NOT
::Do not change IMAGENAME
::You can Copy and Paste this into an empty batch file and change the name of
::notepad.exe to the process you'd like to track
::Also, some large programs take a while to no longer show as not running, so
::give this batch a few seconds timer to avoid a false result!!

@echo off
SETLOCAL EnableExtensions

set EXE=notepad.exe

FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% goto ProcessFound

goto ProcessNotFound

:ProcessFound

echo %EXE% is running
goto END
:ProcessNotFound
echo %EXE% is not running
goto END
:END
echo Finished!

В любом случае, я надеюсь, что это поможет. Я знаю, что иногда чтение партии / командной строки может иногда немного сбивать с толку, если вы новичок, как я.

8
ответ дан kayleeFrye_onDeck 1 September 2018 в 04:11
поделиться

Я не знаю, как это сделать со встроенным CMD, но если у вас есть grep , вы можете попробовать следующее:

tasklist /FI "IMAGENAME eq myApp.exe" | grep myApp.exe
if ERRORLEVEL 1 echo "myApp is not running"
2
ответ дан Motti 1 September 2018 в 04:11
поделиться
  • 1
    см. мой ответ выше, который решает все это из DOS. – Matt Lacey 2 October 2008 в 14:52

Я предполагаю окна здесь. Таким образом, вам понадобится использовать WMI для получения этой информации. Ознакомьтесь с архивами Scripting Guy для большого количества примеров того, как использовать WMI из сценария.

0
ответ дан NotMe 1 September 2018 в 04:11
поделиться
  • 1
    есть окна. Если pos, я бы хотел сделать это в DOS, а не в VBScript. – Matt Lacey 2 October 2008 в 14:39

Мне нравятся инструменты WMIC и TASKLIST, но они недоступны в домашних / базовых версиях окон. Другой способ - использовать команду QPROCESS, доступную почти на всех машинах Windows (для тех, которые имеют терминальные службы - Я думаю, что только выиграть XP без SP2, так что практически каждый компьютер Windows):

@echo off
:check_process
setlocal
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running
set process_to_check=%~1
:: QPROCESS can display only the first 12 symbols of the running process
:: If other tool is used the line bellow could be deleted
set process_to_check=%process_to_check:~0,12%

QPROCESS * | find /i "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)
endlocal

QPROCESS команда не так сильна, как TASKLIST и ограничена показом только 12 символов имени процесса, но следует учитывать, если TASKLIST недоступен.

Более простое использование, когда оно использует имя, если процесс как аргумент (суффикс .exe является обязательным в этот случай, когда вы передаете исполняемое имя):

@echo off
:check_process
setlocal
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running
:: .exe suffix is mandatory
set "process_to_check=%~1"


QPROCESS "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)
endlocal

Различие между двумя способами использования QPROCESS заключается в том, что QPROCESS * отобразит все процессы, в то время как QPROCESS some.exe будет фильтровать только процессы для текущий пользователь.

Использование WMI объектов через Windows-скрипт host exe вместо WMIC также является опцией. Он должен также запускаться на всех машинах Windows (исключая те, где отключен WSH но это редкий случай). Вот файл bat, который перечисляет все процессы через классы WMI и может использоваться вместо QPROCESS в приведенном выше скрипте (это гибрид jscript / bat и должен быть сохранен как .bat):

@if (@X)==(@Y) @end /* JSCRIPT COMMENT **


@echo off
cscript //E:JScript //nologo "%~f0"
exit /b

************** end of JSCRIPT COMMENT **/


var winmgmts = GetObject("winmgmts:\\\\.\\root\\cimv2");
var colProcess = winmgmts.ExecQuery("Select * from Win32_Process");
var processes =  new Enumerator(colProcess);
for (;!processes.atEnd();processes.moveNext()) {
    var process=processes.item();
    WScript.Echo( process.processID + "   " + process.Name );
}

И модификация, которая проверяет, запущен ли процесс:

@if (@X)==(@Y) @end /* JSCRIPT COMMENT **


@echo off
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running
set process_to_check=%~1

cscript //E:JScript //nologo "%~f0" | find /i "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)

exit /b

************** end of JSCRIPT COMMENT **/


var winmgmts = GetObject("winmgmts:\\\\.\\root\\cimv2");
var colProcess = winmgmts.ExecQuery("Select * from Win32_Process");
var processes =  new Enumerator(colProcess);
for (;!processes.atEnd();processes.moveNext()) {
    var process=processes.item();
    WScript.Echo( process.processID + "   " + process.Name );
}

Эти два параметра можно использовать на машинах, у которых нет TASKLIST.

Конечная техника использует MSHTA. Это будет работать на всех машинах Windows с XP и выше и не зависит от настроек хоста Windows Script. вызов MSHTA мог бы немного снизить производительность (опять же нужно сохранить как bat):

@if (@X)==(@Y) @end /* JSCRIPT COMMENT **
@echo off

setlocal
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running

set process_to_check=%~1


mshta "about:<script language='javascript' src='file://%~dpnxf0'></script>" | find /i "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)
endlocal
exit /b
************** end of JSCRIPT COMMENT **/


   var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);


   var winmgmts = GetObject("winmgmts:\\\\.\\root\\cimv2");
   var colProcess = winmgmts.ExecQuery("Select * from Win32_Process");
   var processes =  new Enumerator(colProcess);
   for (;!processes.atEnd();processes.moveNext()) {
    var process=processes.item();
    fso.Write( process.processID + "   " + process.Name + "\n");
   }
   close();
3
ответ дан npocmaka 1 September 2018 в 04:11
поделиться

Вы должны проверить имя родительского процесса, см. статью Code Project о решении, основанном на .NET ** .

Непрограммный способ проверить:

  1. Запустить Cmd.exe
  2. Запустить приложение (например, c:\windows\notepad.exe)
  3. Проверить свойства Notepad.exe процесс в Process & nbsp; Explorer
  4. Проверить родительский процесс (это показывает cmd.exe)

То же самое можно проверить, получив родительский имя процесса.

58
ответ дан Peter Mortensen 1 September 2018 в 04:11
поделиться
  • 1
    Это работает для меня, на XP. Не проверял ничего другого. – Matt Lacey 2 October 2008 в 14:53
  • 2
    Изменение формата списка задач в CSV или что-либо, кроме таблицы, важно, потому что его макет (таблица) по умолчанию для списка задач обрезает длинные имена изображений, что ломает логику. – kibbled_bits 22 June 2011 в 15:56
  • 3
    Это решение не будет работать на Vista, потому что TASKLIST производит некоторый вывод, даже если процесс не найден. Я полагаю, что то же самое верно для Windows 7. – dbenham 28 January 2012 в 18:39
  • 4
    Другие решения работают без временного файла. – Denis Howe 10 March 2018 в 12:22
  • 5
    не работает в Windows 10. search.log содержит & INFO: никаких задач не выполняется, которые соответствуют указанным критериям. & quot; и никакой блокнот не запускается – Sergey 30 May 2018 в 08:21

Еще одна возможность, с которой я столкнулся, с помощью grep :

tasklist /FI "IMAGENAME eq myapp.exe" 2>NUL | find /I /N "myapp.exe">NUL
if "%ERRORLEVEL%"=="0" echo Program is running

Не нужно сохранять дополнительный файл, поэтому я предпочитаю этот метод .

280
ответ дан pkamb 1 September 2018 в 04:11
поделиться
  • 1
    это отлично сработало для меня (Windows XP SP3). IMHO это самый элегантный способ для всех предлагаемых здесь, используя только инструменты, поставляемые с окнами – hello_earth 8 July 2010 в 16:30
  • 2
    У меня была синтаксическая проблема с этой командной строкой. Я изменил его на tasklist /FI "IMAGENAME eq winword.exe" 2>NUL | find /I /N "winword.exe">NUL / if %ERRORLEVEL%==1 goto wordnotrunning, чтобы заставить его работать (подозревая, что цитата вокруг частей if – Steve B 19 October 2011 в 08:17
  • 3
    Помните, что в версиях XP на других языках имена фильтров были переведены в код, но не на экран /?. Так, например, IMAGENAME в польской версии NAZWA_OBRAZU. – rsk82 30 November 2012 в 17:44
  • 4
    В Win7 мне пришлось изменить его на tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL. Первый NUL кажется ненужным, я понятия не имею, что такое «2», / NH является необязательным. – Jan Doggen 8 November 2013 в 11:17
  • 5
    tasklist всегда выходит со статусом 0 независимо от того, найдет ли он какие-либо совпадающие задачи, поэтому он бесполезен сам по себе. Поскольку в любом случае вы должны использовать find (или findstr), чтобы проверить его вывод, нет смысла использовать фильтры списка задач. Просто выполните список задач | найти "myprog.exe & quot; & gt; nul: & amp; & amp; goto foundit или somesuch. Вам может понадобиться параметр / v (verbose) для списка задач. – Denis Howe 7 June 2014 в 13:32

Я обычно выполняю следующую команду в приглашении cmd, чтобы проверить, работает ли мой program.exe или нет:

tasklist | grep program
0
ответ дан Rajeev Jayaswal 1 September 2018 в 04:11
поделиться
TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"
3
ответ дан Riccardo La Marca 1 September 2018 в 04:11
поделиться

Мне нравится решение Chaosmaster! Но я искал решение, которое не запускает другую внешнюю программу (например, find.exe или findstr.exe ). Поэтому я добавил идею из решения Мэтта Лэйси, которая создает также предотвращаемый файл temp. В конце я смог найти довольно простое решение, поэтому я поделился им ...

SETLOCAL EnableExtensions
set EXE=myprog.exe
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% goto FOUND
echo Not running
goto FIN
:FOUND
echo Running
:FIN

Это работает для меня красиво ...

34
ответ дан TrueY 1 September 2018 в 04:11
поделиться
  • 1
    Это решение хорошо протестировано в Windows 8.1. Я заметил, что он чувствителен к регистру. – oliver-clare 2 December 2014 в 12:18
  • 2
    @LordScree Поскольку я работаю над системой un * x, чувствительность к регистру подходит для меня! Я даже установил файловую систему, чтобы разрешать имена файлов, чувствительных к регистру. ;) – TrueY 2 December 2014 в 13:42
  • 3
    Хорошо работает для меня - проверен в Windows 7 X64 – Mr Rubix 15 March 2016 в 19:21
  • 4
    подтвердить сервер 2008 и Windows 10 отлично работает – CWilson 25 November 2016 в 14:50

Я использую PV.exe из http://www.teamcti.com/pview/prcview.htm , установленного в Program Files \ PV, с таким пакетным файлом:

@echo off
PATH=%PATH%;%PROGRAMFILES%\PV;%PROGRAMFILES%\YourProgram
PV.EXE YourProgram.exe >nul
if ERRORLEVEL 1 goto Process_NotFound
:Process_Found
echo YourProgram is running
goto END
:Process_NotFound
echo YourProgram is not running
YourProgram.exe
goto END
:END
8
ответ дан user 1 September 2018 в 04:11
поделиться
  • 1
    это работает для меня на Windows 7. Вторая строка - это каталог, содержащий программу, а не саму программу. – Fabio Cionini 16 April 2012 в 22:23

В Windows вы можете использовать инструментарий управления Windows (WMI), чтобы гарантировать, что приложения с указанной командной строкой не запущены, например:

wmic process where (name="nmake.exe") get commandline | findstr /i /c:"/f load.mak" /c:"/f build.mak" > NUL && (echo THE BUILD HAS BEEN STARTED ALREADY! > %ALREADY_STARTED% & exit /b 1)

20
ответ дан vtrz 1 September 2018 в 04:11
поделиться
  • 1
    Обратите внимание, что WMIC требует административных привилегий; если у вас его нет, тогда Only the administrator group members can use WMIC.EXE., а затем Reason:Win32 Error: Access is denied. – Jeroen Wiert Pluimers 14 February 2012 в 11:48
  • 2
    Я думаю, что это лучшее решение, потому что wmic дает вам полную командную строку, запущенную и milion другую информацию ... – Glavić 23 May 2012 в 16:42
Другие вопросы по тегам:

Похожие вопросы: