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;
/// <summary>
/// Преобразование DateTime в структуру FILETIME
/// </summary>
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;
}
/// <summary>
/// Получение типа процесса
/// </summary>
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
}
}
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);
}
public static List<KeyValuePair<int, string>> GetProcessExtraInformation(int processId)
{
// запрос получения всех процессов связанных с переданным идентификатором processId
string query = "Select * From Win32_Process Where ProcessID = " + processId;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
// здесь будет результат
List<KeyValuePair<int, string>> result = new List<KeyValuePair<int, string>>();
foreach (ManagementObject obj in processList)
{
var description = @"Не могу получить информацию о процессе";
// Получим описание процесса, если таковое имеется
if (obj["ExecutablePath"] != null)
{
try
{
FileVersionInfo info = FileVersionInfo.GetVersionInfo(obj["ExecutablePath"].ToString());
description = info.FileDescription;
}
catch { }
}
// Получить владельца процесса в argList
var owner = @"Не могу получить владельца процесса";
string[] argList = new string[] { string.Empty, string.Empty };
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
if (returnVal == 0)
{
owner = argList[1] + "\\" + argList[0]; // Домен и владелец
}
result.Add(new KeyValuePair<int, string>(processId, string.Format("Description: '{0}'\nOwner: '{1}'", description, owner)));
}
return result;
}
是的,让我们像这样重写初始代码:
Process[] processList = Process.GetProcesses();
foreach (Process process in processList)
{
// В process хранится информация о процессе
var processInfo = GetProcessExtraInformation(process.Id);
foreach (var info in processInfo)
{
Console.WriteLine(string.Format("Id: {0}\n{1}", info.Key, info.Value));
}
Console.WriteLine();
}
Console.ReadLine();
如果应用程序以管理员权限启动,您可以使用Restart Manager API:
基于此示例的代码:https ://code.msdn.microsoft.com/windowsapps/How-to-know-the-process-704839f4
该方法
GetProcessType返回进程类型,对于系统进程,它等于RM_APP_TYPE.RmCritical.如果应用程序没有管理员权限,事情就更简单了:尝试获取系统进程的句柄将简单地失败,并出现“拒绝访问”错误。你只需要抓住
Win32Exception。其他方法
使用 Native API 中的(已弃用)NtQueryInformationProcess函数:
从 Windows 8.1 开始,您可以使用IsProcessCritical函数-示例。
如果您打开任务管理器,您将看到进程的所有者=>遵循此答案
您可以通过 WMI 获取进程所有者:
这是一个比明确列出可以在安装期间添加特殊功能的系统进程更好的解决方案。组件 => 很难列出。
正如他们在评论中纠正我的那样,仍然有各种没有帐户的服务,还有一些系统帐户,例如 MS SQL 从特定帐户工作,如果我没记错的话。
让我们从我们将有一些关于进程的信息开始(不要忘记包含命名空间
using System.Diagnostics;):方法- 返回本地计算机上每个进程资源
GetProcesses的组件数组。Process实际上,进程Process有一个属性Id,其中包含关联进程的唯一标识符。执行此代码后,我们有了流程数据,我们可以继续进行另一部分,获取流程的描述和流程的所有者。
添加到程序集的链接
System.Management,单击项目,然后通过Add->Reference...选中该框并写入using System.Management;让我们编写这个方法:
是的,让我们像这样重写初始代码:
结果,我们得到这样的结果:
从源升级答案:如何确定 C# 中进程的所有者?并在结果中添加了一些细节。根据获得的数据,我们可以假设拥有SYSTEM-的进程是一个系统进程。此外,您应该注意域。
例如,您可以在此处阅读有关帐户和服务的信息:在使用启动帐户启动 SQL Server 服务部分中配置 Windows 服务帐户
如果我没记错的话,没有明确的方法可以确定一个进程是否是系统进程,但是您可以列出系统进程并检查条目。
这是我脑海中的一个列表: