Windows Сервис: получение процессов для всех пользователей, включая MainWindowHandle - PullRequest
1 голос
/ 05 марта 2020

Я написал Windows Сервис в PowerShell. Это работает хорошо, но есть одно главное ограничение, для которого мне нужно найти решение. Мне нужно перечислить все процессы с помощью Windowed Applications - это для пассивного учета приложений (приложения IE открываются и используются каждым вошедшим пользователем).

Служба работает как Local System. Я вижу все процессы, но поскольку служба находится на неинтерактивном рабочем столе (идентификатор сеанса 0), я не вижу MainWindowTitle или MainWindowhandle, все заголовки равны нулю, а все дескрипторы равны 0.

Я пытался использовать Get-Process, Get-CIMInstance Win32_Process и [System.Diagnostics.Process]::GetProcesses(). Ничего из этого не сработало (я получаю все процессы, но с отозванными данными).

Я решил создать консольное приложение C#, которое будет выполнять служба PowerShell и собирать ответ. Это сработало, но все же исключило «конфиденциальную» информацию, поэтому критическое свойство MainWindowhandle всегда было равно 0.

Вот консольное приложение C# (это было быстрое задание только для тестирования):

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Security.Permissions;

namespace ProcessManager
{

    public class ProcessRecord
    {
        // Auto-Initialized properties  
        public string Name { get; set; }
        public int MainWindowHandle { get; set; }
        public string WindowTitle { get; set; }
        public int SessionId { get; set; }
        public DateTime StartTime { get; set; }
    }

    class Program
    {
        [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
        [HostProtectionAttribute(SecurityAction.LinkDemand, SharedState = true, Synchronization = true, ExternalProcessMgmt = true, SelfAffectingProcessMgmt = true)]
        [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
        static void Main(string[] args)
        {
            listProcesses();
        }

        public static void listProcesses()
        {
            List<ProcessRecord> processesList = new List<ProcessRecord>{};
            Process.GetProcesses().ToList().ForEach(p =>
            {
                try 
                {
                    processesList.Add(new ProcessRecord
                    {
                        Name = p.ProcessName,
                        MainWindowHandle = (int) p.MainWindowHandle,
                        WindowTitle = p.MainWindowTitle,
                        SessionId = p.SessionId,
                        StartTime = p.StartTime
                    });
                }
                catch (Win32Exception)
                {
                    // Just ignoring this to avoid the Access Denied exception for low-level system processes
                }

            });
            Console.WriteLine(JsonConvert.SerializeObject(processesList));
        }
    }
}

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

Мне не нужно знать MainWindowHandle , мне просто нужно перечислить процессы, где MainWindowhandle не 0. К сожалению, мне нужно знать идентификатор сессии.

Как мне поступить? Простой ответ «Это невозможно сделать» или существует непослушный обходной путь, такой как олицетворение?

Может быть, есть более простой способ перечисления приложений, открытых пользователями, без необходимости зависеть от MainWindowHandle != 0?

Спасибо за любые указатели!

1 Ответ

0 голосов
/ 05 марта 2020

Если вам нужен процесс с оконными приложениями, вы можете отфильтровать процесс по свойству mainwindowhandle

Get-Process | Where-Object {$_.mainwindowhandle -ne 0} | select ProcessName | ft -HideTableHeaders
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...