как проверить, запущен ли процесс через пакетный скрипт

<p>как я могу проверить, запущено ли приложение из пакетного (хорошо cmd) файла?</p><p>мне не нужно запускать другой экземпляр, если программа уже запущена. (я не могу изменить приложение, чтобы сделать его только один экземпляр.)</p><p>также приложение может работать как любой пользователь.</p>

<p>еще одна возможность, которую я придумал, вдохновленная использованием <a href="http://en.wikipedia.org/wiki/grep">grep</a> , это:</p><pre><code>tasklist /fi "imagename eq myapp.exe" 2>nul | find /i /n "myapp.exe">nul if "%errorlevel%"=="0" echo program is running </code></pre><p>для этого не нужно сохранять дополнительный файл, поэтому я предпочитаю этот метод.</p>

<p>вот как я это сделал:</p><pre><code>tasklist /fi "imagename eq notepad.exe" /fo csv > search.log for /f %%a in (search.log) do if %%~za equ 0 goto end start notepad.exe :end del search.log </code></pre><p>выше откроется <a href="http://en.wikipedia.org/wiki/notepad\_%28software%29">блокнот</a> , если он еще не запущен.</p><p>правка: обратите внимание, что это не найдет приложения, скрытые от списка задач. это будет включать любые запланированные задачи, выполняемые от имени другого пользователя, поскольку они автоматически скрываются.</p>

<p>мне нравится решение chaosmaster! но я искал решение, которое не запускает другую внешнюю программу (например, <a href="https://technet.microsoft.com/en-us/library/bb490906.aspx">find.exe</a> или <a href="https://technet.microsoft.com/en-us/library/bb490907.aspx">findstr.exe</a> ). поэтому я добавил идею из решения мэтта лейси, которая создает временный файл, которого можно избежать. в конце концов я смог найти довольно простое решение, поэтому я делюсь им ...</p><pre><code>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 </code></pre><p>это хорошо работает для меня ...</p>

<p>в windows вы можете использовать инструментарий управления windows (wmi), чтобы убедиться, что не запущены приложения с указанной командной строкой, например:</p><p><code>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)</code></p>

<p>предложение npocmaka использовать qprocess вместо tasklist велико, но его ответ настолько велик и сложен, что я чувствую себя обязанным опубликовать его довольно упрощенную версию, которая, я думаю, решит проблему большинства неопытных пользователей:</p><pre><code>qprocess "myprocess.exe">nul if %errorlevel% equ 0 echo "process running" </code></pre><p>приведенный выше код был протестирован в windows 7 с пользователем с правами администратора.</p>

<p>ответ truey показался мне самым элегантным решением, однако мне пришлось немного повозиться, потому что я не понимал, что именно происходит. позвольте мне все прояснить, чтобы сэкономить время для следующего человека.</p><p>измененный ответ truey:</p><pre><code>::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! </code></pre><p>во всяком случае, я надеюсь, что это помогает. я знаю, что иногда чтение пакетной/командной строки может сбивать с толку, если вы новичок, как я.</p>

<p>я использую pv.exe из <a href="http://www.teamcti.com/pview/prcview.htm">http://www.teamcti.com/pview/prcview.htm</a> установленный в program files\pv с командным файлом, подобным этому:</p><pre><code>@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 </code></pre>

<p> <a href="https://stackoverflow.com/questions/162291/how-to-check-if-a-process-is-running-via-a-batch-script/162361#162361">ответ предоставлен мэттом лэйси</a> работает для windows xp. однако в windows server 2003 строка</p><pre><code> tasklist /fi "imagename eq notepad.exe" /fo csv > search.log </code></pre><p>возвращается</p><blockquote> <p>информация: не выполняются задачи, соответствующие указанным критериям.</p> </blockquote><p>который затем читается при запуске процесса.</p><p>у меня нет опыта работы с пакетными сценариями, поэтому мое решение состоит в том, чтобы затем искать имя процесса в файле <code>search.log</code> и закачивать результаты в другой файл и искать его для любого вывода.</p><pre><code>tasklist /fi "imagename eq notepad.exe" /fo csv > search.log findstr notepad.exe search.log > found.log for /f %%a in (found.log) do if %%~za equ 0 goto end start notepad.exe :end del search.log del found.log </code></pre><p>я надеюсь, что это помогает кому-то еще.</p>

<pre><code>tasklist | findstr programname || start "" "path\programname.exe" </code></pre>

<p>я не знаю, как это сделать со встроенным cmd, но если у вас есть <a href="http://unxutils.sourceforge.net/">grep</a> , вы можете попробовать следующее:</p><pre><code>tasklist /fi "imagename eq myapp.exe" | grep myapp.exe if errorlevel 1 echo "myapp is not running" </code></pre>

<p>просто упомяните, что если имя вашей задачи действительно длинное, то оно не будет полностью отображаться в результате <code>tasklist</code>, поэтому может быть безопаснее (кроме локализации) проверить обратное.</p><p>вариация <a href="https://stackoverflow.com/a/1329790/1037948">этот ответ</a> :</p><pre><code>:: 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 ) </code></pre>

<p>я предполагаю, что окна здесь. итак, вам нужно использовать wmi, чтобы получить эту информацию. посмотрите в сценарии у сценариста <a href="http://www.microsoft.com/technet/scriptcenter/resources/qanda/hsgarch.mspx">архивы</a> много примеров того, как использовать wmi из скрипта.</p>

<p>я использовал <a href="https://stackoverflow.com/questions/162291/how-to-check-if-a-process-is-running-via-a-batch-script/162361#162361">скрипт предоставлен мэттом</a> (2008-10-02). единственное, с чем я столкнулся, было то, что он не удалял файл <code>search.log</code>. я ожидаю, потому что мне пришлось <code>cd</code> в другое место, чтобы запустить мою программу. я <code>cd</code> возвращаюсь туда, где находятся bat-файл и <code>search.log</code>, но он все равно не будет удален. поэтому я решил это, удалив файл <code>search.log</code> первым, а не последним.</p><pre><code>del search.log tasklist /fi "imagename eq myprog.exe" /fo csv > search.log for /f %%a in (search.log) do if %%-za equ 0 goto end cd "c:\program files\myloc\bin" myprog.exe myuser mypwd :end </code></pre>

<p>вы должны проверить имя родительского процесса, см. <a href="http://en.wikipedia.org/wiki/the\_code\_project">the code project</a> статью о <a href="http://www.codeproject.com/kb/cs/parentprocwindow.aspx">решение на основе .net **</a> .</p><p>непрограммный способ проверки:</p><ol> <li>запустите cmd.exe</li> <li>запустите приложение (например, <code>c:\windows\notepad.exe</code>)</li> <li>проверьте свойства процесса notepad.exe в <a href="http://en.wikipedia.org/wiki/process\_explorer">process explorer</a> </li> <li>проверьте родительский процесс (показывает cmd.exe)</li> </ol><p>то же самое можно проверить, получив имя родительского процесса.</p>