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:
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user