Как я могу получить PID родительского процесса моего приложения

StackOverflow https://stackoverflow.com/questions/2531837

Вопрос

Мое приложение Winform запускается другим приложением (родительским), мне нужно определить PID приложения, запустив мое приложение, используя C#.

Это было полезно?

Решение

WMI - это более простой способ сделать это в C#. В классе Win32_Process есть свойство ParentProcessID. Вот пример:

using System;
using System.Management;  // <=== Add Reference required!!
using System.Diagnostics;

class Program {
    public static void Main() {
        var myId = Process.GetCurrentProcess().Id;
        var query = string.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId);
        var search = new ManagementObjectSearcher("root\\CIMV2", query);
        var results = search.Get().GetEnumerator();
        results.MoveNext();
        var queryObj = results.Current;
        var parentId = (uint)queryObj["ParentProcessId"];
        var parent = Process.GetProcessById((int)parentId);
        Console.WriteLine("I was started by {0}", parent.ProcessName);
        Console.ReadLine();
    }
}

Вывод при запуске из Visual Studio:

Меня начал Devenv

Другие советы

Используя ответ Брайана Р. Бонди в качестве руководства, а также то, что находится на pinvoke.net, и некоторые результаты отражателя, я произвел это, для использования в LinqPad MyExtensions:

public static int ParentProcessId(this Process process)
{
  return ParentProcessId(process.Id);
}
public static int ParentProcessId(int Id)
{
    PROCESSENTRY32 pe32 = new PROCESSENTRY32{};
    pe32.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32));
    using(var hSnapshot = CreateToolhelp32Snapshot(SnapshotFlags.Process, (uint)Id))
    {
        if(hSnapshot.IsInvalid)
            throw new Win32Exception();

        if(!Process32First(hSnapshot, ref pe32))
        {
            int errno = Marshal.GetLastWin32Error();
            if(errno == ERROR_NO_MORE_FILES)
                return -1;
            throw new Win32Exception(errno);
        }    
        do {
                if(pe32.th32ProcessID == (uint)Id)
                    return (int)pe32.th32ParentProcessID;
        } while(Process32Next(hSnapshot, ref pe32));
    }
    return -1;
}
private const int ERROR_NO_MORE_FILES = 0x12;
[DllImport("kernel32.dll", SetLastError=true)]
private static extern SafeSnapshotHandle CreateToolhelp32Snapshot(SnapshotFlags flags, uint id);
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool Process32First(SafeSnapshotHandle hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool Process32Next(SafeSnapshotHandle hSnapshot, ref PROCESSENTRY32 lppe);

[Flags]
private enum SnapshotFlags : uint
{
    HeapList = 0x00000001,
    Process  = 0x00000002,
    Thread   = 0x00000004,
    Module   = 0x00000008,
    Module32 = 0x00000010,
    All      = (HeapList | Process | Thread | Module),
    Inherit  = 0x80000000,
    NoHeaps  = 0x40000000
}
[StructLayout(LayoutKind.Sequential)]
private 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=260)] public string szExeFile; 
};
[SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort=true)]
internal sealed class SafeSnapshotHandle : SafeHandleMinusOneIsInvalid
{
    internal SafeSnapshotHandle() : base(true)
    {
    }

    [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)]
    internal SafeSnapshotHandle(IntPtr handle) : base(true)
    {
        base.SetHandle(handle);
    }

    protected override bool ReleaseHandle()
    {
        return CloseHandle(base.handle);
    }

    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true, ExactSpelling=true)]
    private static extern bool CloseHandle(IntPtr handle);
}

Если у вас есть контроль над родительским приложением, вы можете изменить родителя, чтобы передать свой PID ребенку при запуске процесса.

Проверьте член TH32PARENTPOCESSID в CreateToolHelp32SNAPSHOT Перечисление.

Для примера того, как это сделать Смотрите мой пост здесь.

Так как вы используете C#, хотя вам нужно использовать dllimports. В связанном посте есть страницы MSDN для каждого для необходимых вам функций. Внизу каждой страницы MSDN они имеют код для Dllimport для C#.

Есть также более простой способ использования управляемого Только код, но он не работает, если у вас есть более одного имени процесса, запущенное различными приложениями.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top