solution to getting the parent process
In case anyone was interested, I did end up figuring out how to get the parent process of a given process...here's the code I used to do it... just to make note of it, wttsvc is a test harness which launches my test processes, there will only be one of them. For this test example I had it launch notepad, and for use with this example it works perfectly fine unless there is more than one instance of notepad up and running. :)
class Program
{
static void Main(string[] args)
{
Process[] myProc = Process.GetProcessesByName("notepad");
Process[] wttProc = Process.GetProcessesByName("wttsvc");
PROCESSENTRY32 myProcEntry = new PROCESSENTRY32();
IntPtr handleToSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
try
{
if (Process32First(handleToSnapshot, myProcEntry))
{
if (myProc[0].Id == myProcEntry.ProcID && wttProc[0].Id == myProcEntry.ParentProcID)
{
Console.WriteLine("Process ID : {0}", myProcEntry.ProcID);
Console.WriteLine("Parent Process ID: {0}", myProcEntry.ParentProcID);
}
}
else
{
Console.WriteLine("Failed with Wind32 error code {0}", Marshal.GetLastWin32Error());
}
while (Process32Next(handleToSnapshot, myProcEntry))
{
if (myProc[0].Id == myProcEntry.ProcID && wttProc[0].Id == myProcEntry.ParentProcID)
{
Console.WriteLine("Process ID : {0}", myProcEntry.ProcID);
Console.WriteLine("Parent Process ID: {0}", myProcEntry.ParentProcID);
}
}
}
catch (System.IndexOutOfRangeException ex)
{
Console.WriteLine("Notepad or WTTSvc was not running. Exception message: {0}", ex.Message);
}
}
[DllImport("kernel32", SetLastError=true, CharSet=System.Runtime.InteropServices.CharSet.Auto)]
static extern IntPtr CreateToolhelp32Snapshot([In]UInt32 dwFlags, [In]UInt32 th32ProcessID);
[DllImport("kernel32", SetLastError = true, CharSet=System.Runtime.InteropServices.CharSet.Auto)]
static extern bool Process32First([In]IntPtr hSnapshot, [In, Out]PROCESSENTRY32 lppe);
[DllImport("kernel32", SetLastError = true, CharSet=System.Runtime.InteropServices.CharSet.Auto)]
static extern bool Process32Next([In]IntPtr hSnapshot, [In, Out]PROCESSENTRY32 lppe);
const UInt32 TH32CS_SNAPPROCESS = 0x00000002;
const int MAX_PATH = 260;
[StructLayout(LayoutKind.Sequential)]
class PROCESSENTRY32
{
UInt32 dwSize = (UInt32)Marshal.SizeOf(typeof(PROCESSENTRY32));
UInt32 cntUsage = 0;
UInt32 th32ProcessID = 0;
IntPtr th32DefaultHeapID = IntPtr.Zero;
UInt32 th32ModuleID = 0;
UInt32 cntThreads = 0;
UInt32 th32ParentProcessID = 0;
Int32 pcPriClassBase = 0;
UInt32 dwFlags = 0;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=MAX_PATH*sizeof(char))]
string szExeFile;
public UInt32 ProcID
{
get
{
return th32ProcessID;
}
}
public UInt32 ParentProcID
{
get
{
return th32ParentProcessID;
}
}
}
}
Comments
- Anonymous
July 21, 2005
Ah. That's much simpler than using WMI. ;-)
Here's a snippet of VB Script that does the same thing.
Set objWMIService = GetObject("winmgmts:.rootCIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name='notepad.exe'")
For Each objItem in colItems
WScript.Echo "Process ID: " & objItem.ProcessId
WScript.Echo "Parent Process ID: " & objItem.ParentProcessId
Next - Anonymous
July 25, 2005
definatly like the size of your solution better. If we weren't trying to avoid using WMI I would probably use it. ;) - Anonymous
April 14, 2007
The szExeFile member is marshalled incorrectly. You have to change [StructLayout(LayoutKind.Sequential)] into [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] and [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH * sizeof(char))] into [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]