<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=512748</guid>
        <pubDate>Tue, 16 Nov 2004 02:09:36 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=512748</link>
        <description><![CDATA[ufo_: попробую - tnx.]]></description>
        <author>ufo_</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=512434</guid>
        <pubDate>Mon, 15 Nov 2004 15:48:02 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=512434</link>
        <description><![CDATA[MARcoDEN: Попробуй это  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">HANDLE PHandle;</div><div class="code_line">PROCESSENTRY32 ProcEntry;</div><div class="code_line">BOOL Result;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;PHandle = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS,0);</div><div class="code_line">&nbsp;ProcEntry.dwSize = sizeof(PROCESSENTRY32);</div><div class="code_line">&nbsp;if (!Process32First(PHandle, &amp;ProcEntry))</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp;if (ExtractFileName(ProcEntry.szExeFile) == &quot;PROG_NAME.exe&quot;) Result = true;</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;while(Process32Next(PHandle, &amp;ProcEntry))</div><div class="code_line">&nbsp;&nbsp;if (ExtractFileName(ProcEntry.szExeFile) == &quot;PROG_NAME.exe&quot;) Result = true;</div><div class="code_line">&nbsp;// анализ результата</div><div class="code_line">&nbsp;if (Result == true) MessageBox(0, &quot;У вас запущен PROG_NAME.&quot;, &quot;Внимание&quot;, MB_OK);</div><div class="code_line">&nbsp;Application-&#62;Terminate();</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>]]></description>
        <author>MARcoDEN</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=511150</guid>
        <pubDate>Sun, 14 Nov 2004 13:08:27 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=511150</link>
        <description><![CDATA[ufo_: P.S материал из ФАКа не работает - точнее нахождение PID&#39;a по имени. <br>Работает через раз...]]></description>
        <author>ufo_</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507831</guid>
        <pubDate>Thu, 11 Nov 2004 06:58:40 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507831</link>
        <description><![CDATA[ufo_: Спасиюо всем]]></description>
        <author>ufo_</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507396</guid>
        <pubDate>Wed, 10 Nov 2004 15:17:53 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507396</link>
        <description><![CDATA[p_kolya: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Как узнать запущен ли процесс с определенным именем?<br>
Как убить процесс с определенным именем? </div></div><br>
В FAQ по билдеру это есть&#33;<br>
http:///sources.ru/builder/faq/058.html - сначала узнай pid процесса<br>
http:///sources.ru/builder/faq/063.html - а потом уже убей его&#33;<br>
Думаю разберешься :) &quot;Определенное имя&quot; - это обычно название exe-файла.]]></description>
        <author>p_kolya</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507165</guid>
        <pubDate>Wed, 10 Nov 2004 11:36:01 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507165</link>
        <description><![CDATA[Song: <div class="tag-mod"><div class="tag-mod__prefix">M</div><div class="tag-mod__body">Используем тег &#91;code&#93; для добавление текста программы в пост! Устное предупреждение! Читаем <a class='tag-url' href='http&#58;//forum.sources.ru/rules.html' target='_blank'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="red" style="color&#58; red">правила</span></strong></a>!</div></div>]]></description>
        <author>Song</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507145</guid>
        <pubDate>Wed, 10 Nov 2004 11:18:45 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=507145</link>
        <description><![CDATA[Olega: <a class='tag-url' href='http://jtsoftik.narod.ru/builder/num115.html' target='_blank'>Snapshot</a><br>
<a class='tag-url' href='http://rosigma.boom.ru/richter/head6.htm' target='_blank'>Threads</a> <br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2004-11-10T11:21:08+00:00">10.11.04, 11:21</time></span></span><br>
Хорошая статья была в инете, сейчас оно не доступна.<br>
<br>
Функция TerminateProcess<br>
Для принудительного и безоговорочного завершения процессов в Win32 служит функция TerminateProcess: <br>
<br>
BOOL TerminateProcess(<br>
    IN HANDLE hProcess,	    // описатель процесса<br>
    IN DWORD dwExitCode	    // код завершения процесса<br>
    );<br>
<br>
 <br>
<br>
Сейчас я обязан сделать <br>
<br>
ПРЕДУПРЕЖДЕНИЕ<br>
Функцию TerminateProcess следует использовать только в исключительных случаях, когда исчерпаны все другие способы воздействия на процесс, поскольку она не позволяет потокам процесса выполнить очистку или сохранить данные, а также не оповещает загруженные DLL о завершении процесса.  <br>
<br>
Я уверен, что это предупреждение вас не остановит. Для того, чтобы воспользоваться функцией TerminateProcess, необходимо получить описатель (handle) процесса. Зная идентификатор процесса, это несложно сделать c помощью функции OpenProcess, в итоге функция принудительного завершения процесса может выглядеть, например, так: <br>
<br>
BOOL KillProcess(<br>
    IN DWORD dwProcessId<br>
    )<br>
{<br>
    // получаем описатель процесса<br>
    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);<br>
    if (hProcess == NULL)<br>
        return FALSE;<br>
<br>
    DWORD dwError = ERROR_SUCCESS;<br>
<br>
    // пытаемся завершить процесс<br>
    if (&#33;TerminateProcess(hProcess, (DWORD)-1))<br>
        dwError = GetLastError();<br>
<br>
    // закрываем описатель процесса<br>
    CloseHandle(hProcess);<br>
<br>
    SetLastError(dwError);<br>
    return dwError == ERROR_SUCCESS;<br>
}<br>
<br>
 <br>
<br>
Завершение процессов и система безопасности Windows NT<br>
Если вы воспользуетесь функцией KillProcess, то обнаружите, что хотя она замечательно работает в Windows 95/98, в Windows NT она не может завершить некоторые процессы, потому что OpenProcess возвращает ошибку ERROR_ACCESS_DENIED. В частности, это происходит при попытке остановить процессы системных служб и некоторых DCOM-серверов. Как вы наверное уже догадываетесь, все дело в правах доступа. <br>
<br>
Как и любой объект ядра, объект процесса защищен дескриптором безопасности, который проверяется всякий раз, когда открывается описатель процесса. Для разных видов процессов дескриптор безопасности инициализируется по-разному. Вы можете воспользоваться тестовой программой Process Viewer для изучения дескрипторов безопасности процессов. Так, вы можете обнаружить, что дескриптор безопасности для интерактивных процессов выглядит так: <br>
<br>
Интерактивный пользователь Полный доступ <br>
СИСТЕМА Полный доступ <br>
<br>
в то время как для системных служб, работающих в контексте системной логон-сессии, дескриптор безопасности выглядит иначе: <br>
<br>
Администраторы Чтение <br>
СИСТЕМА Полный доступ <br>
<br>
Теперь ясно, почему OpenProcess не позволяет открыть описатель процесса системной службы с правами PROCESS_TERMINATE, даже если вызывающий пользователь является администратором компьютера. Это может показаться странным, почему администратор компьютера не может остановить любой процесс в системе. На самом деле, такая возможность у него есть, и заключается она в наличии привилегии SE_DEBUG_NAME. <br>
<br>
Все привилегии, которые имеет пользователь, могут находиться в двух состояниях: выключенном, неактивном, и включенном, активном состоянии. Администраторы компьютера имеют привилегию SE_DEBUG_NAME, но по умолчанию она находится в выключенном состоянии и не оказывает влияния на работу OpenProcess. Когда эта привилегия включена, вызывающий поток может открывать описатели процессов с любыми правами доступа, вне зависимости от того, какой дескриптор безопасности назначен объекту процесса. Это как раз то, что нам нужно. <br>
<br>
Ниже приведен модифицированный код функции KillProcess, которая при необходимости включает привилегию SE_DEBUG_NAME, чтобы получить описатель процесса. <br>
<br>
BOOL KillProcess(<br>
    IN DWORD dwProcessId<br>
    )<br>
{<br>
    HANDLE hProcess;<br>
    DWORD dwError;<br>
<br>
    // сначала попробуем получить описатель процесса без <br>
    // использования дополнительных привилегий<br>
    hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);<br>
    if (hProcess == NULL)<br>
    {<br>
        if (GetLastError() &#33;= ERROR_ACCESS_DENIED)<br>
            return FALSE;<br>
<br>
        OSVERSIONINFO osvi;<br>
<br>
        // определяем версию операционной системы<br>
        osvi.dwOSVersionInfoSize = sizeof(osvi);<br>
        GetVersionEx(&amp;osvi);<br>
<br>
        // мы больше ничего не можем сделать, если это не Windows NT<br>
        if (osvi.dwPlatformId &#33;= VER_PLATFORM_WIN32_NT)<br>
            return SetLastError(ERROR_ACCESS_DENIED), FALSE;<br>
<br>
        // включим привилегию SE_DEBUG_NAME и попробуем еще раз<br>
<br>
        TOKEN_PRIVILEGES Priv, PrivOld;<br>
        DWORD cbPriv = sizeof(PrivOld);<br>
        HANDLE hToken;<br>
<br>
        // получаем токен текущего потока <br>
        if (&#33;OpenThreadToken(GetCurrentThread(), <br>
                             TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,<br>
                             FALSE, &amp;hToken))<br>
        {<br>
            if (GetLastError() &#33;= ERROR_NO_TOKEN)<br>
                return FALSE;<br>
<br>
            // используем токен процесса, если потоку не назначено<br>
	    // никакого токена<br>
            if (&#33;OpenProcessToken(GetCurrentProcess(),<br>
                                  TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,<br>
                                  &amp;hToken))<br>
                return FALSE;<br>
        }<br>
<br>
        _ASSERTE(ANYSIZE_ARRAY &gt; 0);<br>
<br>
        Priv.PrivilegeCount = 1;<br>
        Priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;<br>
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &amp;Priv.Privileges[0].Luid);<br>
<br>
        // попробуем включить привилегию<br>
        if (&#33;AdjustTokenPrivileges(hToken, FALSE, &amp;Priv, sizeof(Priv),<br>
                                   &amp;PrivOld, &amp;cbPriv))<br>
        {<br>
            dwError = GetLastError();<br>
            CloseHandle(hToken);<br>
            return SetLastError(dwError), FALSE;<br>
        }<br>
<br>
        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)<br>
        {<br>
            // привилегия SE_DEBUG_NAME отсутствует в токене<br>
            // вызывающего<br>
            CloseHandle(hToken);<br>
            return SetLastError(ERROR_ACCESS_DENIED), FALSE;<br>
        }<br>
<br>
        // попробуем открыть описатель процесса еще раз<br>
        hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);<br>
        dwError = GetLastError();<br>
        <br>
        // восстанавливаем исходное состояние привилегии<br>
        AdjustTokenPrivileges(hToken, FALSE, &amp;PrivOld, sizeof(PrivOld),<br>
                              NULL, NULL);<br>
        CloseHandle(hToken);<br>
<br>
        if (hProcess == NULL)<br>
            return SetLastError(FALSE), NULL;<br>
    }<br>
<br>
    // пытаемся завершить процесс<br>
    if (&#33;TerminateProcess(hProcess, (UINT)-1))<br>
    {<br>
        dwError = GetLastError();<br>
        CloseHandle(hProcess);<br>
        return SetLastError(dwError), FALSE;<br>
    }<br>
<br>
    CloseHandle(hProcess);<br>
<br>
    // успешное завершение<br>
    return TRUE;<br>
}<br>
<br>
 <br>
<br>
Модифицированный вариант функции KillProcess сначала пытается открыть описатель процесса без использования привилегии SE_DEBUG_NAME. Если это у него не получается, он включает привилегию, получает описатель процесса и затем восстанавливает привилегию в исходное состояние. <br>
<br>
Теперь с помощью функции KillProcess можно убить практически любой процесс в системе, если, конечно, вы являетесь администратором компьютера. Чтобы проверить новый вариант функции в деле, вы можете воспользоваться тестовым приложением Process Viewer, которое теперь умеет завершать процессы. Например, можно остановить процесс Winlogon и через несколько секунд увидеть синий экран с надписью STOP 0xC000021A (не забудьте сохранить все открытые документы, прежде чем это сделать). <br>
<br>
Завершение дерева процессов<br>
Некоторое время назад мой коллега по работе попросил меня написать утилиту, аналогичную утилите kill в Unix. Он занимался переносом каких-то скриптов из Unix на Windows NT и ему нужна была такая утилита. Использовать утилиту, поставляемую в составе Windows NT Resource Kit, он не мог по лицензионным (а может, и религиозным) соображениям. <br>
<br>
Я быстро оформил функцию KillProcess в виде небольшого консольного приложения и отправил ему. Коллега был приятно удивлен скорости, с которой я выполнил его просьбу, однако он отметил, что моя версия kill работает не так, как аналог из Unix. В Unix, kill завершает не только сам процесс, но и все дочерние процессы, которые были запущены из него прямо или косвенно (так называемое дерево процессов). Моя же версия работала как kill -9, когда завершается только указанный процесс. Таким образом, встала задача повторить поведение Unix kill на Windows NT. <br>
<br>
Чтобы завершить все процессы в дереве, необходимо каким-либо образом отследить отношения родитель - потомок между процессами. В Windows 9x/Me и Windows 2000/XP это позволяют сделать функции перечисления процессов из ToolHelp32 API, в частности поле th32ParentProcessID структуры PROCESSENTRY32 содержит идентификатор родительского процесса. В Windows NT 4.0 эту информацию можно получить с помощью официально недокументированной функции ZwQuerySystemInformation. (Подробнее о функциях перечисления процессов рассказано в статье Как получить список запущенных процессов?) <br>
<br>
Ниже приведен код функции KillProcessEx, которая позволяет завершать как отдельный процесс, так и целое дерево процессов. Если вы читали статью про перечисление процессов, то найдете много знакомых кусков кода в этой функции. <br>
<br>
// вспомогательная функция, которая рекурсивно обходит дерево процессов<br>
// в Windows NT и завершает все процессы в дереве<br>
static<br>
BOOL KillProcessTreeNtHelper(<br>
    IN PSYSTEM_PROCESSES pInfo,<br>
    IN DWORD dwProcessId<br>
    )<br>
{<br>
    _ASSERTE(pInfo &#33;= NULL);<br>
<br>
    PSYSTEM_PROCESSES p = pInfo;<br>
<br>
    // сначала завершаем все дочерние процессы<br>
    for (;;)<br>
    {<br>
        if (p-&gt;InheritedFromProcessId == dwProcessId)<br>
            KillProcessTreeNtHelper(pInfo, p-&gt;ProcessId);<br>
<br>
        if (p-&gt;NextEntryDelta == 0)<br>
            break;<br>
<br>
        // находим адрес следующей структуры<br>
        p = (PSYSTEM_PROCESSES)(((LPBYTE)p) + p-&gt;NextEntryDelta);<br>
    }<br>
<br>
    // завершаем исходный процесс<br>
    if (&#33;KillProcess(dwProcessId))<br>
        return GetLastError();<br>
<br>
    return ERROR_SUCCESS;<br>
}<br>
<br>
// вспомогательная функция, которая рекурсивно обходит дерево процессов<br>
// в Windows 9x и завершает все процессы в дереве<br>
static<br>
BOOL KillProcessTreeWinHelper(<br>
    IN DWORD dwProcessId<br>
    )<br>
{<br>
    HINSTANCE hKernel;<br>
    HANDLE (WINAPI * _CreateToolhelp32Snapshot)(DWORD, DWORD);<br>
    BOOL (WINAPI * _Process32First)(HANDLE, PROCESSENTRY32 *);<br>
    BOOL (WINAPI * _Process32Next)(HANDLE, PROCESSENTRY32 *);<br>
<br>
    // получаем описатель KERNEL32.DLL<br>
    hKernel = GetModuleHandle(_T(&quot;kernel32.dll&quot;));<br>
    _ASSERTE(hKernel &#33;= NULL);<br>
<br>
    // находим необходимые функции KERNEL32.DLL<br>
    *(FARPROC *)&amp;_CreateToolhelp32Snapshot =<br>
        GetProcAddress(hKernel, &quot;CreateToolhelp32Snapshot&quot;);<br>
    *(FARPROC *)&amp;_Process32First =<br>
        GetProcAddress(hKernel, &quot;Process32First&quot;);<br>
    *(FARPROC *)&amp;_Process32Next =<br>
        GetProcAddress(hKernel, &quot;Process32Next&quot;);<br>
<br>
    if (_CreateToolhelp32Snapshot == NULL ||<br>
        _Process32First == NULL ||<br>
        _Process32Next == NULL)<br>
        return ERROR_PROC_NOT_FOUND;<br>
<br>
    HANDLE hSnapshot;<br>
    PROCESSENTRY32 Entry;<br>
<br>
    // создаем моментальный снимок процессов<br>
    hSnapshot = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);<br>
    if (hSnapshot == INVALID_HANDLE_VALUE)<br>
        return GetLastError();<br>
<br>
    Entry.dwSize = sizeof(Entry);<br>
    if (&#33;_Process32First(hSnapshot, &amp;Entry))<br>
    {<br>
        DWORD dwError = GetLastError();<br>
        CloseHandle(hSnapshot);<br>
        return dwError;<br>
    }<br>
<br>
    // завершаем сначала дочерние процессы<br>
    do<br>
    {<br>
        if (Entry.th32ParentProcessID == dwProcessId)<br>
            KillProcessTreeWinHelper(Entry.th32ProcessID);<br>
<br>
        Entry.dwSize = sizeof(Entry);<br>
    }<br>
    while (_Process32Next(hSnapshot, &amp;Entry));<br>
<br>
    CloseHandle(hSnapshot);<br>
<br>
    // завершаем исходный процесс<br>
    if (&#33;KillProcess(dwProcessId))<br>
        return GetLastError();<br>
<br>
    return ERROR_SUCCESS;<br>
}<br>
<br>
BOOL KillProcessEx(<br>
    IN DWORD dwProcessId,   // идентификатор процесса<br>
    IN BOOL bTree           // признак завершения всего дерева<br>
    )<br>
{<br>
    if (&#33;bTree)<br>
        return KillProcess(dwProcessId);<br>
<br>
    OSVERSIONINFO osvi;<br>
    DWORD dwError;<br>
<br>
    // определяем версию операционной системы<br>
    osvi.dwOSVersionInfoSize = sizeof(osvi);<br>
    GetVersionEx(&amp;osvi);<br>
<br>
    if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)<br>
    {<br>
        HINSTANCE hNtDll;<br>
        NTSTATUS (WINAPI * _ZwQuerySystemInformation)(UINT, PVOID, ULONG, PULONG);<br>
<br>
        // получаем описатель NTDLL.DLL<br>
        hNtDll = GetModuleHandle(_T(&quot;ntdll.dll&quot;));<br>
        _ASSERTE(hNtDll &#33;= NULL);<br>
<br>
        // находим адрес ZwQuerySystemInformation<br>
        *(FARPROC *)&amp;_ZwQuerySystemInformation =<br>
            GetProcAddress(hNtDll, &quot;ZwQuerySystemInformation&quot;);<br>
        if (_ZwQuerySystemInformation == NULL)<br>
            return SetLastError(ERROR_PROC_NOT_FOUND), NULL;<br>
<br>
        // получаем описатель кучи процесса по умолчанию<br>
        HANDLE hHeap = GetProcessHeap();<br>
    <br>
        NTSTATUS Status;<br>
        ULONG cbBuffer = 0x8000;<br>
        PVOID pBuffer = NULL;<br>
<br>
	// трудно заранее определить, какой размер выходного<br>
	// буфера будет достаточным, поэтому мы начинам с буфера<br>
	// размером 32K и увеличиваем его по необходимости<br>
        do<br>
        {<br>
            pBuffer = HeapAlloc(hHeap, 0, cbBuffer);<br>
            if (pBuffer == NULL)<br>
                return SetLastError(ERROR_NOT_ENOUGH_MEMORY), FALSE;<br>
<br>
            Status = _ZwQuerySystemInformation(<br>
                            SystemProcessesAndThreadsInformation,<br>
                            pBuffer, cbBuffer, NULL);<br>
<br>
            if (Status == STATUS_INFO_LENGTH_MISMATCH)<br>
            {<br>
                HeapFree(hHeap, 0, pBuffer);<br>
                cbBuffer *= 2;<br>
            }<br>
            else if (&#33;NT_SUCCESS(Status))<br>
            {<br>
                HeapFree(hHeap, 0, pBuffer);<br>
                return SetLastError(Status), NULL;<br>
            }<br>
        }<br>
        while (Status == STATUS_INFO_LENGTH_MISMATCH);<br>
<br>
        // вызываем вспомогательную функцию<br>
        dwError = KillProcessTreeNtHelper((PSYSTEM_PROCESSES)pBuffer, <br>
                                          dwProcessId);<br>
        <br>
        HeapFree(hHeap, 0, pBuffer);<br>
    }<br>
    else<br>
    {<br>
        // вызываем вспомогательную функцию<br>
        dwError = KillProcessTreeWinHelper(dwProcessId);<br>
    }<br>
<br>
    SetLastError(dwError);<br>
    return dwError == ERROR_SUCCESS;<br>
}<br>
<br>
 <br>
<br>
Используя функцию KillProcessEx, я смог написать утилиту PKILL, которая более точно соответствует своему Unix-аналогу. Эта утилита прилагается в качестве тестового приложения к данной статье. <br>
<br>
Завершение 16-битных задач в Windows NT<br>
Рассмотрение вопроса о завершении процессов не будет полным, если мы не затронем тему 16-битных задач на Windows NT. Для завершения 16-битных задач VDMDBG.DLL предоставляет функцию VDMTerminateTaskWOW: <br>
<br>
BOOL VDMTerminateTaskWOW(<br>
    IN DWORD dwProcessId,   // идентификатор виртуальной DOS-машины<br>
    IN WORD hTask16	    // идентификатор 16-битной задачи<br>
    );<br>
<br>
 <br>
<br>
Параметры этой функции говорят сами за себя. Тестовое приложение Process Viewer использует ее для завершения 16-битных задач на Windows NT.<br>
<br>
Заключение<br>
Таким образом, теперь вы во всеоружии готовы завершить любой процесс. Но, как и всякое оружие, используйте возможность принудительного завершения процессов с осторожностью.]]></description>
        <author>Olega</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=506891</guid>
        <pubDate>Wed, 10 Nov 2004 07:55:31 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=506891</link>
        <description><![CDATA[TarasCo: Для NT:<br>EnumProcesses<br>OpenProcess<br>EnumProcessModules ( модуль процесса - первый в списке)<br><br>Убить процесс:<br>TerminateProcess]]></description>
        <author>TarasCo</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=506872</guid>
        <pubDate>Wed, 10 Nov 2004 07:42:10 +0000</pubDate>
        <title>Работа с процессами</title>
        <link>https://forum.sources.ru/index.php?showtopic=72137&amp;view=findpost&amp;p=506872</link>
        <description><![CDATA[ufo_: Как узнать запущен ли процесс с определенным именем?<br>Как убить процесс с определенным именем?]]></description>
        <author>ufo_</author>
        <category>Borland C++ Builder/Turbo C++ Explorer</category>
      </item>
	
      </channel>
      </rss>
	