Привет читатель ! Если ты попал сюда, значит тебе срочно нужно создать с помощью Windows Service демона который будет открыть или закрывать приложение когда тебе это будет нужно. Но вот не задача ! есть запрет от Microsoft, после версии Windows Vista, сервисам запрещено выполнять программы прямо на рабочем столе, они выполняют их в своем “Нулевом” сеансе, по этому мы их не видим, но они запускаются. Это сделано чтобы увеличить безопасность ОС.
Я очень долго добил интернет, и пытался разобраться как реализовать включение программы в обход нулевого сеанса. Ну чтож, задача была выполнена. Так как в рунете нету подобного туториала, я опишу его для тебя. И так, приступим.
- Скачиваем вот этот Файлик
Это либа для обхода этого страшного сеанса. Но есть минусы в этой схеме. увы. О них поподробнее далее.
Кидайте этот файл себе в проект и в своем коде, где необходимо запустить какую либо программу, пишем такие строки
1 2 3 4 5 6 7 8 9 10 11 |
private static void RunApp(ref int Processid, string path) { if (!Win32Api.CreateProcessAsUser(path, pathcut, "winlogon", out output, ref Processid)) { PrintInLog("Ошибка запуска приложения " + Process.GetProcessById(Processid).ProcessName + " причина ошибки: " + output.ToString()); } else { PrintInLog("Приложение " + Process.GetProcessById(Processid).ProcessName + " запущенно. (ID процесса= " + Processid + ")"); } } |
Вот уже написанный для вас метод запуска приложения я назвал его RunApp, из него вы получите ProcessId который нам понадобиться дальше(В этом и минус) и указывайте путь к файлу запуска в path. Оговорюсь сразу , в ProcessId можете при запуске передавать инициализированную переменную типа int, после выполнения запуска, ваша переменная, которую вы передали, изменит свое значение на необходимое нам для остановки запущенного приложения.
Для тех кто в танке и не знает что такое ref и out в C# пишу - идите в MSDN. А не создавайте сервисы. Но если очень надо, объясняю, нужно сделать так
1 2 3 4 |
int Processid = 0; String path = @"C:/Windows/system32/notepad.exe" RunApp(ref Processid, path) int ProcessIdForKill = ProcessId; //теперь в переменной ProcessIdForKill будет храниться нужный нам ID для убийства приложения |
И так, теперь у нас есть ID нашего приложения, теперь нам надо его остановить или другими словами закрыть. Для этого я для себя накатал такой метод :
1 2 3 4 |
public static void KillProcess(int Processid) { Process.GetProcessById(Processid).Kill(); } |
Обращаясь к встроенной библиотеке Process выполняем убийство приложения.
Теперь немного поговорим о минусах данного подхода. Допустим у вас есть какое-то приложение, которое запускается, и после этого запускает другое приложение. Тогда вам вернется ID того приложения которое запустило Win32Api, и закрыть его вы не сможете после этого. Ищите как исправить этот баг если вам это очень надо, в принципе костылики можно приделать не такие уж и большие. Просто найти что запускает ваша программа и запускать ее напрямую. Просто если что-то у вас не получится, допустим приложение открылось и не закрылось - это и будет этот случай проблемы с ID процесса.
Проверяйте работоспособность вашей программы сначала на Notepad.exe !!! после этого на той программе которая вам нужна.
Собственно все ! Удачи в написании ваших демонов.
Если вам необходим пример работы, можете использовать программу разработанную мной на Github