none
如何区分系统进程和用户进程 RRS feed

  • 问题

  • 已取出当前所有的进程,但我想区分出哪些进程是系统的进程,哪些是用户程序的进程或非系统的应用程序的进程,需要如何区分呢?用WMI?谢谢!
    meerio
    2012年1月5日 15:48

答案

  • 目前我的想法是比較process的owner是否為登入者,如果是的話,就列出來!

    private void button1_Click(object sender, EventArgs e)
    {
    	//畫面上的listBox物件
    	listBox1.Items.Clear();
    	//取得目前登入者的資訊
    	string userName = Environment.UserDomainName + "\\" + Environment.UserName;
    	Process[] procList = Process.GetProcesses();
    	foreach (Process p in procList)
    	{
    		Application.DoEvents();
    		string processOwner = GetProcessOwner(p.Id);
    		//比較如果是目前登入者起的process就列出來
    		if (userName == processOwner)
    		{
    			listBox1.Items.Add(p.ProcessName );
    		}
    		
    	}
    }
    
    public string GetProcessOwner(int processId)
    {
    	string query = "Select * From Win32_Process Where ProcessID = " + processId;
    	ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
    	ManagementObjectCollection processList = searcher.Get();
    
    	foreach (ManagementObject obj in processList)
    	{
    		string[] argList = new string[] { string.Empty, string.Empty };
    		int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
    		if (returnVal == 0)
    		{
    			// return DOMAIN\user
    			return argList[1] + "\\" + argList[0];
    		}
    	}
    
    	return "NO OWNER";
    }
    
    
    



    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/
    • 已标记为答案 meerio 2012年1月7日 2:39
    2012年1月5日 22:23
  • 您好,我發現使用OpenProcessToken來check好像也可以! 請看一下以下的Code,謝謝!

    1.加入namespace

    using System.Runtime.InteropServices;
    


    2.宣告使用api

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
    private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
    private const int TOKEN_ASSIGN_PRIMARY = 0x1;
    private const int TOKEN_DUPLICATE = 0x2;
    private const int TOKEN_IMPERSONATE = 0x4;
    private const int TOKEN_QUERY = 0x8;
    private const int TOKEN_QUERY_SOURCE = 0x10;
    private const int TOKEN_ADJUST_GROUPS = 0x40;
    private const int TOKEN_ADJUST_PRIVILEGES = 0x20;
    private const int TOKEN_ADJUST_SESSIONID = 0x100;
    private const int TOKEN_ADJUST_DEFAULT = 0x80;
    private const int TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_DEFAULT);
    
    

    3.加入IsSystemProcess function

    /// <summary>
    /// 檢查該Process是否為System Process
    /// </summary>
    /// <param name="proc"></param>
    /// <returns></returns>
    public static bool IsSystemProcess(Process proc)
    {
    
    	IntPtr ph = IntPtr.Zero;
    	try
    	{
    		OpenProcessToken(proc.Handle, TOKEN_ALL_ACCESS, out ph);
    	}
    	catch (Exception ex)
    	{
    
    	}
    	//如果ph為0或是有Exception的話,表示是System的Process
    	bool result = (ph.ToInt32() == 0);
    	return result;
    }
    


    4.將使用者的process加入listBox2之中

    private void button4_Click(object sender, EventArgs e)
    {
    	//畫面上的listBox物件
    	listBox2.Items.Clear();
    	Process[] procList = Process.GetProcesses();
    	foreach (Process p in procList)
    	{
    		Application.DoEvents();
    		if (!IsSystemProcess(p))
    		{
    			listBox2.Items.Add(p.ProcessName);
    		}
    	}
    }
    


    參考資訊:

    http://stackoverflow.com/questions/5479551/detect-if-another-process-is-started-as-run-as-administrator

    http://www.cnblogs.com/pearry/archive/2011/08/23/2151353.html


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/
    2012年1月8日 3:24

全部回复

  • 目前我的想法是比較process的owner是否為登入者,如果是的話,就列出來!

    private void button1_Click(object sender, EventArgs e)
    {
    	//畫面上的listBox物件
    	listBox1.Items.Clear();
    	//取得目前登入者的資訊
    	string userName = Environment.UserDomainName + "\\" + Environment.UserName;
    	Process[] procList = Process.GetProcesses();
    	foreach (Process p in procList)
    	{
    		Application.DoEvents();
    		string processOwner = GetProcessOwner(p.Id);
    		//比較如果是目前登入者起的process就列出來
    		if (userName == processOwner)
    		{
    			listBox1.Items.Add(p.ProcessName );
    		}
    		
    	}
    }
    
    public string GetProcessOwner(int processId)
    {
    	string query = "Select * From Win32_Process Where ProcessID = " + processId;
    	ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
    	ManagementObjectCollection processList = searcher.Get();
    
    	foreach (ManagementObject obj in processList)
    	{
    		string[] argList = new string[] { string.Empty, string.Empty };
    		int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
    		if (returnVal == 0)
    		{
    			// return DOMAIN\user
    			return argList[1] + "\\" + argList[0];
    		}
    	}
    
    	return "NO OWNER";
    }
    
    
    



    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/
    • 已标记为答案 meerio 2012年1月7日 2:39
    2012年1月5日 22:23
  • 您可以參考以下文章做處理

    How To Get Process Owner ID and Current User SID

    http://www.codeproject.com/KB/cs/processownersid.aspx

    How do I determine the owner of a process in C#?

    http://stackoverflow.com/questions/777548/how-do-i-determine-the-owner-of-a-process-in-c


    歡迎參觀我的Blog.NET菜鳥自救會
    2012年1月6日 1:02
  • GetOwner

    这个方法的名称我要如何知道,从哪里可以查到?或者说我想知道还有哪些方法要从哪里查?

    谢谢

    meerio
    2012年1月7日 2:40
  • 請參考以下的link,thanks.

    Win32_Process Methods


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/
    2012年1月7日 2:57
  • 这几天有点事,今天细研究了一下,这个是根据所有者(其实就是我们看到的用户名)来区分是否系统进程和用户进程的,

    但用户程序(进程)的所有者同样可以被认为是系统的

    比如说服务程序,所有者就可以选择是system,如果是这样,如何区分呢?

     

     

    还有小歐ou的方法,其实也是根据进程的所有者来判断的,难道没有其它的方法?

     

    谢谢


    meerio
    2012年1月7日 3:23
  • 您好,我發現使用OpenProcessToken來check好像也可以! 請看一下以下的Code,謝謝!

    1.加入namespace

    using System.Runtime.InteropServices;
    


    2.宣告使用api

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
    private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
    private const int TOKEN_ASSIGN_PRIMARY = 0x1;
    private const int TOKEN_DUPLICATE = 0x2;
    private const int TOKEN_IMPERSONATE = 0x4;
    private const int TOKEN_QUERY = 0x8;
    private const int TOKEN_QUERY_SOURCE = 0x10;
    private const int TOKEN_ADJUST_GROUPS = 0x40;
    private const int TOKEN_ADJUST_PRIVILEGES = 0x20;
    private const int TOKEN_ADJUST_SESSIONID = 0x100;
    private const int TOKEN_ADJUST_DEFAULT = 0x80;
    private const int TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_DEFAULT);
    
    

    3.加入IsSystemProcess function

    /// <summary>
    /// 檢查該Process是否為System Process
    /// </summary>
    /// <param name="proc"></param>
    /// <returns></returns>
    public static bool IsSystemProcess(Process proc)
    {
    
    	IntPtr ph = IntPtr.Zero;
    	try
    	{
    		OpenProcessToken(proc.Handle, TOKEN_ALL_ACCESS, out ph);
    	}
    	catch (Exception ex)
    	{
    
    	}
    	//如果ph為0或是有Exception的話,表示是System的Process
    	bool result = (ph.ToInt32() == 0);
    	return result;
    }
    


    4.將使用者的process加入listBox2之中

    private void button4_Click(object sender, EventArgs e)
    {
    	//畫面上的listBox物件
    	listBox2.Items.Clear();
    	Process[] procList = Process.GetProcesses();
    	foreach (Process p in procList)
    	{
    		Application.DoEvents();
    		if (!IsSystemProcess(p))
    		{
    			listBox2.Items.Add(p.ProcessName);
    		}
    	}
    }
    


    參考資訊:

    http://stackoverflow.com/questions/5479551/detect-if-another-process-is-started-as-run-as-administrator

    http://www.cnblogs.com/pearry/archive/2011/08/23/2151353.html


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/
    2012年1月8日 3:24