Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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)]