Как программно можно проверить нужный мне процесс, является ли он системным ?
Ответ Если приложение запускается с правами администратора, можно воспользоваться Restart Manager API: using System using System.Collections.Generic using System.ComponentModel using System.Runtime.InteropServices using System.Text using System.Diagnostics using System.Windows.Forms namespace WindowsFormsTest1 { public partial class Form1 : Form { [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)] public static extern UInt32 RmStartSession(out UInt32 pSessionHandle, UInt32 dwSessionFlags, string strSessionKey) [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)] public static extern UInt32 RmRegisterResources(UInt32 dwSessionHandle, UInt32 nFiles, string[] rgsFilenames, UInt32 nApplications, ref RM_UNIQUE_PROCESS rgApplications, UInt32 nServices, string[] rgsServiceNames) [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)] public static extern UInt32 RmGetList(UInt32 dwSessionHandle, out UInt32 pnProcInfoNeeded, ref UInt32 pnProcInfo, [In, Out] RM_PROCESS_INFO[] rgAffectedApps, ref UInt32 lpdwRebootReasons) [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)] public static extern UInt32 RmEndSession(UInt32 dwSessionHandle) public const UInt32 RmRebootReasonNone = 0x0 public const int ERROR_MORE_DATA = 234 /// /// Преобразование DateTime в структуру FILETIME /// public static System.Runtime.InteropServices.ComTypes.FILETIME FileTimeFromDateTime(DateTime date) { long ftime = date.ToFileTime() System.Runtime.InteropServices.ComTypes.FILETIME ft = new System.Runtime.InteropServices.ComTypes.FILETIME() ft.dwHighDateTime = (int)(ftime >> 32) ft.dwLowDateTime = (int)ftime return ft } /// /// Получение типа процесса /// public static RM_APP_TYPE GetProcessType(Process proc) { uint handle string key = Guid.NewGuid().ToString() uint res = RmStartSession(out handle, (uint)0, key) if (res != 0) { throw new ApplicationException("Could not begin restart session. ") } try { uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone RM_UNIQUE_PROCESS uniqueprocess = new RM_UNIQUE_PROCESS() uniqueprocess.dwProcessId = proc.Id System.Runtime.InteropServices.ComTypes.FILETIME ft = FileTimeFromDateTime(proc.StartTime) uniqueprocess.ProcessStartTime = ft res = RmRegisterResources(handle, 0, null, 1, ref uniqueprocess, 0, null) if (res != 0) { throw new ApplicationException("Could not register resource.") } res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons) if (res == ERROR_MORE_DATA) { RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded] pnProcInfo = pnProcInfoNeeded // Get the list. res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons) if (res == 0) { if (pnProcInfo == 0) throw new ApplicationException("Process not found") return processInfo[0].ApplicationType } else { throw new ApplicationException("Could not list processes") } } else if (res != 0) { throw new ApplicationException("Failed to get size of result.") } } finally { RmEndSession(handle) } throw new ApplicationException("Process not found") } public Form1() { InitializeComponent() } private void button1_Click(object sender, EventArgs e) { //пример использования Process p=Process.GetProcessesByName(textBox1.Text)[0] MessageBox.Show(GetProcessType(p).ToString()) /*Для системных процессов выведет RmCritical*/ } } /* Определения структур */ [StructLayout(LayoutKind.Sequential)] public struct RM_UNIQUE_PROCESS { // The product identifier (PID). public int dwProcessId // The creation time of the process. public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct RM_PROCESS_INFO { const int CCH_RM_MAX_APP_NAME = 255 const int CCH_RM_MAX_SVC_NAME = 63 // Contains an RM_UNIQUE_PROCESS structure that uniquely identifies the // application by its PID and the time the process began. public RM_UNIQUE_PROCESS Process [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)] // If the process is a service, this parameter returns the // long name for the service. public string strAppName [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)] // If the process is a service, this is the short name for the service. public string strServiceShortName // Contains an RM_APP_TYPE enumeration value. public RM_APP_TYPE ApplicationType // Contains a bit mask that describes the current status of the application. public uint AppStatus // Contains the Terminal Services session ID of the process. public uint TSSessionId // TRUE if the application can be restarted by the // Restart Manager otherwise, FALSE. [MarshalAs(UnmanagedType.Bool)] public bool bRestartable } public enum RM_APP_TYPE { // The application cannot be classified as any other type. RmUnknownApp = 0, // A Windows application run as a stand-alone process that // displays a top-level window. RmMainWindow = 1, // A Windows application that does not run as a stand-alone // process and does not display a top-level window. RmOtherWindow = 2, // The application is a Windows service. RmService = 3, // The application is Windows Explorer. RmExplorer = 4, // The application is a stand-alone console application. RmConsole = 5, // A system restart is required to complete the installation because // a process cannot be shut down. RmCritical = 1000 } } Код основан на данном примере: https://code.msdn.microsoft.com/windowsapps/How-to-know-the-process-704839f4 Метод GetProcessType возвращает тип процесса, для системных процессов он равен значению RM_APP_TYPE.RmCritical. Если приложение не имеет прав администратора, все проще: попытка получить дескриптор системного процесса просто упадет с ошибкой "Отказано в доступе". Нужно лишь ловить Win32Exception.
Другие способы С использованием (нерекомендуемой) функции NtQueryInformationProcess из Native API: const uint ProcessBreakOnTermination = 29 [DllImport("NTDLL.DLL")] static extern int NtQueryInformationProcess(IntPtr hProcess, uint pic, ref uint pi, int cb, out int pSize) public static bool IsProcessCritical(Process pr) { uint val = 0 int size int res = NtQueryInformationProcess(pr.Handle, ProcessBreakOnTermination, ref val, sizeof(uint), out size) if (res != 0 || size != sizeof(uint)) throw new Win32Exception("NtQueryInformationProcess failed") return (val != 0) } Начиная с Windows 8.1 можно использовать функцию IsProcessCritical - пример.