Как я могу получить PID родительского процесса моего приложения
Мое приложение winform запускается другим приложением (родителем), мне нужно определить pid приложения, которое запускает мое приложение с помощью c #.
- Скрыть вкладку Заголовок на C # TabControl
- Как обнаружить, что код C # Windows Forms выполняется в Visual Studio?
- Модель-View-Presenter в WinForms
- Invoke или BeginInvoke нельзя вызвать в элементе управления до тех пор, пока дескриптор windows не будет создан
- MVVM для winforms
- Ключевые события: ProcessCmdKey
- В чем разница между Application.ThreadException и AppDomain.CurrentDomain.UnhandledException?
- Автоматическая настройка winform и элементов управления размером экрана
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, и некоторый вывод Reflector, я создал это для использования в 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 #.
Существует также более простой способ использования управляемого кода, но он не работает, если у вас есть несколько имен процессов, запущенных различными приложениями.