كيف يمكنني الحصول على 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

نصائح أخرى

باستخدام إجابة Brian R. Bondy كدليل ، وكذلك ما هو موجود على 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 إلى الطفل عند إطلاق العملية.

تحقق من عضو Th32ParentProcessid من تعداد CreateToolHelp32Snapshot.

للحصول على مثال على كيفية القيام بذلك انظر رسالتي هنا.

نظرًا لأنك تستخدم C# على الرغم من أنك ستحتاج إلى استخدام Dllimports. في المنشور المرتبط ، توجد صفحات MSDN لكل الوظائف التي تحتاجها. في الجزء السفلي من كل صفحة MSDN لديهم رمز Dllimport لـ C#.

هناك أيضا طريقة أسهل باستخدام المدارة رمز فقط ولكنه لا يعمل إذا كان لديك أكثر من اسم عملية تبدأ من خلال تطبيقات مختلفة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top