SmartRebooteR для работы с портативными программами
Цитата: Никита от 24.06.2021, 14:16Всем привет..
Около месяца назад спрашивал, что можно сделать с тем, что при перезагрузке ПК с открытыми Portable программами, при следующем их запуске получаем такое окно..
[spoiler title="Скрин"][/spoiler]
Которое само по себе не очень радует глаз, так и вынуждает снова запускать приложение, либо всегда следить за тем, чтобы перед каждой перезагрузкой ПК не было открытых приложений.Я например любитель слушать музыку в Spotify, с запущенной сессией в TeamW и в добавок посмотреть, что-то в Notepad++
И чтобы резко перезагрузить ПК, нужно каждую из них закрывать вручную.. А если не закрывать, то каждый раз при перезапуске видеть, то самое окно..И все эти приложения у меня портативны..
Так вот! Сделал себе кнопку для панели задач, которая по нажатию проверяет нужные мне процессы от портативных приложений. После чего закрывает их, затем дожидается, пока сам Portable Launcher уберёт весь мусор из системы и только после этого происходит перезагрузка ПК..
[spoiler title="Вот полноценный видеообзор (записан с озвучкой) где показано, как и что работает.."]https://www.youtube.com/watch?v=9oMbV_YTxjw[/spoiler]
На данный момент настроено для правильной перезагрузки с запущенными:
1. Notepad++
2. Audition
3. Photoshop
4. Spotify
5. Total Uninstall
6. TeamViewer
7. SkypeЕсли будете пользоваться и нужно добавить в список другие Portable приложения, то жду ссылки на программы в комментариях..
Скачаю их, добавлю, протестирую и выложу обновленный RebooteR..
Непосредственно ссылка на загрузку RebooteR'a с upload.ee
Всем привет..
Около месяца назад спрашивал, что можно сделать с тем, что при перезагрузке ПК с открытыми Portable программами, при следующем их запуске получаем такое окно..

Которое само по себе не очень радует глаз, так и вынуждает снова запускать приложение, либо всегда следить за тем, чтобы перед каждой перезагрузкой ПК не было открытых приложений.
Я например любитель слушать музыку в Spotify, с запущенной сессией в TeamW и в добавок посмотреть, что-то в Notepad++
И чтобы резко перезагрузить ПК, нужно каждую из них закрывать вручную.. А если не закрывать, то каждый раз при перезапуске видеть, то самое окно..
И все эти приложения у меня портативны..
Так вот! Сделал себе кнопку для панели задач, которая по нажатию проверяет нужные мне процессы от портативных приложений. После чего закрывает их, затем дожидается, пока сам Portable Launcher уберёт весь мусор из системы и только после этого происходит перезагрузка ПК..
На данный момент настроено для правильной перезагрузки с запущенными:
1. Notepad++
2. Audition
3. Photoshop
4. Spotify
5. Total Uninstall
6. TeamViewer
7. Skype
Если будете пользоваться и нужно добавить в список другие Portable приложения, то жду ссылки на программы в комментариях..
Скачаю их, добавлю, протестирую и выложу обновленный RebooteR..
Непосредственно ссылка на загрузку RebooteR'a с upload.ee
Цитата: XpucT от 24.06.2021, 14:34Привет 🖐
В идеале, конечно, отслеживать попытку перезагрузить.
Через WinAPI можно даже запрещать. По WinAPI сделаю урок (уже на заметке).
Но если додумывать отдельно за других, как с Adobe и Spotify, т.к. делают разные люди, то лучше создать отдельный List, чтобы не плодить методы для каждой программы. Так код чище 😉[spoiler title="Ещё можно немного сэкономить на размере программы, сразу избегая лишний раз string:"]
Environment.ExpandEnvironmentVariables("%USERPROFILE%")
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)[/spoiler][spoiler title="Процессы лучше также тушить не отдельными методами, а пачкой:"]
// Бритва Оккама new List<string> { "notepad++", "Spotify", "Tu", "Photoshop", "Adobe Audition", "Skype", "4kvideodownloader", "TeamViewer", }.ForEach(x => Process.GetProcessesByName(x).AsParallel().ForAll(y => y.Kill()));[/spoiler]
Привет 🖐
В идеале, конечно, отслеживать попытку перезагрузить.
Через WinAPI можно даже запрещать. По WinAPI сделаю урок (уже на заметке).
Но если додумывать отдельно за других, как с Adobe и Spotify, т.к. делают разные люди, то лучше создать отдельный List, чтобы не плодить методы для каждой программы. Так код чище 😉
СкопированоEnvironment.ExpandEnvironmentVariables("%USERPROFILE%")СкопированоEnvironment.GetFolderPath(Environment.SpecialFolder.UserProfile)// Бритва Оккама
new List<string>
{
"notepad++",
"Spotify",
"Tu",
"Photoshop",
"Adobe Audition",
"Skype",
"4kvideodownloader",
"TeamViewer",
}.ForEach(x => Process.GetProcessesByName(x).AsParallel().ForAll(y => y.Kill()));
Цитата: Никита от 24.06.2021, 14:46Принял.. По оптимизации кода, ещё учиться и учиться)
Сегодня попробую переписать таким образом, спасибо!
Принял.. По оптимизации кода, ещё учиться и учиться)
Сегодня попробую переписать таким образом, спасибо!
Цитата: ЯR от 24.06.2021, 15:00Добрый день.
Проблема может заключаться в именах ланчеров, так как некоторые сборщики портативных программ именуют их по своему усмотрению. Можно, конечно, применять маски поиска имён процессов, но, как мне кажется, идеальным вариантом было бы создание ini-файла, с возможностью вручную составлять список программ.
Добрый день.
Проблема может заключаться в именах ланчеров, так как некоторые сборщики портативных программ именуют их по своему усмотрению. Можно, конечно, применять маски поиска имён процессов, но, как мне кажется, идеальным вариантом было бы создание ini-файла, с возможностью вручную составлять список программ.
Цитата: Никита от 24.06.2021, 16:35Цитата: Яр от 24.06.2021, 15:00Добрый день.
Проблема может заключаться в именах ланчеров, так как некоторые сборщики портативных программ именуют их по своему усмотрению. Можно, конечно, применять маски поиска имён процессов, но, как мне кажется, идеальным вариантом было бы создание ini-файла, с возможностью вручную составлять список программ.Здравствуй, Яр..
Уже придумал, как реализовать. Осталось только исполнить)
Спасибо за подсказки.. код становится раз в 7 короче)
Цитата: Яр от 24.06.2021, 15:00Добрый день.
Проблема может заключаться в именах ланчеров, так как некоторые сборщики портативных программ именуют их по своему усмотрению. Можно, конечно, применять маски поиска имён процессов, но, как мне кажется, идеальным вариантом было бы создание ini-файла, с возможностью вручную составлять список программ.
Здравствуй, Яр..
Уже придумал, как реализовать. Осталось только исполнить)
Спасибо за подсказки.. код становится раз в 7 короче)
Цитата: Никита от 24.06.2021, 19:14Обновил!
Теперь всё считывается с .ini файлов..
как теперь с приложением работать описал в видео
[spoiler title="Ютуб"]https://www.youtube.com/watch?v=zfkuRrn5pD8[/spoiler]Скачать обнову с upload.ee
Обновил!
Теперь всё считывается с .ini файлов..
как теперь с приложением работать описал в видео
Скачать обнову с upload.ee
Цитата: Юрий от 24.06.2021, 20:59Всем привет!
Никита, а можно добавить кнопочку на Выключение ПК (Завершение работы)?
Всем привет!
Никита, а можно добавить кнопочку на Выключение ПК (Завершение работы)?
Цитата: Никита от 24.06.2021, 21:04Цитата: Юрий от 24.06.2021, 20:59Всем привет!
Никита, а можно добавить кнопочку на Выключение ПК (Завершение работы)?Привет, Юрий. Ночью сделаю.
Цитата: Юрий от 24.06.2021, 20:59Всем привет!
Никита, а можно добавить кнопочку на Выключение ПК (Завершение работы)?
Привет, Юрий. Ночью сделаю.
Цитата: Никита от 24.06.2021, 22:25@yuriy Забирайте.
[spoiler title="Скрин"][/spoiler]
@yuriy Забирайте.

Цитата: Юрий от 24.06.2021, 22:41Никита, спасибо!
Никита, спасибо!
Цитата: Adler от 25.06.2021, 09:25Добрый день.
В принципе, что бы не создавать два конфига можно это упростить приняв, что все процессы из Apps.ini создаются процессами из Launcher.ini.
Т.е. не нужен отдельный Apps.ini, а берем процесс из Launcher.ini и ищем его дочерние процессы с помощью нехитрой функции расширения.using System.Management; //Нужно её еще добавить в ссылки проекта. public static class ProcessExtensions { public static List<Process> GetChildProcesses(this Process process) { var query = $"Select * From Win32_Process Where ParentProcessId = {process.Id.ToString()}"; ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); ManagementObjectCollection processList = searcher.Get(); var result = processList.Cast<ManagementObject>().Select(p => Process.GetProcessById(Convert.ToInt32(p.GetPropertyValue("ProcessId")))).ToList(); return result; } }А функцию
CheckApps()заменить на эту:private void CheckApps() { File.ReadAllLines("Launchers.ini").AsParallel().ForAll(x=> Process.GetProcessesByName(x).ToList<Process>().ForEach(y => y.GetChildProcesses().ForEach(z => z.Kill()))); }Единственный возможный нюанс, что если дочерний процесс создан с помощью
cmd /cто это может не сработать. С особенностями портативного софта не знаком, не знаю, какова вероятность встретить именно такой способ запуска процессов.P.S. В работе это не проверял.
Добрый день.
В принципе, что бы не создавать два конфига можно это упростить приняв, что все процессы из Apps.ini создаются процессами из Launcher.ini.
Т.е. не нужен отдельный Apps.ini, а берем процесс из Launcher.ini и ищем его дочерние процессы с помощью нехитрой функции расширения.
using System.Management; //Нужно её еще добавить в ссылки проекта.
public static class ProcessExtensions
{
public static List<Process> GetChildProcesses(this Process process)
{
var query = $"Select * From Win32_Process Where ParentProcessId = {process.Id.ToString()}";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
var result = processList.Cast<ManagementObject>().Select(p =>
Process.GetProcessById(Convert.ToInt32(p.GetPropertyValue("ProcessId")))).ToList();
return result;
}
}
А функцию СкопированоCheckApps() заменить на эту:
private void CheckApps()
{
File.ReadAllLines("Launchers.ini").AsParallel().ForAll(x=> Process.GetProcessesByName(x).ToList<Process>().ForEach(y => y.GetChildProcesses().ForEach(z => z.Kill())));
}
Единственный возможный нюанс, что если дочерний процесс создан с помощью Скопированоcmd /c то это может не сработать. С особенностями портативного софта не знаком, не знаю, какова вероятность встретить именно такой способ запуска процессов.
P.S. В работе это не проверял.
Цитата: Adler от 25.06.2021, 09:44А если еще заморочиться, то можно и от
Launchers.iniизбавиться, если принять, что все процессы изLaunchers.iniзапускаются из одного места, т.е., к примеруD:\Portable\<Название программы>\<Launcher>.exe, а все Apps процессы откуда-то изD:\Portable\<Название программы>\<Какая-то папка, а может и не одна>\<Apps>.exe, т.е. откуда-то с другого уровня вложения.Класс
ProcessExtensionsможно расширить еще одной функцией:public static string GetCommandLine(this Process process) { using (ManagementObjectSearcher searcher = new ManagementObjectSearcher($"SELECT CommandLine FROM Win32_Process WHERE ProcessId = {process.Id.ToString()}")) using (ManagementObjectCollection objects = searcher.Get()) { return objects.Cast<ManagementBaseObject>().SingleOrDefault()?["CommandLine"]?.ToString(); } }То можно получить командную строу запуска процесса и определить откуда он запущен (может есть способ и проще, но как-то в голову ничего не пришло другого).
Потом перебрать все процессы отобрав нужные, с нужного места запуска, ну а потом уже немного заморочиться, что бы определить "глубину" запуска процесса у "отсеять" возможные параметры запуска. С ходу не придумал как.
А если еще заморочиться, то можно и от СкопированоLaunchers.ini избавиться, если принять, что все процессы из СкопированоLaunchers.ini запускаются из одного места, т.е., к примеру СкопированоD:\Portable\<Название программы>\<Launcher>.exe, а все Apps процессы откуда-то из СкопированоD:\Portable\<Название программы>\<Какая-то папка, а может и не одна>\<Apps>.exe, т.е. откуда-то с другого уровня вложения.
Класс СкопированоProcessExtensions можно расширить еще одной функцией:
public static string GetCommandLine(this Process process)
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher($"SELECT CommandLine FROM Win32_Process WHERE ProcessId = {process.Id.ToString()}"))
using (ManagementObjectCollection objects = searcher.Get())
{
return objects.Cast<ManagementBaseObject>().SingleOrDefault()?["CommandLine"]?.ToString();
}
}
То можно получить командную строу запуска процесса и определить откуда он запущен (может есть способ и проще, но как-то в голову ничего не пришло другого).
Потом перебрать все процессы отобрав нужные, с нужного места запуска, ну а потом уже немного заморочиться, что бы определить "глубину" запуска процесса у "отсеять" возможные параметры запуска. С ходу не придумал как.
Цитата: ЯR от 25.06.2021, 11:50Всем привет.
Вопрос возник: а как быть с программами, у которых при работе происходит запуск нескольких утилит/процессов?
Например, набор утилит Glary Utilities и другие подобные. При запуске утилит из главного окна, каждая из них запускается отдельным процессом.
Прав Adler — нужен способ вычленять дочерние процессы, причём, в два уровня глубины, т.е.: поиск дочернего процесса ланчера + дочерние процессы, запускаемые через главное окно программы.
Только что проверил, если завершить главный процесс, соответственно, завершит свою работу и ланчер, но утилиты при этом продолжают исполняться.
Всем привет.
Вопрос возник: а как быть с программами, у которых при работе происходит запуск нескольких утилит/процессов?
Например, набор утилит Glary Utilities и другие подобные. При запуске утилит из главного окна, каждая из них запускается отдельным процессом.
Прав Adler — нужен способ вычленять дочерние процессы, причём, в два уровня глубины, т.е.: поиск дочернего процесса ланчера + дочерние процессы, запускаемые через главное окно программы.
Только что проверил, если завершить главный процесс, соответственно, завершит свою работу и ланчер, но утилиты при этом продолжают исполняться.
Цитата: Adler от 25.06.2021, 12:06🖐По идее
, а если и нет, то не проблема еще раз сделатьProcess.Kill(true)должен прибивать и дочерние процессыGetChildProcesses()и кильнуть их.
P.S. Дерево запуска процессов удобно отслеживать с помощью Process Explorer
P.S.S. Kill(true) нет в .Net Framewok, только в .Net Core...
🖐По идее , а если и нет, то не проблема еще раз сделать СкопированоProcess.Kill(true) должен прибивать и дочерние процессыСкопированоGetChildProcesses() и кильнуть их.
P.S. Дерево запуска процессов удобно отслеживать с помощью Process Explorer
P.S.S. Kill(true) нет в .Net Framewok, только в .Net Core...