Вопрос или проблема
У меня есть проблема: у меня есть служба Windows, которая запускает и останавливает приложения. Сессии приложения запускаются, однако они работают в фоновом режиме. Для того, что мне нужно сделать, я хочу, чтобы они были выведены на передний план, чтобы пользователи могли следить за их корректной работой. В голову пришла мысль сделать консольное приложение, однако цель этой службы заключается в том, чтобы пользователи могли управлять сессиями с другого ПК. Имейте в виду, что уже есть работающий API для этой службы, который управляет программами для запуска и остановки. Всё, что я нашел до сих пор, это поиск основного дескриптора окна, но так как эти программы открываются в фоновом режиме, основной дескриптор окна равен 0, что также может означать нормальный возврат, так как я не могу к нему получить доступ. Буду признателен за любые советы или рекомендации.
Вот что я сделал, чтобы запустить сессии продукта, но они работают в фоновом режиме, используя 0% CPU.
public static void StartProcess(int Year, int sessionCount, string filepath, string newProcess)
{
int i = 1;
while (i <= sessionCount)
{
try
{
System.Diagnostics.Process cmdProcess = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
if (newProcess.Contains("Program1"))
{
//Должно быть установлено так, чтобы окно было видно.
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
startInfo.UseShellExecute = true;
startInfo.CreateNoWindow = false;
ProcessStartInfo psi = new ProcessStartInfo(newProcess);
Process.Start(psi);
}
else if (newProcess.Contains("Program2"))
{
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = "\"" + filepath + "\""; ;
startInfo.FileName = newProcess;
cmdProcess.StartInfo = startInfo;
cmdProcess.Start();
}
}
catch (Exception ex)
{
AppLogger appLogger = new AppLogger();
if (newProcess == "")
{
appLogger.LogError("Процесс не найден. Пожалуйста, проверьте продукт и год");
}
else
{
appLogger.LogError(ex.Message);
}
}
i++;
}
}
Если есть способ это сделать, я буду вам навеки признателен, я чувствую, что уже перепробовал всё на данный момент.
Ответ или решение
Для решения проблемы запуска приложений из Windows-сервиса так, чтобы они появлялись на переднем плане, необходимо учитывать ряд аспектов, связанных с работой служб и пользовательскими сессиями в Windows.
Службы Windows работают в контексте учетной записи системы, и они не имеют доступа к пользовательскому интерфейсу. Это означает, что даже если вы попытаетесь открыть приложение с помощью службы, оно будет запущено в фоновом режиме и не сможет отображаться пользователям. Вот несколько подходов, которые вы можете рассмотреть для решения данной проблемы:
-
Использование Task Scheduler: Вместо запуска приложений непосредственно из службы, вы можете создать задачу в планировщике задач Windows (Task Scheduler), которая будет запускать ваше приложение. Задача может быть настроена так, чтобы запускаться от имени текущего пользователя и отображаться на рабочем столе. Вот пример, как это можно сделать:
- Создайте задачу с помощью
schtasks.exe
с параметрами, указывающими, что задача должна выполняться при входе пользователя в систему.
schtasks /create /tn "MyApp" /tr "C:\Path\To\YourApp.exe" /sc onlogon
- Создайте задачу с помощью
-
Использование WMI для запуска процессов в пользовательской сессии: Вы можете использовать Windows Management Instrumentation (WMI) для запуска процессов в активной пользовательской сессии. Это потребует дополнительных прав, и вам нужно будет обеспечить, чтобы ваш сервис имел необходимые разрешения.
Пример кода ищет активную сессию и запускает в ней процесс:
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem"); foreach (ManagementObject obj in searcher.Get()) { var username = obj["UserName"].ToString(); // Получите ID сессии, где запущен этот пользователь // Затем используйте этот ID для запуска процесса в нужной сессии }
-
Использование консольного приложения как посредника: Вы можете создать консольное приложение, которое будет исполняться в контексте пользователя и принимать команды от вашего Windows-сервиса через API. Это приложение может обрабатывать команды на запуск приложения в переднем плане.
-
Использование UI Automation: Если ваше приложение поддерживает UI Automation, вы можете попробовать фокусировать окна с помощью API, таких как
SetForegroundWindow
. Тем не менее, это может потребовать наличия окна в системе и прав на его фокусировку. -
Использование
CreateProcessAsUser
: Если у вас есть возможность, вы можете использовать Win32 APICreateProcessAsUser
, который позволяет запускать процессы под конкретным пользователем, что может помочь запустить приложение в переднем плане. Однако это потребует сложной настройки и обработки токенов безопасности.
Важно отметить, что попытки запуска процессов от имени службы могут нарушать политику безопасности Windows и могут не сработать в следующих версиях Windows. Всегда тестируйте подобные решения в безопасной среде и следуйте серьезным практикам безопасности.
Заключение
Запуск приложений из Windows-сервиса в переднем плане невозможно из-за ограничений окружения службы. Рекомендую использовать задачи планировщика, либо создавать отдельное приложение для взаимодействия пользователя, которое будет запускаться в нужной сессии. Это обеспечит более надежный и безопасный способ решения вашей проблемы.