I don't see why you don't want to p/invoke. If you look at System.Diagnostics in Reflector, you'll see that it uses p/invokes internally. Anyway, the Process class does not have a way of retrieving a process' parent PID. Instead:
The struct definition:
[StructLayout(LayoutKind.Sequential)]
struct PROCESS_BASIC_INFORMATION
{
public int ExitStatus;
public int PebBaseAddress;
public int AffinityMask;
public int BasePriority;
public int UniqueProcessId;
public int InheritedFromUniqueProcessId;
}
The (simplified) function import:
[DllImport("ntdll.dll")]
static extern int NtQueryInformationProcess(
IntPtr ProcessHandle,
int ProcessInformationClass,
out PROCESS_BASIC_INFORMATION ProcessInformation,
int ProcessInformationLength,
out int ReturnLength
);
The code:
Process p = Process.GetProcessById(1234);
PROCESS_BASIC_INFORMATION pbi;
int size;
NtQueryInformationProcess(p.Handle, 0, out pbi, Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)), out size);
// pbi.InheritedFromUniqueProcessId now contains the process' parent PID
You'll need to insert these usings at the top of your file:
using System.Runtime.InteropServices;
using System.Diagnostics;
If you want to enumerate processes, you'd be better off using NtQuerySystemInformation - although that code is a bit too long to post here.