JJServiceManagerEnt/Core/Models.cs

174 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace JJServiceManager
{
/// <summary>바인딩용 기본 클래스</summary>
public abstract class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(name);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
/// <summary>로그창 띄우기 방식</summary>
public enum LogWindowMode
{
Individual = 0, // 개별 창
Tabs = 1, // 하나의 창에 탭
Split = 2 // 창을 좌우로 나누어 비교
}
/// <summary>Esc 키 동작</summary>
public enum EscAction
{
Tray = 0, // 트레이로 (백그라운드)
Exit = 1 // 완전 종료
}
/// <summary>등록된 서비스 한 건</summary>
public class ServiceEntry
{
public string ServiceName { get; set; } = "";
public string DisplayName { get; set; } = "";
/// <summary>로그 파일 경로 또는 로그 폴더 경로 (없으면 빈 값)</summary>
public string LogPath { get; set; } = "";
/// <summary>true면 LogPath는 폴더이며, 그 안의 가장 최근 수정 파일을 표시</summary>
public bool LogIsFolder { get; set; }
/// <summary>로그 인코딩: auto / utf-8 / cp949</summary>
public string LogEncoding { get; set; } = "auto";
}
/// <summary>프로그램 설정 (settings.json)</summary>
public class AppSettings
{
public List<ServiceEntry> Services { get; set; } = new List<ServiceEntry>();
/// <summary>컴퓨터 시작 시 기동</summary>
public bool RunAtStartup { get; set; }
/// <summary>단축키 사용 여부</summary>
public bool HotkeyEnabled { get; set; } = true;
/// <summary>단축키 보조키 (System.Windows.Input.ModifierKeys 값)</summary>
public int HotkeyModifiers { get; set; } = 2 | 4; // Ctrl + Shift
/// <summary>단축키 키 (System.Windows.Input.Key 값)</summary>
public int HotkeyKey { get; set; } = 44; // Key.A
/// <summary>서비스 시작 시 로그보기 = 작업 로그를 화면 하단에 표시할지 여부</summary>
public bool ShowOperationLog { get; set; } = true;
/// <summary>로그창 띄우기 방식</summary>
public LogWindowMode LogWindowMode { get; set; } = LogWindowMode.Individual;
/// <summary>Esc 키 동작</summary>
public EscAction EscAction { get; set; } = EscAction.Tray;
/// <summary>Windows 강제종료 / 재시작 버튼 표시</summary>
public bool ShowShutdownButtons { get; set; } = true;
/// <summary>창 크기·위치</summary>
public double WindowLeft { get; set; } = double.NaN;
public double WindowTop { get; set; } = double.NaN;
public double WindowWidth { get; set; } = 1000;
public double WindowHeight { get; set; } = 720;
}
/// <summary>설정 파일 저장/불러오기</summary>
public static class SettingsStore
{
public static string DataFolder { get; } =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "JJServiceManager");
public static string SettingsPath => Path.Combine(DataFolder, "settings.json");
private static readonly JsonSerializerOptions Options = new JsonSerializerOptions
{
WriteIndented = true,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
Converters = { new JsonStringEnumConverter() }
};
public static AppSettings Load()
{
try
{
if (File.Exists(SettingsPath))
{
var json = File.ReadAllText(SettingsPath);
var s = JsonSerializer.Deserialize<AppSettings>(json, Options);
if (s != null)
{
s.Services ??= new List<ServiceEntry>();
return s;
}
}
}
catch
{
// 설정 파일이 손상된 경우 기본값 사용 (원본 파일은 지우지 않음)
}
return new AppSettings();
}
public static void Save(AppSettings settings)
{
try
{
Directory.CreateDirectory(DataFolder);
var tmp = SettingsPath + ".tmp";
File.WriteAllText(tmp, JsonSerializer.Serialize(settings, Options));
File.Copy(tmp, SettingsPath, true);
File.Delete(tmp);
}
catch
{
// 저장 실패는 무시 (다음 저장 때 다시 시도)
}
}
}
/// <summary>작업 로그를 날짜별 파일에 추가 기록 (삭제 기능 없음)</summary>
public static class OperationLogFile
{
private static readonly object Sync = new object();
public static string Folder => Path.Combine(SettingsStore.DataFolder, "logs");
public static void Append(DateTime time, string text)
{
try
{
lock (Sync)
{
Directory.CreateDirectory(Folder);
var path = Path.Combine(Folder, time.ToString("yyyy-MM-dd") + ".log");
File.AppendAllText(path, $"[{time:yyyy-MM-dd HH:mm:ss}] {text}{Environment.NewLine}");
}
}
catch
{
// 기록 실패는 무시
}
}
}
}