Time usage saved from a process is not properly stored/shown

20 Views Asked by At

The time saved on the log.txt file and later shown through the View Time Logs menu option is completely inaccurate, I have tried several methods but none of them store the time correctly. I have restarted my pc and the log file several times with no result. Here is the main file

class Program
{
    static void Main(string[] args)
    {
        Console.Clear();


        startupApp startupApp = new startupApp();
        startupApp.startup();


        Console.WriteLine("Welcome to PTimeTrack");
        Thread.Sleep(1000);


        List<string> ignoredProcessLines = UserIgnoredProcesses();
        TimeLogger timeLogger = new TimeLogger(); // Create an instance of the TimeLogger class


        while (true)
        {
            Console.Clear();
            Process[] processes = Process.GetProcesses();

            foreach (Process process in processes)
            {
                bool isIgnored = IsProcessIgnored(process, ignoredProcessLines);


                if (!isIgnored && !string.IsNullOrEmpty(process.MainWindowTitle))
                {
                    Console.WriteLine($"Process Name: {process.ProcessName}, Window Title: {process.MainWindowTitle}");
                    TimeSpan programRunningTime = DateTime.Now - process.StartTime; // Calculate the running time
                    Console.WriteLine($"Running Time: {programRunningTime.ToString(@"hh\:mm\:ss")} \n");

                    string formattedRunningTime = $"{programRunningTime.Hours:00}:{programRunningTime.Minutes:00}:{programRunningTime.Seconds:00}";

                    // Pass the formatted running time to the LogTime method
                    timeLogger.LogTime(process.ProcessName, TimeSpan.Parse(formattedRunningTime), ignoredProcessLines);
                }

            }

            Console.WriteLine("Press the ENTER key to bring up the menu");
            if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Enter)
            {
                ShowMenu();
            }
            Thread.Sleep(2000); // Pause execution for 10 seconds
        }

        static List<string> UserIgnoredProcesses()
        {
            List<string> ignoredProcessLines = new List<string>();

            string fileName = "ignoredprocesses.txt";
            string projectFolder = Directory.GetCurrentDirectory();
            int index = projectFolder.IndexOf("\\bin\\Debug\\net8.0");
            if (index != -1)
            {
                projectFolder = projectFolder.Substring(0, index); // Remove the bin\Debug\net8.0 part
            }
            string filePath = Path.Combine(projectFolder, fileName);

            if (File.Exists(filePath))
            {
                Console.WriteLine("Ignored processes file found. Reading ignored processes...");
                using (StreamReader reader = new StreamReader(filePath))
                {
                    string line;
                    // Read each line of the file until the end
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line.StartsWith("#")) // Ignore comments
                        {
                            continue;
                        }


                        // Process each line here
                        ignoredProcessLines.Add(line);


                    }
                }
            }
            return ignoredProcessLines;
        }
        static bool IsProcessIgnored(Process process, List<string> ignoredProcessLines)
        {
            string processDetails = process.ToString().ToLower();
            foreach (string ignoredLine in ignoredProcessLines)
            {
                if (processDetails.Contains(ignoredLine.ToLower()))
                {
                    return true;
                }
            }
            return false;
        }
        static void ShowMenu()
        {
            Console.Clear();
            Console.WriteLine("MENU\n\n");
            Console.WriteLine("1) Go Back");
            Console.WriteLine("2) Info");
            Console.WriteLine("3) View Time Logs");
            Console.WriteLine("4) License");
            Console.WriteLine("5) Credits");
            Console.WriteLine("6) Exit\n");
            Console.WriteLine("Type in your choice: ");
            string choice = Console.ReadLine();
            switch (choice)
            {
                case "1":
                    Console.Clear();
                    break;
                case "2":
                    Console.Clear();
                    break;
                case "3":
                    Console.Clear();
                    TimeLogger timeLogger = new TimeLogger(); //must create new instance of the class so that the method can be called
                    timeLogger.ViewTimeLogs();
                    Console.WriteLine("\n\nPress the ENTER key to bring up the menu");
                    if (Console.ReadKey().Key == ConsoleKey.Enter)
                    { break; }
                    break;
                case "4":
                    Console.Clear();
                    break;
                    break;
                case "5":
                    Console.Clear();
                    break;
                case "6":
                    Environment.Exit(0);
                    break;
                default:
                    Console.Clear();
                    Console.WriteLine("Invalid choice. Please try again.");
                    break;
            }
        }
    }

}

And here's the Time Logging class

using System;
using System.Diagnostics;
using System.IO;

namespace programTimeCounter
{
    public class TimeLogger
    {
        public void LogTime(string processName, TimeSpan runningTime, List<string> ignoredProcessLines) //get all inputs from the main program
        {
            string logfileName = "log.txt";
            string projectFolder = Directory.GetCurrentDirectory();
            int index = projectFolder.IndexOf("\\bin\\Debug\\net8.0");
            if (index != -1)
            {
                projectFolder = projectFolder.Substring(0, index); // Remove the bin\Debug\net8.0 part
            }
            string logFilePath = Path.Combine(projectFolder, logfileName);

            try
            {
                Dictionary<string, TimeSpan> processRunningTimes = new Dictionary<string, TimeSpan>();


                // Read existing total time from the file if it exists
                if (File.Exists(logFilePath))
                {
                    string[] lines = File.ReadAllLines(logFilePath);
                    foreach (string line in lines)
                    {
                        string[] parts = line.Split(';');

                        if (parts.Length >= 2)
                        {
                            string name = parts[0].Trim();
                            string timeStr = parts[1].Trim();
                            if (TimeSpan.TryParse(timeStr, out TimeSpan processTotalTime))
                            {
                                // Add process name and total time to the dictionary
                                processRunningTimes[name] = processTotalTime;
                            }
                        }
                    }

                    // Update the total running time for the current process
                    if (processRunningTimes.ContainsKey(processName))
                    {
                        TimeSpan currentRunningTime = (DateTime.Now - Process.GetProcessesByName(processName).FirstOrDefault()?.StartTime) ?? TimeSpan.Zero; //defauts to timespan.zero if starttime is null


                        processRunningTimes[processName] += currentRunningTime;
                    }
                    else
                    {
                        processRunningTimes[processName] = runningTime; //if there isn't anything it will set the current one as the running time
                    }

                    // Construct the log entry with total time for each process
                    string logEntry = string.Join("\n", processRunningTimes.Select(kvp => $"{kvp.Key}; {kvp.Value:dd\\:hh\\:mm\\:ss}"));


                    // Write the log entry to the log file
                    File.WriteAllText(logFilePath, logEntry);

                    Console.WriteLine("Time logged successfully.");

                }

            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error logging time: {ex.Message}");
            }
        }
       
        public void ViewTimeLogs()
        {
            string logFileName = "log.txt";
            string projectFolder = Directory.GetCurrentDirectory();
            int index = projectFolder.IndexOf("\\bin\\Debug\\net8.0");
            if (index != -1)
            {
                projectFolder = projectFolder.Substring(0, index); // Remove the bin\Debug\net8.0 part
            }
            string logFilePath = Path.Combine(projectFolder, logFileName);

            try
            {
                if (File.Exists(logFilePath))
                {
                    //Read content from the files
                    string[] logLines = File.ReadAllLines(logFilePath);

                    Console.WriteLine("Time logs:");
                    //display the content of the log file
                    foreach (string logLine in logLines)
                    {
                        string[] parts = logLine.Split(';');
                        if (parts.Length >= 2)
                        {
                            string processName = parts[0].Trim();
                            TimeSpan totalTime = TimeSpan.Parse(parts[1].Trim());
                            Console.WriteLine($"{processName}: {FormatTimeSpan(totalTime)}");
                            
                        }
                    }
                }
                else
                {
                    Console.WriteLine("No time logs found.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error viewing time logs: {ex.Message}");
            }
        }
        
        private static string FormatTimeSpan(TimeSpan timeSpan)
        {
            return $"{(int)timeSpan.TotalDays:D2} days {timeSpan.Hours:D2} hours {timeSpan.Minutes:D2} minutes {timeSpan.Seconds:D2} seconds";

        }
    }

}

The log file and View Time Logs output this:

devenv: 00 days 00 hours 08 minutes 54 seconds TextInputHost: 00 days 07 hours 25 minutes 24 seconds WindowsTerminal: 00 days 00 hours 05 minutes 20 seconds Spotify: 00 days 07 hours 21 minutes 08 seconds Discord: 00 days 07 hours 18 minutes 06 seconds ApplicationFrameHost: 00 days 07 hours 16 minutes 59 seconds SystemSettings: 00 days 07 hours 09 minutes 46 seconds HxOutlook: 00 days 07 hours 09 minutes 24 seconds SnippingTool: 00 days 04 hours 07 minutes 17 seconds firefox: 00 days 00 hours 20 minutes 25 seconds GitHubDesktop: 00 days 00 hours 03 minutes 11 seconds

The problem is that the time is off by quite a sizeable amount as sometimes it can be off by a couple of minutes or even hours. So it doesn't make any sense as why it does that.

0

There are 0 best solutions below