Home All Groups Group Topic Archive Search About

Find all child processes

Author
16 Oct 2005 12:23 PM
Markus Walther
Hi!

I need a vb6 application to be able to list all processes and the processes'
child processes (their PIDs).

For example, if cmd.exe has been run from the vb6 app, and notepad has been
run from the cmd.exe, I need to list the PIDs of both cmd and notepad.

This, in order to be able to kill all processes and child processes started
by the vb6 app.

markus

Author
16 Oct 2005 6:20 PM
Tom Esh
On Sun, 16 Oct 2005 14:23:21 +0200, "Markus Walther"
<markuswalther@community.nospam> wrote:

>I need a vb6 application to be able to list all processes and the processes'
>child processes (their PIDs).
>
>For example, if cmd.exe has been run from the vb6 app, and notepad has been
>run from the cmd.exe, I need to list the PIDs of both cmd and notepad.
>
>This, in order to be able to kill all processes and child processes started
>by the vb6 app.

Have a look at these Toolhelp Api functions to enumerate processes:
    CreateToolhelp32Snapshot
    Process32First
    Process32Next

The parent PID is returned as one of the members of the PROCESSENTRY32
structure.

There's an example here:
http://vbnet.mvps.org/code/system/getparentprocess.htm


Note however the parent PID will be that of the VB app only if VB's
Shell function or the CreateProcess Api function was used to start it.
(If for example you used ShellExecute instead, it would be that of the
shell itself.)
Also note using the PID to kill a process (OpenProcess,
TerminateProcess) is recommended only as a last resort. Much better
(to start with at least) to post a WM_CLOSE message to the app's main
window and allow it to shutdown normally.


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
16 Oct 2005 7:50 PM
Markus Walther
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:9m55l19crh3jv3isr7smt27as50q58bqto@4ax.com...

> Have a look at these Toolhelp Api functions to enumerate processes:
> CreateToolhelp32Snapshot
> Process32First
> Process32Next
>
> The parent PID is returned as one of the members of the PROCESSENTRY32
> structure.
>
> There's an example here:
> http://vbnet.mvps.org/code/system/getparentprocess.htm

Thanks Tom!
Can you give me some more information on how to find the parent PIDs?

I made a tiny vb app using the example code, but I'm stuck on how do find
the parent PIDs.

markus
Author
17 Oct 2005 7:48 PM
Someone
Check this article. It works for Windows 9x and NT.

How To List Running Processes
http://support.microsoft.com/default.aspx?scid=kb;en-us;187913

> I made a tiny vb app using the example code, but I'm stuck on how do find
> the parent PIDs.

Use:

If proc.th32ParentProcessID = MyProcessId Then
    Form1.List1.AddItem TrimNull(proc.szExeFile) & ", PID: " &
proc.th32ProcessID & ", Parent PID: " & proc.th32ParentProcessID
End If

TrimNull function can be found here:

http://vbnet.mvps.org/index.html?code/core/trimnull.htm

Note that Process32First/Process32Next works with Windows 9x and 2000+. NT4
is not supported by it. For NT4, use EnumProcesses, but I don't know how to
get the parent process ID if you used that one.


Show quoteHide quote
"Markus Walther" <markuswalther@community.nospam> wrote in message
news:Oa7xwro0FHA.2880@TK2MSFTNGP12.phx.gbl...
> "Tom Esh" <tjeshGibber***@suscom.net> wrote in message
> news:9m55l19crh3jv3isr7smt27as50q58bqto@4ax.com...
>
>> Have a look at these Toolhelp Api functions to enumerate processes:
>> CreateToolhelp32Snapshot
>> Process32First
>> Process32Next
>>
>> The parent PID is returned as one of the members of the PROCESSENTRY32
>> structure.
>>
>> There's an example here:
>> http://vbnet.mvps.org/code/system/getparentprocess.htm
>
> Thanks Tom!
> Can you give me some more information on how to find the parent PIDs?
>
> I made a tiny vb app using the example code, but I'm stuck on how do find
> the parent PIDs.
>
> markus
>
Author
17 Oct 2005 8:44 PM
Karl E. Peterson
Markus Walther wrote:
> Can you give me some more information on how to find the parent PIDs?
>
> I made a tiny vb app using the example code, but I'm stuck on how do
> find the parent PIDs.

I have routines in http://vb.mvps.org/samples/Console for this.

The "short story" <g> is:

   Private Function GetProcessParent() As String
      ' *** Added at v1.01 (entire routine) ***
      Dim ProcessID As Long
      Dim os As OSVERSIONINFO
      Dim hProcess As Long
      Dim info As PROCESS_BASIC_INFORMATION
      Dim Buffer As String
      Dim hSnap As Long
      Dim ProcEntry As PROCESSENTRY32
      Dim nRet As Long

      Const STATUS_SUCCESS As Long = 0

      ' Windows 2000+ and Windows 9x ship with the
      ' ToolHelp routines, so we only need to use
      ' NTDLL on NT4 and lower.
      os.dwOSVersionInfoSize = Len(os)
      Call GetVersionEx(os)

      ' We are after the parent of *this* process.
      ProcessID = GetCurrentProcessId()

      If m_Compiled = False Then
         ' If uncompiled, we are running under the VB IDE process.
         ' Return full name/path and current process ID.
         GetProcessParent = GetProcessFileName(0&)
         m_ParentProcessID = ProcessID

      ElseIf os.dwPlatformId = VER_PLATFORM_WIN32_NT And os.dwMajorVersion < 5 Then
         ' *** Use undocumented calls only when needed. ***
         ' This is a version of NT prior to Win2000!
         ' Make sure we have the needed function.
         If Exported("ntdll", "NtQueryInformationProcess") Then
            ' Obtain a handle to the current process.
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0,
ProcessID)
            If hProcess Then
               nRet = NtQueryInformationProcess(hProcess, SystemBasicInformation,
info, Len(info), ByVal 0&)
               If nRet = STATUS_SUCCESS Then
                  m_ParentProcessID = info.InheritedFromUniqueProcessId
               End If
               ' Done with this process.
               Call CloseHandle(hProcess)
            End If
            ' Return results.
            GetProcessParent = GetProcessFileName(m_ParentProcessID)
         End If

      Else
         ' Use the documented methods...
         ' Make sure we have the needed function.
         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
         If hSnap Then
            ProcEntry.dwSize = Len(ProcEntry)

            ' Iterate through the processes once to find the parent:
            If Process32First(hSnap, ProcEntry) Then
               Do
                  If ProcEntry.th32ProcessID = ProcessID Then
                     ' This is us.  Get the parent ID:
                     m_ParentProcessID = ProcEntry.th32ParentProcessID
                     Exit Do
                  End If
               Loop While Process32Next(hSnap, ProcEntry)
            End If

            ' Now get the parent name.
            If os.dwPlatformId = VER_PLATFORM_WIN32_NT Then
               ' Newer NT version toolhelp libraries do not
               ' provide path information, so it's better to
               ' use GetModuleFileNameEx for max info.
               GetProcessParent = GetProcessFileName(m_ParentProcessID)
            Else
               ' In Win9x versions, iterate the process snapshot. Again.
               If Process32First(hSnap, ProcEntry) Then
                  Do
                     If ProcEntry.th32ProcessID = m_ParentProcessID Then
                        ' This is the parent process -- get its filename.
                        GetProcessParent = TrimNull(ProcEntry.szExeFile)
                        Exit Do
                     End If
                  Loop While Process32Next(hSnap, ProcEntry)
               End If
            End If

         End If
      End If
   End Function

Although this function returns a string (the parent process's filename), you'll be
most interested in the m_ParentProcessID variable.

Later...   Karl
--
Working Without a .NET?
http://classicvb.org/petition
Author
19 Oct 2005 9:32 PM
Markus Walther
"Karl E. Peterson" <k***@mvps.org> wrote in message
news:%23XfcYu10FHA.1264@tk2msftngp13.phx.gbl...
> Markus Walther wrote:
>> Can you give me some more information on how to find the parent PIDs?
>>
>> I made a tiny vb app using the example code, but I'm stuck on how do
>> find the parent PIDs.
>
> I have routines in http://vb.mvps.org/samples/Console for this.
>
> The "short story" <g> is:
> [...]


I'm not looking for the parent-PID of my vbapp's process. I'm looking for
the PIDs of every process that is originating from my vb app. :/

But thanks for the effort anyway =)

markus
Author
19 Oct 2005 9:40 PM
Karl E. Peterson
Markus Walther wrote:
Show quoteHide quote
> "Karl E. Peterson" <k***@mvps.org> wrote in message
> news:%23XfcYu10FHA.1264@tk2msftngp13.phx.gbl...
>> Markus Walther wrote:
>>> Can you give me some more information on how to find the parent
>>> PIDs?
>>>
>>> I made a tiny vb app using the example code, but I'm stuck on how do
>>> find the parent PIDs.
>>
>> I have routines in http://vb.mvps.org/samples/Console for this.
>>
>> The "short story" <g> is:
>> [...]
>
>
> I'm not looking for the parent-PID of my vbapp's process. I'm looking
> for the PIDs of every process that is originating from my vb app. :/
>
> But thanks for the effort anyway =)

All you need to change (perhaps pass it as a parameter), in that case, is this:

      ' We are after the parent of this process.
      ProcessID = GetCurrentProcessId()

You can obtain that ProcessID in many different ways, of course.  It really depends
on your goals.  But once you have a process in hand, you'd use the techniques I
showed you to find its parent process.

Later...   Karl
--
Working Without a .NET?
http://classicvb.org/petition
Author
16 Oct 2005 7:53 PM
Markus Walther
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:9m55l19crh3jv3isr7smt27as50q58bqto@4ax.com...

> The parent PID is returned as one of the members of the PROCESSENTRY32
> structure.

Isn't the PROCESSENTRY32 only used on 95/98?
I need this to work on NT (only).

markus
Author
16 Oct 2005 8:13 PM
Tom Esh
On Sun, 16 Oct 2005 21:53:57 +0200, "Markus Walther"
<markuswalther@community.nospam> wrote:

>Isn't the PROCESSENTRY32 only used on 95/98?
>I need this to work on NT (only).

It works in XP too, but yeah, not NT.
In NT you would use the psapi functions (EnumProcesses, etc.) to get
the PIDs, but I don't see a way to grab parent PID. Maybe someone else
can offer a clue on this.


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
17 Oct 2005 7:11 PM
Markus Walther
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:bcc5l1lpjgl01pehpeoka291ff9rephbm8@4ax.com...
> It works in XP too, but yeah, not NT.

Actually NT is what I meant :) But no, when I run the code in my sample app
it uses the "NT CODE", not the 95/98 code.

markus
Author
17 Oct 2005 7:33 PM
Randy Birch
It's up to you to determine the OS version when the app is run, and branch
to the appropriate set of routines for that OS.  See
http://vbnet.mvps.org/code/helpers/iswinversion.htm

--

Randy Birch
MS MVP Visual Basic
http://vbnet.mvps.org/

----------------------------------------------------------------------------
Read. Decide. Sign the petition to Microsoft.
http://classicvb.org/petition/
----------------------------------------------------------------------------


Show quoteHide quote
"Markus Walther" <markuswalther@community.nospam> wrote in message
news:eoJwm600FHA.736@tk2msftngp13.phx.gbl...
: "Tom Esh" <tjeshGibber***@suscom.net> wrote in message
: news:bcc5l1lpjgl01pehpeoka291ff9rephbm8@4ax.com...
: > It works in XP too, but yeah, not NT.
:
: Actually NT is what I meant :) But no, when I run the code in my sample
app
: it uses the "NT CODE", not the 95/98 code.
:
: markus
:
:
Author
18 Oct 2005 6:35 AM
Markus Walther
"Randy Birch" <rgb_removet***@mvps.org> wrote in message
news:%23nRq1G10FHA.1264@tk2msftngp13.phx.gbl...
> It's up to you to determine the OS version when the app is run, and branch
> to the appropriate set of routines for that OS.  See
> http://vbnet.mvps.org/code/helpers/iswinversion.htm

Yes,thanks. I forced it to use the "95-98" code on my xp system, and that
worked well.
Thanks again.

markus
Author
18 Oct 2005 9:28 PM
Markus Walther
"Markus Walther" <markuswalther@community.nospam> wrote in message
news:%238Vxb460FHA.448@TK2MSFTNGP09.phx.gbl...
> "Randy Birch" <rgb_removet***@mvps.org> wrote in message
> news:%23nRq1G10FHA.1264@tk2msftngp13.phx.gbl...
>> It's up to you to determine the OS version when the app is run, and
>> branch
>> to the appropriate set of routines for that OS.  See
>> http://vbnet.mvps.org/code/helpers/iswinversion.htm
>
> Yes,thanks. I forced it to use the "95-98" code on my xp system, and that
> worked well.

Hmm not so well. This is a bit complicated. Is there an easier way to do
this? Maybe there is a magic function out there somewhere?

The reason I want to do this is because I have an "admin application" that
runs stuff in administrator context while one is logged in as a regular user
(kind of like runas). When this admin application is closed, I want
everything that is run from the app to be closed as well.

markus
Author
18 Oct 2005 9:58 PM
Tom Esh
On Tue, 18 Oct 2005 23:28:59 +0200, "Markus Walther"
<markuswalther@community.nospam> wrote:

>Hmm not so well. This is a bit complicated. Is there an easier way to do
>this? Maybe there is a magic function out there somewhere?

There is ...but we're keeping it secret just to torment you :-)

Seriously, no magic bullet for this.

>The reason I want to do this is because I have an "admin application" that
>runs stuff in administrator context while one is logged in as a regular user
>(kind of like runas). When this admin application is closed, I want
>everything that is run from the app to be closed as well.

Have you considered keeping track of the PIDs or the hwnd of the
launched apps main windows ~as~ they're launched. You could sfuff 'em
in a collection and just iterate through it when closing. Keeping the
hwnd would simplify posting WM_CLOSE. Plus if need be you can easily
obtain the PID from the hwnd with GetWindowThreadProcessID.


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
19 Oct 2005 1:19 PM
Markus Walther
Show quote Hide quote
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:mfral11m6kju14a51799pnc81qdrctb3n8@4ax.com...
> On Tue, 18 Oct 2005 23:28:59 +0200, "Markus Walther"
> <markuswalther@community.nospam> wrote:
>
>>Hmm not so well. This is a bit complicated. Is there an easier way to do
>>this? Maybe there is a magic function out there somewhere?
>
> There is ...but we're keeping it secret just to torment you :-)
>
> Seriously, no magic bullet for this.

:-)

> Have you considered keeping track of the PIDs or the hwnd of the
> launched apps main windows ~as~ they're launched. You could sfuff 'em
> in a collection and just iterate through it when closing.

Yes - thats just what I am doing. The problem is cmd.exe for example, which
can be run in admin context through my vb app. I would like to be able to
shut down any apps started from the cmd.exe as well - not just the cmd.exe.

markus