using System; using System.Windows.Forms; namespace ActivityRecorder { internal static class Program { // Main entry pt for system trap app [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new SystemTrayApplicationContext()); } } public class SystemTrayApplicationContext : ApplicationContext { private NotifyIcon trayIcon; private bool isRecording = false; private System.Windows.Forms.Timer captureTimer; private ScreenshotCapture screenshotCapture; private string dataDirectory; private InputMonitor inputMonitor; private DataUploader dataUploader; private PerformanceMonitor performanceMonitor; private HtmlViewer htmlViewer; public SystemTrayApplicationContext() { // Data dir setup dataDirectory = System.IO.Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ActivityRecorder" ); System.IO.Directory.CreateDirectory(dataDirectory); // Initialise screenshot capturer, input monitor, data uploader and timer screenshotCapture = new ScreenshotCapture(dataDirectory); inputMonitor = new InputMonitor(dataDirectory); dataUploader = new DataUploader(dataDirectory); captureTimer = new System.Windows.Forms.Timer { Interval = 5000 // Capture every 5 seconds }; captureTimer.Tick += CaptureTimer_Tick; // Initialise performance monitor and HTML viewer (added later) performanceMonitor = new PerformanceMonitor(dataDirectory); htmlViewer = new HtmlViewer(dataDirectory); // Create icon - future improvement could be to create my own trayIcon = new NotifyIcon() { Icon = System.Drawing.SystemIcons.Application, ContextMenuStrip = new ContextMenuStrip(), Visible = true, Text = "Activity Recorder" }; // Add menu items trayIcon.ContextMenuStrip.Items.Add("Start Recording", null, StartRecording); trayIcon.ContextMenuStrip.Items.Add("Stop Recording", null, StopRecording); trayIcon.ContextMenuStrip.Items.Insert(2, new ToolStripMenuItem("Upload Data", null, UploadData)); trayIcon.ContextMenuStrip.Items.Insert(3, new ToolStripMenuItem("View Data", null, ViewData)); trayIcon.ContextMenuStrip.Items.Add("-"); // code for separator trayIcon.ContextMenuStrip.Items.Add("Exit", null, Exit); UpdateMenuState(); // initialise menu states } private void CaptureTimer_Tick(object sender, EventArgs e) { string filename = screenshotCapture.CaptureScreen(); if (filename != null) { Console.WriteLine($"Screenshot saved: {filename}"); } } private void StartRecording(object sender, EventArgs e) { if (!isRecording) { isRecording = true; UpdateMenuState(); // Start input monitoring, timer, performance monitor inputMonitor.Start(); captureTimer.Start(); performanceMonitor.Start(); trayIcon.ShowBalloonTip(3000, "Activity Recorder", "Recording started", ToolTipIcon.Info); //when notifications are enabled } } private void StopRecording(object sender, EventArgs e) { if (isRecording) { // stop timer, input monitor, performance monitor captureTimer.Stop(); inputMonitor.Stop(); performanceMonitor.Stop(); isRecording = false; UpdateMenuState(); trayIcon.ShowBalloonTip(3000, "Activity Recorder", "Recording stopped", ToolTipIcon.Info); } } private async void UploadData(object sender, EventArgs e) { trayIcon.ShowBalloonTip(3000, "Activity Recorder", "Starting data upload...", ToolTipIcon.Info); await dataUploader.UploadAllData(); trayIcon.ShowBalloonTip(3000, "Activity Recorder", "Uploaded!", ToolTipIcon.Info); } private void ViewData(object sender, EventArgs e) { htmlViewer.GenerateViewer(); } private void Exit(object sender, EventArgs e) { trayIcon.Visible = false; Application.Exit(); } private void UpdateMenuState() { // Enable/disable menu options based on state of recording trayIcon.ContextMenuStrip.Items[0].Enabled = !isRecording; // Items[0] = Start rec trayIcon.ContextMenuStrip.Items[1].Enabled = isRecording; // Items[1] = Stop rec } protected override void Dispose(bool disposing) { if (disposing) { // Clean up open resources trayIcon.Dispose(); captureTimer.Dispose(); } base.Dispose(disposing); } } }