feat: make service paths and lifecycle Windows-Service safe
Exe-relative paths + graceful timer shutdown / job isolation.main
parent
0773ee3311
commit
9da7d1b003
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace HanvonF710XAttendanceService
|
||||
{
|
||||
internal static class ApplicationPaths
|
||||
{
|
||||
public static string BaseDirectory { get; private set; } = AppDomain.CurrentDomain.BaseDirectory ?? "";
|
||||
|
||||
public static string InternalLogs => Path.Combine(BaseDirectory, "InternalLogs");
|
||||
public static string Logs => Path.Combine(BaseDirectory, "Logs");
|
||||
public static string TemplateRawLogs => Path.Combine(BaseDirectory, "TemplateRawLogs");
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
BaseDirectory = AppDomain.CurrentDomain.BaseDirectory ?? "";
|
||||
try
|
||||
{
|
||||
Environment.CurrentDirectory = BaseDirectory;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Best effort; paths below are always rooted to BaseDirectory.
|
||||
}
|
||||
|
||||
EnsureDirectory(InternalLogs);
|
||||
EnsureDirectory(Logs);
|
||||
EnsureDirectory(TemplateRawLogs);
|
||||
EnsureDirectory(Path.Combine(Logs, "Attendance"));
|
||||
EnsureDirectory(Path.Combine(Logs, "Machine User service"));
|
||||
EnsureDirectory(Path.Combine(Logs, "SaveFaceTemplate logs"));
|
||||
EnsureDirectory(Path.Combine(Logs, "FaceTransferLog"));
|
||||
}
|
||||
|
||||
public static string Resolve(string relativeOrAbsolutePath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(relativeOrAbsolutePath))
|
||||
{
|
||||
return BaseDirectory;
|
||||
}
|
||||
|
||||
string trimmed = relativeOrAbsolutePath.Trim();
|
||||
return Path.IsPathRooted(trimmed)
|
||||
? trimmed
|
||||
: Path.Combine(BaseDirectory, trimmed);
|
||||
}
|
||||
|
||||
public static string DatedFile(string directory, string filePrefix)
|
||||
{
|
||||
string datePart = DateTime.Now.Date.ToShortDateString().Replace('/', '_');
|
||||
return Path.Combine(directory, filePrefix + "_" + datePart + ".txt");
|
||||
}
|
||||
|
||||
private static void EnsureDirectory(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,48 +16,35 @@ namespace HanvonF710XAttendanceService
|
|||
{
|
||||
public partial class HanvonF710XWindowsService : ServiceBase
|
||||
{
|
||||
// Separate timers for attendance/users and template sync.
|
||||
System.Timers.Timer timer = new System.Timers.Timer(); // attendance + users
|
||||
System.Timers.Timer timer1 = new System.Timers.Timer(); // templates
|
||||
private System.Timers.Timer timer = new System.Timers.Timer();
|
||||
private System.Timers.Timer timer1 = new System.Timers.Timer();
|
||||
|
||||
// Independent locks/flags so jobs don't block each other.
|
||||
private static readonly object _attendanceLock = new object();
|
||||
private static readonly object _templateLock = new object();
|
||||
private static bool _attendanceJobRunning = false;
|
||||
private static bool _templateJobRunning = false;
|
||||
private static volatile bool _attendanceJobRunning;
|
||||
private static volatile bool _templateJobRunning;
|
||||
private volatile bool _stopping;
|
||||
|
||||
public HanvonF710XWindowsService()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>Starts timers and jobs when running outside the Windows Service Control Manager.</summary>
|
||||
public void StartForConsole(string[] args)
|
||||
{
|
||||
OnStart(args ?? Array.Empty<string>());
|
||||
}
|
||||
|
||||
/// <summary>Stops timers and flushes logs when running in console/debug mode.</summary>
|
||||
public void StopForConsole()
|
||||
{
|
||||
OnStop();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
// So the service finds HwDevComm.dll (and sibling DLLs) in the EXE folder
|
||||
string exeDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||
try
|
||||
{
|
||||
Environment.CurrentDirectory = exeDir;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { WriteInternalLog("OnStart set CurrentDirectory failed: " + ex.Message); } catch { }
|
||||
}
|
||||
ApplicationPaths.Initialize();
|
||||
|
||||
// Start buffered, cross-process-safe logging.
|
||||
try { LogService.Start(); } catch { }
|
||||
try { LogService.Start(); } catch (Exception ex) { Program.WriteInternalLog("LogService.Start failed: " + ex.Message); }
|
||||
|
||||
WriteToFile("--Service is started at " + DateTime.Now);
|
||||
WriteInternalLog("--Service is started at " + DateTime.Now);
|
||||
|
|
@ -72,12 +59,12 @@ namespace HanvonF710XAttendanceService
|
|||
double attendanceIntervalMs = Math.Max(1, attendanceMinutes) * 60 * 1000;
|
||||
double templateIntervalMs = Math.Max(1, templateMinutes) * 60 * 1000;
|
||||
|
||||
timer.Elapsed += new ElapsedEventHandler(OnAttendanceElapsed);
|
||||
timer.Elapsed += OnAttendanceElapsed;
|
||||
timer.Interval = attendanceIntervalMs;
|
||||
timer.AutoReset = true;
|
||||
timer.Enabled = true;
|
||||
|
||||
timer1.Elapsed += new ElapsedEventHandler(OnTemplateElapsed);
|
||||
timer1.Elapsed += OnTemplateElapsed;
|
||||
timer1.Interval = templateIntervalMs;
|
||||
timer1.AutoReset = true;
|
||||
timer1.Enabled = true;
|
||||
|
|
@ -87,42 +74,117 @@ namespace HanvonF710XAttendanceService
|
|||
WriteToFile($"Attendance job interval: {attendanceMinutes} minutes");
|
||||
WriteToFile($"Template job interval: {templateMinutes} minutes");
|
||||
|
||||
// Run both jobs once immediately on startup (non-blocking).
|
||||
// Uses the same guarded execution path as the timer callbacks.
|
||||
try
|
||||
{
|
||||
WriteInternalLog("--Startup trigger: running attendance job immediately at " + DateTime.Now);
|
||||
Task.Run(() => RunAttendanceJob());
|
||||
Task.Run(() => RunStartupAttendanceJob());
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("Startup attendance trigger failed: " + ex.Message);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int delaySec = 30;
|
||||
WriteInternalLog("--Startup trigger: running template job after " + delaySec + "s at " + DateTime.Now);
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(delaySec * 1000).ConfigureAwait(false);
|
||||
RunTemplateJob();
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
Task.Run(() => RunStartupTemplateJob(delaySec));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("Startup template trigger failed: " + ex.Message);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
WriteToFile("--Service is stopped at " + DateTime.Now);
|
||||
_stopping = true;
|
||||
WriteToFile("--Service is stopping at " + DateTime.Now);
|
||||
WriteInternalLog("--Service is stopping at " + DateTime.Now);
|
||||
|
||||
try
|
||||
{
|
||||
timer.Enabled = false;
|
||||
timer1.Enabled = false;
|
||||
timer.Elapsed -= OnAttendanceElapsed;
|
||||
timer1.Elapsed -= OnTemplateElapsed;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("OnStop timer shutdown failed: " + ex.Message);
|
||||
}
|
||||
|
||||
WaitForRunningJobs();
|
||||
|
||||
try
|
||||
{
|
||||
timer.Dispose();
|
||||
timer1.Dispose();
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("OnStop timer dispose failed: " + ex.Message);
|
||||
}
|
||||
|
||||
try { LogService.StopAndFlush(TimeSpan.FromSeconds(5)); } catch { }
|
||||
|
||||
WriteToFile("--Service is stopped at " + DateTime.Now);
|
||||
WriteInternalLog("--Service is stopped at " + DateTime.Now);
|
||||
}
|
||||
|
||||
private void WaitForRunningJobs()
|
||||
{
|
||||
int waitSeconds = GetIntConfig("SERVICE_SHUTDOWN_WAIT_SECONDS", 300);
|
||||
if (waitSeconds <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deadline = DateTime.UtcNow.AddSeconds(waitSeconds);
|
||||
while ((_attendanceJobRunning || _templateJobRunning) && DateTime.UtcNow < deadline)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
if (_attendanceJobRunning || _templateJobRunning)
|
||||
{
|
||||
WriteInternalLog($"--Service stop: jobs still running after {waitSeconds}s (attendance={_attendanceJobRunning}, template={_templateJobRunning})");
|
||||
}
|
||||
}
|
||||
|
||||
private void RunStartupAttendanceJob()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_stopping)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunAttendanceJob();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("Startup attendance job error: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunStartupTemplateJob(int delaySec)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(Math.Max(0, delaySec) * 1000).ConfigureAwait(false);
|
||||
if (_stopping)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunTemplateJob();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("Startup template job error: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetIntConfig(string key, int defaultValue)
|
||||
|
|
@ -139,7 +201,6 @@ namespace HanvonF710XAttendanceService
|
|||
}
|
||||
}
|
||||
|
||||
// Attendance + machine-user job
|
||||
private void OnAttendanceElapsed(object source, ElapsedEventArgs e)
|
||||
{
|
||||
RunAttendanceJob();
|
||||
|
|
@ -147,11 +208,18 @@ namespace HanvonF710XAttendanceService
|
|||
|
||||
private void RunAttendanceJob()
|
||||
{
|
||||
if (_stopping)
|
||||
{
|
||||
WriteInternalLog("--Attendance tick skipped (service stopping) at " + DateTime.Now);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Monitor.TryEnter(_attendanceLock))
|
||||
{
|
||||
WriteInternalLog("--Attendance tick skipped (previous attendance job still running) at " + DateTime.Now);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (_attendanceJobRunning)
|
||||
|
|
@ -159,6 +227,7 @@ namespace HanvonF710XAttendanceService
|
|||
WriteInternalLog("--Attendance tick skipped (previous attendance job still running) at " + DateTime.Now);
|
||||
return;
|
||||
}
|
||||
|
||||
_attendanceJobRunning = true;
|
||||
|
||||
WriteSyncCycleHeader();
|
||||
|
|
@ -172,32 +241,42 @@ namespace HanvonF710XAttendanceService
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("syncMachineUsers error: " + ex.Message);
|
||||
WriteInternalLog("syncMachineUsers error: " + ex);
|
||||
WriteMachineUserServiceLog("syncMachineUsers error: " + ex.Message);
|
||||
}
|
||||
|
||||
if (_stopping)
|
||||
{
|
||||
WriteInternalLog("--Attendance job interrupted (service stopping) before attendance sync at " + DateTime.Now);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
syncAttendance();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("syncAttendance error: " + ex.Message);
|
||||
WriteInternalLog("syncAttendance error: " + ex);
|
||||
WriteAttendanceServiceLog("syncAttendance error: " + ex.Message);
|
||||
}
|
||||
|
||||
WriteInternalLog("--Attendance job finished at " + DateTime.Now);
|
||||
WriteAttendanceServiceLog("--Attendance job finished at " + DateTime.Now);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("--Attendance job failed: " + ex);
|
||||
WriteAttendanceServiceLog("--Attendance job failed: " + ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { Program.EndSyncCycle(); } catch { }
|
||||
try { Program.EndSyncCycle(); } catch (Exception ex) { WriteInternalLog("EndSyncCycle error: " + ex.Message); }
|
||||
_attendanceJobRunning = false;
|
||||
Monitor.Exit(_attendanceLock);
|
||||
}
|
||||
}
|
||||
|
||||
// Template job
|
||||
private void OnTemplateElapsed(object source, ElapsedEventArgs e)
|
||||
{
|
||||
RunTemplateJob();
|
||||
|
|
@ -205,11 +284,18 @@ namespace HanvonF710XAttendanceService
|
|||
|
||||
private void RunTemplateJob()
|
||||
{
|
||||
if (_stopping)
|
||||
{
|
||||
WriteInternalLog("--Template tick skipped (service stopping) at " + DateTime.Now);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Monitor.TryEnter(_templateLock))
|
||||
{
|
||||
WriteInternalLog("--Template tick skipped (previous template job still running) at " + DateTime.Now);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (_templateJobRunning)
|
||||
|
|
@ -217,6 +303,7 @@ namespace HanvonF710XAttendanceService
|
|||
WriteInternalLog("--Template tick skipped (previous template job still running) at " + DateTime.Now);
|
||||
return;
|
||||
}
|
||||
|
||||
_templateJobRunning = true;
|
||||
|
||||
WriteJobHeaderToSimpleLogs("TEMPLATE");
|
||||
|
|
@ -229,14 +316,21 @@ namespace HanvonF710XAttendanceService
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("syncTemplatesIfEnabled error: " + ex.ToString());
|
||||
WriteFaceTemplateTransferLog("syncTemplatesIfEnabled error: " + ex.ToString());
|
||||
WriteSaveFaceTemplateLog("syncTemplatesIfEnabled error: " + ex.ToString());
|
||||
WriteInternalLog("syncTemplatesIfEnabled error: " + ex);
|
||||
WriteFaceTemplateTransferLog("syncTemplatesIfEnabled error: " + ex);
|
||||
WriteSaveFaceTemplateLog("syncTemplatesIfEnabled error: " + ex);
|
||||
}
|
||||
|
||||
WriteInternalLog("--Template job finished at " + DateTime.Now);
|
||||
WriteSaveFaceTemplateLog("--Template job finished at " + DateTime.Now);
|
||||
WriteFaceTemplateTransferLog("--Template job finished at " + DateTime.Now);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteInternalLog("--Template job failed: " + ex);
|
||||
WriteFaceTemplateTransferLog("--Template job failed: " + ex.Message);
|
||||
WriteSaveFaceTemplateLog("--Template job failed: " + ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_templateJobRunning = false;
|
||||
|
|
@ -244,11 +338,8 @@ namespace HanvonF710XAttendanceService
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void syncAttendance()
|
||||
{
|
||||
|
||||
|
||||
WriteToFile("--Sync Attendance is recall at " + DateTime.Now);
|
||||
WriteInternalLog("--Sync Attendance is recall at " + DateTime.Now);
|
||||
WriteAttendanceServiceLog("--Sync Attendance is recall at " + DateTime.Now);
|
||||
|
|
@ -258,17 +349,15 @@ namespace HanvonF710XAttendanceService
|
|||
WriteToFile(response);
|
||||
WriteInternalLog(response);
|
||||
|
||||
// Attendance simple log: only machine-level results and connectivity.
|
||||
if (IsAttendanceSimpleLine(response))
|
||||
{
|
||||
WriteAttendanceServiceLog(response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void syncMachineUsers()
|
||||
{
|
||||
|
||||
WriteToFile("--Sync Machine users is recall at " + DateTime.Now);
|
||||
WriteInternalLog("--Sync Machine users is recall at " + DateTime.Now);
|
||||
WriteMachineUserServiceLog("--Sync Machine users is recall at " + DateTime.Now);
|
||||
|
|
@ -278,43 +367,38 @@ namespace HanvonF710XAttendanceService
|
|||
WriteToFile(response);
|
||||
WriteInternalLog(response);
|
||||
|
||||
// Machine user simple log: only machine totals and connectivity.
|
||||
if (IsMachineUserSimpleLine(response))
|
||||
{
|
||||
WriteMachineUserServiceLog(response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void syncTemplatesIfEnabled()
|
||||
{
|
||||
WriteToFile("--Template sync is recall at " + DateTime.Now);
|
||||
WriteInternalLog("--Template sync is recall at " + DateTime.Now);
|
||||
// We'll route template logs into either SaveFaceTemplate or FaceTransfer logs based on TRANSFER_MODE.
|
||||
List<string> responses = Program.syncTemplates();
|
||||
foreach (var response in responses)
|
||||
{
|
||||
WriteToFile(response);
|
||||
WriteInternalLog(response);
|
||||
|
||||
// SaveFaceTemplate logs: DEVICE_TO_DB and any "Serial number--" lines.
|
||||
if (IsSaveFaceTemplateLine(response))
|
||||
{
|
||||
WriteSaveFaceTemplateLog(response);
|
||||
}
|
||||
|
||||
// FaceTransfer logs: DB_TO_DEVICE / DEVICE_TO_DEVICE and connectivity issues.
|
||||
if (IsFaceTransferLine(response))
|
||||
{
|
||||
WriteFaceTemplateTransferLog(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteToFile(string Message)
|
||||
{
|
||||
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" +
|
||||
DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
|
||||
string filepath = ApplicationPaths.DatedFile(ApplicationPaths.Logs, "ServiceLog");
|
||||
LogService.EnqueueLine(filepath, Message);
|
||||
}
|
||||
|
||||
|
|
@ -336,7 +420,6 @@ namespace HanvonF710XAttendanceService
|
|||
WriteInternalLog(line3);
|
||||
WriteInternalLog(line4);
|
||||
|
||||
// Simple per-feature logs (keep InternalLogs unchanged).
|
||||
WriteAttendanceServiceLog(line1);
|
||||
WriteAttendanceServiceLog(line2);
|
||||
WriteAttendanceServiceLog(line3);
|
||||
|
|
@ -348,8 +431,6 @@ namespace HanvonF710XAttendanceService
|
|||
WriteMachineUserServiceLog(line4);
|
||||
}
|
||||
|
||||
// Ensures per-feature simple logs have a header even when a job doesn't call WriteSyncCycleHeader.
|
||||
// Used by template job.
|
||||
private void WriteJobHeaderToSimpleLogs(string jobName)
|
||||
{
|
||||
string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
|
@ -375,7 +456,6 @@ namespace HanvonF710XAttendanceService
|
|||
private static bool IsAttendanceSimpleLine(string line)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line)) return false;
|
||||
// Keep only the machine summary lines.
|
||||
if (line.IndexOf(" has ", StringComparison.OrdinalIgnoreCase) >= 0 &&
|
||||
line.IndexOf(" records", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf(" is not connected", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
|
|
@ -385,7 +465,6 @@ namespace HanvonF710XAttendanceService
|
|||
private static bool IsMachineUserSimpleLine(string line)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line)) return false;
|
||||
// Keep only "MACHINE X -> N", "X removed from MACHINE Y", and connectivity lines.
|
||||
if (line.IndexOf(" -> ", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf(" removed from ", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf(" is not connected", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
|
|
@ -404,13 +483,11 @@ namespace HanvonF710XAttendanceService
|
|||
private static bool IsFaceTransferLine(string line)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line)) return false;
|
||||
// Any transfer mode other than DEVICE_TO_DB and connectivity issues.
|
||||
if (line.IndexOf("DB_TO_DEVICE", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf("DEVICE_TO_DEVICE", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf("[DB_TO_DEVICE]", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf("TemplateDistribution", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf("TemplateRegistrationTargets", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
// Peer distribution uses job id "TemplateDist:<ip>" in [TemplateJob ...] lines from GetEmployeeID on targets.
|
||||
if (line.IndexOf("TemplateDist:", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf("SetEmployee", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
if (line.IndexOf(" is not connected", StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
|
|
@ -419,10 +496,7 @@ namespace HanvonF710XAttendanceService
|
|||
|
||||
private static void AppendLineToDatedLog(string folderName, string filePrefix, string message)
|
||||
{
|
||||
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||
string logsRoot = Path.Combine(baseDir, "Logs");
|
||||
string folderPath = Path.Combine(logsRoot, folderName);
|
||||
|
||||
string folderPath = Path.Combine(ApplicationPaths.Logs, folderName);
|
||||
string datePart = DateTime.Now.ToString("yyyy-MM-dd");
|
||||
string filePath = Path.Combine(folderPath, filePrefix + "_" + datePart + ".txt");
|
||||
LogService.EnqueueLine(filePath, message);
|
||||
|
|
@ -447,11 +521,10 @@ namespace HanvonF710XAttendanceService
|
|||
{
|
||||
AppendLineToDatedLog("FaceTransferLog", "FaceTransferLogs", message);
|
||||
}
|
||||
|
||||
public void WriteInternalLog(string Message)
|
||||
{
|
||||
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\InternalLogs\\InternalLog_" +
|
||||
DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
|
||||
LogService.EnqueueLine(filepath, Message);
|
||||
Program.WriteInternalLog(Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue