SystemEvents.SessionSwitch, какой пользователь был заблокирован / разблокирован - PullRequest
3 голосов
/ 31 октября 2011

Я использую событие SystemEvents.SessionSwitch, чтобы определить, заблокирован ли пользователь, выполняющий мой процесс, но это событие не дает вам знать, какой пользователь заблокирован / разблокирован. Как я могу получить эту информацию (от процесса, принадлежащего пользователю с низкими привилегиями)

1 Ответ

0 голосов
/ 02 ноября 2011

Я не думаю, что вы можете для частично доверенного кода. Если ваше приложение или его часть может быть превращено в сервис с полным доверием, идентификатор сеанса можно получить, как указано в ответе на связанный вопрос .

Затем, учитывая идентификатор сеанса, вы можете найти любой процесс с этим идентификатором сеанса, чтобы получить фактического пользователя (абстрагировано от Получение имени владельца процесса Windows ):

[DllImport ("advapi32.dll", SetLastError = true)]
static extern bool OpenProcessToken (IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

[DllImport ("kernel32.dll", SetLastError = true)]
[return: MarshalAs (UnmanagedType.Bool)]
static extern bool CloseHandle (IntPtr hObject); 

static uint TOKEN_QUERY = 0x0008;

// ...

public static WindowsIdentity GetUserFromSession(int sessionId)
{
    return Process.GetProcesses()
        .Where(p => p.SessionId == sessionId)
        .Select(GetUserFromProcess)
        .FirstOrDefault();
}

public static WindowsIdentity GetUserFromProcess(Process p)
{
    IntPtr ph;
    try
    {
        OpenProcessToken (p.Handle, TOKEN_QUERY, out ph);
        return new WindowsIdentity(ph);
    }
    catch (Exception e)
    {
        return null;
    }
    finally
    {
        if (ph != IntPtr.Zero) CloseHandle(ph);
    }
}
...