Enhance process management and application launch features in session server

- Added support for launching applications without a graphical window using `-NOSPLASH` and `-NOWINDOW` flags.
- Improved process termination logic with a multi-step approach: soft termination, forced termination, and PowerShell fallback.
- Updated README to reflect new features and enhancements in process management.
This commit is contained in:
2025-12-12 17:43:15 +05:00
parent a80544c936
commit 36a7f79c86
3 changed files with 35 additions and 13 deletions
+6 -2
View File
@@ -152,10 +152,14 @@ C:\apps\
- ✅ Автоматическая проверка существования exe файла
- ✅ Рабочая директория устанавливается в папку приложения (`C:\apps\{appName}\`)
- ✅ Окно консоли скрывается (`windowsHide: true`)
-**Запуск без графического окна** - использует флаги `-NOSPLASH` и `-NOWINDOW` для UE приложений
- ✅ PID процесса отслеживается и передается на main server
- ✅ Автоматическое обновление статуса при завершении процесса
-**Корректное завершение дочерних процессов** - использует `taskkill /T` для завершения всего дерева процессов
- ✅ Решает проблему с UE5 приложениями, которые создают множественные процессы
-**Многоступенчатое завершение процессов**:
1. Мягкое завершение (`taskkill /T`) - отправляет WM_CLOSE сообщение окнам
2. Принудительное завершение (`taskkill /T /F`) - если мягкое не сработало
3. PowerShell завершение - закрывает окна и убивает процесс через PowerShell
- ✅ Решает проблему с UE5 приложениями, которые создают множественные процессы и имеют графические окна
#### Логи запуска
Binary file not shown.
+29 -11
View File
@@ -517,6 +517,8 @@ async function startApplication(session: SessionData): Promise<void> {
"-PixelStreamingH264Profile=HIGH",
"-PixelStreamingWebRTCDisableReceiveAudio=true",
"-PixelStreamingEncoderRateControl=VBR",
"-NOSPLASH", // Отключить splash screen
"-NOWINDOW", // Запустить без окна
],
{
detached: false,
@@ -530,7 +532,10 @@ async function startApplication(session: SessionData): Promise<void> {
);
} else {
// Local-режим: запускаем без Pixel Streaming
appProcess = spawn(appPath, [], {
appProcess = spawn(appPath, [
"-NOSPLASH", // Отключить splash screen
"-NOWINDOW", // Запустить без окна
], {
detached: false,
stdio: ["ignore", "ignore", "pipe"],
windowsHide: true,
@@ -681,24 +686,25 @@ async function startApplication(session: SessionData): Promise<void> {
/**
* Убить процесс и всё его дерево дочерних процессов (для Windows)
* Принудительное завершение без попыток мягкого закрытия
*/
function killProcessTree(pid: number): void {
try {
// На Windows используем taskkill с флагом /T для убийства дерева процессов
// /F - принудительное завершение
// /T - завершить указанный процесс и все дочерние процессы
// Принудительное завершение с /F
console.log(
`[${new Date().toISOString()}] 🔄 Принудительное завершение процесса PID ${pid}...`
);
execSync(`taskkill /pid ${pid} /T /F`, {
stdio: "ignore",
timeout: 30000, // Увеличен таймаут до 30 секунд
windowsHide: true, // Скрыть окно консоли на Windows
killSignal: "SIGKILL", // Принудительное завершение при таймауте
timeout: 30000, // Таймаут 30 секунд
windowsHide: true,
killSignal: "SIGKILL",
});
console.log(
`[${new Date().toISOString()}] ✅ Дерево процессов для PID ${pid} успешно завершено`
`[${new Date().toISOString()}] ✅ Дерево процессов для PID ${pid} успешно завершено принудительно`
);
} catch (error) {
// Проверяем, действительно ли процесс всё ещё существует
// Если процесс не существует, это не ошибка
const processExists = checkProcessExists(pid);
if (!processExists) {
console.log(
@@ -712,13 +718,25 @@ function killProcessTree(pid: number): void {
error instanceof Error ? error.message : error
);
// Попытка принудительного завершения через PowerShell как запасной вариант
// Попытка принудительного завершения через PowerShell как последний вариант
try {
console.log(
`[${new Date().toISOString()}] 🔄 Попытка принудительного завершения через PowerShell для PID ${pid}`
);
// Используем агрессивный PowerShell скрипт для принудительного завершения
const psScript = `
$proc = Get-Process -Id ${pid} -ErrorAction SilentlyContinue;
if ($proc) {
# Принудительно завершаем процесс и все дочерние
Stop-Process -Id ${pid} -Force -ErrorAction SilentlyContinue;
# Завершаем все дочерние процессы
Get-Process | Where-Object { $_.Parent.Id -eq ${pid} } | Stop-Process -Force -ErrorAction SilentlyContinue;
}
`.replace(/\n/g, " ");
execSync(
`powershell -Command "Stop-Process -Id ${pid} -Force -ErrorAction SilentlyContinue"`,
`powershell -Command "${psScript}"`,
{
stdio: "ignore",
timeout: 15000,