using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Card_Dispenser_Service { internal class Utils { static public readonly string _logFilePath = @"C:\Card Dispenser Service.txt"; static public readonly object _logLock = new object(); static public void LogToFile(string message) { try { lock (_logLock) { string logLine = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}{Environment.NewLine}"; File.AppendAllText(_logFilePath, logLine); } } catch { // Fail silently if the file is locked or unavailable to prevent the service from crashing } } static public void LogToFile(string message,string type) { try { lock (_logLock) { string logLine = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - [{type}]: {message}{Environment.NewLine}"; File.AppendAllText(_logFilePath, logLine); } } catch { // Fail silently if the file is locked or unavailable to prevent the service from crashing } } public static string GetLogContents() { if (!File.Exists(_logFilePath)) { return string.Empty; } try { // FileShare.ReadWrite prevents file locking conflicts with the background service thread using (var stream = new FileStream(_logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var reader = new StreamReader(stream, Encoding.UTF8)) { return reader.ReadToEnd(); } } catch (IOException) { // Fail gracefully if the OS temporarily blocks access return " [System Warning: Log file temporarily busy...]"; } } internal static void StringToArray(string hexStr, byte[] targetArray) { if (string.IsNullOrEmpty(hexStr)) return; // Pad with a leading zero if the hex string has an odd length if (hexStr.Length % 2 == 1) { hexStr = "0" + hexStr; } // Determine how many bytes we can safely copy without overrunning the target array int byteCount = Math.Min(hexStr.Length / 2, targetArray.Length); for (int i = 0; i < byteCount; i++) { // Extract 2 hex characters and convert them to a single byte targetArray[i] = Convert.ToByte(hexStr.Substring(i * 2, 2), 16); } } internal static void ClearLog() { if (!File.Exists(_logFilePath)) { return; } try { // FileMode.Truncate instantly wipes out the text, leaving an empty file, // while FileShare.ReadWrite prevents collisions with the background API thread. using (var stream = new FileStream(_logFilePath, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite)) { // Stream closes immediately after wiping the data cleanly } } catch (IOException) { // Fallback: If the OS is heavily locking the file, try a direct write wipe try { File.WriteAllText(_logFilePath, string.Empty); } catch (Exception ex) { LogToFile($"[System Error] Failed to clear log file: {ex.Message}"); } } } } }