/
spruttechnology
/
cam-api-examples
Обзор
Документация
Войти
/
spruttechnology
/
cam-api-examples
Код
Запросы
3
Задачи
Пакеты
0
Релизы
1
Аналитика
v19/develop
Project/ExtensionUtilityExportInformationNet/viewer/main/RunningInstance.cs
84 строки
3 KB
renal
Добавление отображения информации в WEB - версии в расширении экспорта информации
20 июл 2026, 08:34
20 июл 2026, 08:34
c8b8e63
Код
Авторство
О чём код?
using System.Text; using System.Text.Json; namespace ProjectInfoViewer; /// <summary> /// Single-instance через lock-файл в %TEMP% с URL работающего сервера. /// Повторный запуск не поднимает второй сервер, а активирует существующий. /// </summary> public static class RunningInstance { private const string InstanceMarker = "ProjectInfoViewer"; private static readonly TimeSpan ProbeTimeout = TimeSpan.FromSeconds(1.5); private static string LockFilePath => Path.Combine(Path.GetTempPath(), "ProjectInfoViewer.lock"); /// <summary> /// Если вьюер уже работает — передаёт ему новый jsonPath и возвращает его URL. /// Иначе возвращает null (нужно стартовать свой сервер). /// </summary> public static async Task<string?> TryActivateExistingAsync(string jsonPath) { string url; try { if (!File.Exists(LockFilePath)) return null; url = (await File.ReadAllTextAsync(LockFilePath)).Trim(); if (string.IsNullOrEmpty(url)) return null; } catch (IOException) { return null; } try { using var client = new HttpClient { Timeout = ProbeTimeout }; var instanceJson = await client.GetStringAsync($"{url}/api/instance"); if (!instanceJson.Contains(InstanceMarker)) return null; var payload = new StringContent( JsonSerializer.Serialize(new { jsonPath }), Encoding.UTF8, "application/json"); var response = await client.PostAsync($"{url}/api/activate", payload); return response.IsSuccessStatusCode ? url : null; } catch (Exception e) when (e is HttpRequestException or TaskCanceledException) { DeleteLockFile(); // lock устарел: сервера за ним больше нет return null; } } /// <summary>Ответ для GET /api/instance — по маркеру повторный запуск узнаёт «своих».</summary> public static object Describe() => new { app = InstanceMarker, pid = Environment.ProcessId }; public static void WriteLockFile(string url) { try { File.WriteAllText(LockFilePath, url); } catch (IOException) { // без lock-файла single-instance не сработает, но сам сервер работоспособен } } public static void DeleteLockFile() { try { if (File.Exists(LockFilePath)) File.Delete(LockFilePath); } catch (IOException) { // просроченный lock перепишет следующий запуск } } }