Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / September 2005

Tip: Looking for answers? Try searching our database.

Has anyone PInvoked the Toolhelp32 functions?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Thomas W. Brown - 07 Sep 2005 18:10 GMT
I'm trying to use the Toolhelp32 functions to enumerate processes,
specifically because I need to get the Parent Process ID of a specific
process (to know who launched it).

The CreateToolhelp32Snapshot call does not fail (does not return an
INVALID_HANDLE_VALUE), but the call to Process32First returns false.  I'm
calling the first as

  CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

in order to enumerate all processes.

Any pointers, tricks, tips, etc?
Thanks,
-- Tom
Robert Jordan - 07 Sep 2005 19:16 GMT
Hi Thomas,

> I'm trying to use the Toolhelp32 functions to enumerate processes,
> specifically because I need to get the Parent Process ID of a specific
[quoted text clipped - 9 lines]
>
> Any pointers, tricks, tips, etc?

Are your p/invoke declarations correct? Especially the
PROCESSENTRY32 struct? Have a look at:

http://www.pinvoke.net/default.aspx/kernel32.CreateToolhelp32Snapshot
http://www.pinvoke.net/default.aspx/kernel32.Process32First
http://www.pinvoke.net/default.aspx/kernel32.Process32Next

Rob
Thomas W. Brown - 07 Sep 2005 20:06 GMT
> Hi Thomas,
>
[quoted text clipped - 18 lines]
> http://www.pinvoke.net/default.aspx/kernel32.Process32First
> http://www.pinvoke.net/default.aspx/kernel32.Process32Next

Yes, thanks -- I got them from pinvoke.com.  Just to double check, I've
pasted from my source below.  There is one thing I wasn't sure of and have
added in my code -- that is the dwSize field of the PROCESS32 structure...  
All the MS documentation for the PlatformSDK shows this field filled out with
the actual size of the struct prior to calling Process32First...  I've tried
it without and with to no effect.

Anyway, here is my code...

using System;
using System.Runtime.InteropServices;

namespace ToolHelpTest
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESSENTRY32
        {
            public uint        dwSize;
            public uint        cntUsage;
            public uint        th32ProcessID;
            public IntPtr    th32DefaultHeapID;
            public uint        th32ModuleID;
            public uint        cntThreads;
            public uint        th32ParentProcessID;
            public int        pcPriClassBase;
            public uint        dwFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public string
szExeFile;
        }

        public static uint PROCESS32SIZE = (uint)IntPtr.Size + (8 * 4) + 256;

        public class CreateToolhelp32SnapshotFlags
        {
            public const uint TH32CS_SNAPHEAPLIST = 0x00000001;
            public const uint TH32CS_SNAPPROCESS  = 0x00000002;
            public const uint TH32CS_SNAPTHREAD   = 0x00000004;
            public const uint TH32CS_SNAPMODULE   = 0x00000008;
            public const uint TH32CS_SNAPMODULE32 = 0x00000010;
            public const uint TH32CS_SNAPALL      = (TH32CS_SNAPHEAPLIST |
TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE);
            public const uint TH32CS_INHERIT      = 0x80000000;
        }

        [DllImport("KERNEL32.DLL", SetLastError=true)]
        public extern static IntPtr CreateToolhelp32Snapshot(UInt32 flags, UInt32
pid);

        [DllImport("KERNEL32.DLL")]
        public extern static bool Process32First(IntPtr snapshot, ref
PROCESSENTRY32 proc);

        [DllImport("KERNEL32.DLL")]
        public extern static bool Process32Next(IntPtr snapshot, ref
PROCESSENTRY32 proc);

        [DllImport("KERNEL32.DLL")]
        public extern static uint GetLastError();

        [DllImport("KERNEL32.DLL")]
        public extern static bool CloseHandle(IntPtr handle);

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            IntPtr snapshot =
CreateToolhelp32Snapshot(CreateToolhelp32SnapshotFlags.TH32CS_SNAPPROCESS, 0);
            if ((int)snapshot == -1)
            {
                UInt32 err = GetLastError();
                Console.WriteLine("Unable to get Toolhelp32 snapshot, err = {0}", err);
            }

            PROCESSENTRY32 p32 = new PROCESSENTRY32();
            p32.dwSize = PROCESS32SIZE;
            Console.WriteLine("snapshot = 0x{0:08x}, PROCESS32SIZE = {1}",
(int)snapshot, p32.dwSize);

            bool moreProcesses = Process32First(snapshot, ref p32);
            Console.WriteLine("{0,-32}  {1,5}  {2,5}", "Filename", "PID", "Parent");
            Console.WriteLine("================================================");
            while (moreProcesses)
            {
                Console.WriteLine("{0,-32}  {1,5}  {2,5}", p32.szExeFile,
p32.th32ProcessID, p32.th32ParentProcessID);
                moreProcesses = Process32Next(snapshot, ref p32);
            }

            CloseHandle(snapshot);
            Console.WriteLine("done");
            Console.WriteLine();
            Console.WriteLine("Press [ENTER] to finish...");
            Console.ReadLine();
        }
    }
}

This produces output like this (the value of the snapshot IntPtr changes, of
course):

snapshot = 0x3008x, PROCESS32SIZE = 292
Filename                            PID  Parent
================================================
done

Press [ENTER] to finish...
Thomas W. Brown - 07 Sep 2005 20:16 GMT
> > Hi Thomas,
> >
[quoted text clipped - 27 lines]
>
> Anyway, here is my code...

[ snip]

Found it -- it turns out that setting dwSize *is* necessary and I had gotten
it wrong -- I was adding 256 for the szExeFile instead of 512 (they are
TCHARs).

Thanks,
-- Tom
Robert Jordan - 07 Sep 2005 20:31 GMT
Hi Thomas,

comments inside

>>Hi Thomas,
>>
[quoted text clipped - 25 lines]
> the actual size of the struct prior to calling Process32First...  I've tried
> it without and with to no effect.

Marshal.SizeOf (typeof (PROCESSENTRY32));

> Anyway, here is my code...
>
[quoted text clipped - 22 lines]
>             [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public string
> szExeFile;

These 2 fields seem to be necessary for XP SP2:

                        uint th32MemoryBase;
                        uint th32AccessKey;

>         }
>
[quoted text clipped - 46 lines]
>             PROCESSENTRY32 p32 = new PROCESSENTRY32();
>             p32.dwSize = PROCESS32SIZE;

p32.dwSize = (uint) Marshal.SizeOf (typeof(PROCESSENTRY32));

>             Console.WriteLine("snapshot = 0x{0:08x}, PROCESS32SIZE = {1}",
> (int)snapshot, p32.dwSize);
[quoted text clipped - 27 lines]
>
> Press [ENTER] to finish...
Willy Denoyette [MVP] - 07 Sep 2005 19:37 GMT
> I'm trying to use the Toolhelp32 functions to enumerate processes,
> specifically because I need to get the Parent Process ID of a specific
[quoted text clipped - 11 lines]
> Thanks,
> -- Tom

Use System.Management and WMI for this, it's much easier and less error
prone.

using System;
using System.Management;
using System.Diagnostics;
public class Tester{
public static void Main() {
    Process p = Process.GetCurrentProcess();
    int parentPid = GetParentProcess(p.Id);
    Console.WriteLine(parentPid);
}
static int GetParentProcess(int Id)
{
     int parentPid=0;
     using(ManagementObject mo = new
ManagementObject("win32_process.handle='" + Id.ToString() + "'"))
     {
          mo.Get();
          parentPid = Convert.ToInt32(mo["ParentProcessId"]);
     }
     return parentPid;
}

Willy.
Thomas W. Brown - 07 Sep 2005 20:17 GMT
> > I'm trying to use the Toolhelp32 functions to enumerate processes,
> > specifically because I need to get the Parent Process ID of a specific
[quoted text clipped - 37 lines]
>
> Willy.

Ah, excellent -- I will try that immediately!!  Thanks.

-- Tom

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.