Here's how you use the new method:
////
// 'WindowsIdentity' Extension Method Demo:
// Enumerate all running processes with their associated Windows Identity
////
foreach (var p in Process.GetProcesses())
{
string processName;
try
{
processName = p.WindowsIdentity().Name;
}
catch (Exception ex)
{
processName = ex.Message; // Probably "Access is denied"
}
Console.WriteLine(p.ProcessName + " (" + processName + ")");
}
Here's the corresponding class:
//-----------------------------------------------------------------------
// <copyright file="ProcessExtensions.cs" company="DockOfTheBay">
// http://www.dotbay.be
// </copyright>
// <summary>Defines the ProcessExtensions class.</summary>
//-----------------------------------------------------------------------
namespace DockOfTheBay
{
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
/// <summary>
/// Extension Methods for the System.Diagnostics.Process Class.
/// </summary>
public static class ProcessExtensions
{
/// <summary>
/// Required to query an access token.
/// </summary>
private static uint TOKEN_QUERY = 0x0008;
/// <summary>
/// Returns the WindowsIdentity associated to a Process
/// </summary>
/// <param name="process">The Windows Process.</param>
/// <returns>The WindowsIdentity of the Process.</returns>
/// <remarks>Be prepared for 'Access Denied' Exceptions</remarks>
public static WindowsIdentity WindowsIdentity(this Process process)
{
IntPtr ph = IntPtr.Zero;
WindowsIdentity wi = null;
try
{
OpenProcessToken(process.Handle, TOKEN_QUERY, out ph);
wi = new WindowsIdentity(ph);
}
catch (Exception)
{
throw;
}
finally
{
if (ph != IntPtr.Zero)
{
CloseHandle(ph);
}
}
return wi;
}
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
}
}
Great post, and what I was looking for, BUT, it needed the following to get it working for me:
ReplyDeleteI'm sure you can work out the tidyup and const definition code:-)
OpenProcessToken(process.Handle, TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY, out ph);
wi = new WindowsIdentity(DuplicateToken(ph, SecurityImpersonation, ref dupeTokenHandle)?dupeTokenHandle:ph);
Just to clarify, I was using your class like this:
ReplyDeleteusing (Process ownerProcess = Process.GetProcessById((int) info.ProcessId))
{
using (WindowsImpersonationContext impersonationContext = ownerProcess.WindowsIdentity().Impersonate())
{
// Do Access / ACL stuff
}
}
Hi,
ReplyDeleteI know you wrote this a long time ago, but I'm currently writing a service that monitors all processes and your class does not work for me. I always have an access denied error...
Can you help me ?
Hi,
ReplyDeleteI added the code in my app, it returned me the following error.
Token cannot be zero.
Could you please help me out?
It only returns me the current users name, but the same process is executed by other users it can't access their name even the current users is administrator.
ReplyDelete