diff --git a/Etupirka/Etupirka.csproj b/Etupirka/Etupirka.csproj index 70b751b..5267fcd 100644 --- a/Etupirka/Etupirka.csproj +++ b/Etupirka/Etupirka.csproj @@ -165,6 +165,7 @@ + DatabaseConfigView.xaml diff --git a/Etupirka/MainWindow.xaml.cs b/Etupirka/MainWindow.xaml.cs index 5ae4ccc..722436d 100644 --- a/Etupirka/MainWindow.xaml.cs +++ b/Etupirka/MainWindow.xaml.cs @@ -182,17 +182,14 @@ private void OnHotKeyHandler_ErogeHelper(HotKey hotKey) #endregion private ObservableCollection items; - - //private Dictionary timeDict; - - private System.Windows.Threading.DispatcherTimer watchProcTimer; - + private System.Windows.Threading.DispatcherTimer watchProcTimer; private DBManager db; - + private ProcessInfoCache processInfoCache = new ProcessInfoCache(); + - public MainWindow() + public MainWindow() { if (Settings.Default.UpgradeRequired) @@ -216,8 +213,8 @@ public MainWindow() db = new DBManager(Utility.userDBPath); Utility.im = new InformationManager(Utility.infoDBPath); - items = new ObservableCollection(); - db.LoadGame(items); + items = new ObservableCollection(); + db.LoadGame(items); GameListView.ItemsSource = items; GameListView.SelectedItem = null; @@ -245,8 +242,8 @@ public MainWindow() } } - #region Function - private void doCheckUpdate() + #region Function + private void doCheckUpdate() { try { @@ -284,83 +281,84 @@ private void UpdateStatus(int time=0) Console.WriteLine(e); } - System.Console.WriteLine(calcID); bool play_flag = false; - this.Dispatcher.BeginInvoke( - new Action(() => - { - Process[] proc = Process.GetProcesses(); - - Dictionary dic = new Dictionary(); - foreach (Process p in proc) - { - try - { - string path = p.MainModule.FileName.ToLower(); - if (dic.ContainsKey(path)) - { - dic[path] |= p.Id == calcID; - } - else - { - dic.Add(p.MainModule.FileName.ToLower(), p.Id == calcID); - } - } - catch (Exception e) - { - // Console.WriteLine(e); - } - } - - string statusBarText = ""; - string trayTipText = "Etupirka Version " + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion; - - foreach (GameExecutionInfo i in items) - { - bool running = false; - if (i.UpdateStatus2(dic, ref running, time)) - // if (i.UpdateStatus(proc, calcID,ref running, time)) - { - if (time != 0) - { - //string date = DateTime.Now.Date.ToString("yyyy-MM-dd"); - - db.UpdateTimeNow(i.UID, time); - } - db.UpdateGameTimeInfo(i.UID, i.TotalPlayTime, i.FirstPlayTime, i.LastPlayTime); - if (i.Status == ProcStat.Focused) - { - play_flag = true; - PlayMessage.Content = i.Title + " : " + i.TotalPlayTimeString; - - if (Properties.Settings.Default.hideListWhenPlaying) - { - ErogeHelper = true; - } - } - } - System.Console.WriteLine(running); - if (running) - { - trayTipText += "\n" + i.Title + " : " + i.TotalPlayTimeString; - } - } - - dic.Clear(); - if (!play_flag) - { - PlayMessage.Content = statusBarText; - - if (Properties.Settings.Default.hideListWhenPlaying) - { - ErogeHelper = false; - } - } - tbico.ToolTipText = trayTipText; - - OnPropertyChanged("TotalTime"); - })); + this.Dispatcher.BeginInvoke(new Action(() => { + Process[] proc = Process.GetProcesses(); + + Dictionary dic = new Dictionary(); + using (var scopedAccess = processInfoCache.scopedAccess()) + { + foreach (Process p in proc) + { + try + { + string path = processInfoCache.getProcessPath(p); + if (path == "") + { + continue; + } + bool isForeground = p.Id == calcID; + if (dic.ContainsKey(path)) + { + dic[path] |= isForeground; + } + else + { + dic[path] = isForeground; + } + } + catch (Exception e) + { + // Console.WriteLine(e); + } + } + } + + string statusBarText = ""; + string trayTipText = "Etupirka Version " + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion; + + foreach (GameExecutionInfo i in items) + { + bool running = false; + if (i.UpdateStatus2(dic, ref running, time)) + { + if (time != 0) + { + db.UpdateTimeNow(i.UID, time); + } + db.UpdateGameTimeInfo(i.UID, i.TotalPlayTime, i.FirstPlayTime, i.LastPlayTime); + if (i.Status == ProcStat.Focused) + { + play_flag = true; + PlayMessage.Content = i.Title + " : " + i.TotalPlayTimeString; + + if (Properties.Settings.Default.hideListWhenPlaying) + { + ErogeHelper = true; + } + } + } + if (running) + { + trayTipText += "\n" + i.Title + " : " + i.TotalPlayTimeString; + } + } + + dic.Clear(); + if (!play_flag) + { + PlayMessage.Content = statusBarText; + + if (Properties.Settings.Default.hideListWhenPlaying) + { + ErogeHelper = false; + } + } + tbico.ToolTipText = trayTipText; + + OnPropertyChanged("TotalTime"); + })); } private void RegisterInStartup(bool isChecked) diff --git a/Etupirka/ProcessInfoCache.cs b/Etupirka/ProcessInfoCache.cs new file mode 100644 index 0000000..ebaaae8 --- /dev/null +++ b/Etupirka/ProcessInfoCache.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace Etupirka +{ + class ProcessInfo + { + public int id { get; set; } + + public string processName { get; set; } + + public string path { get; set; } + + // True if we have access to this process. + public bool accesible { get; set; } + + // True if the process info is pinned. Unpinned entries will be automatically cleaned up. + public bool pinned { get; set; } + } + + class ProcessInfoCleanup : IDisposable + { + public ProcessInfoCleanup(ProcessInfoCache cache) + { + this.cache = cache; + } + + public void Dispose() + { + cache.cleanUp(); + } + + private ProcessInfoCache cache; + } + + class ProcessInfoCache + { + // Returns an object that automatically cleans up process info that is not used in the scope. + public ProcessInfoCleanup scopedAccess() + { + foreach (var entry in processInfoById) + { + entry.Value.pinned = false; + } + + return new ProcessInfoCleanup(this); + } + + public void cleanUp() + { + var entriesToRemove = processInfoById.Where((entry) => !entry.Value.pinned).ToList(); + foreach (var entry in entriesToRemove) + { + processInfoById.Remove(entry.Key); + } + } + + // Returns the path of the process, or an empty string if the process is not accesible. + public string getProcessPath(Process p) + { + if (processInfoById.ContainsKey(p.Id)) + { + ProcessInfo info = processInfoById[p.Id]; + if (info.processName == p.ProcessName) + { + info.pinned = true; + return info.path; + } + } + + var processInfo = new ProcessInfo + { + id = p.Id, + accesible = false, + processName = p.ProcessName, + pinned = true + }; + + try + { + processInfo.path = p.MainModule.FileName.ToLower(); + processInfo.accesible = true; + } + catch { } + + processInfoById[p.Id] = processInfo; + return processInfo.path; + } + + private Dictionary processInfoById = new Dictionary(); + } +}