SEBWIN-312: Removed lazy loading of names for processes.

This commit is contained in:
dbuechel 2019-12-02 16:11:44 +01:00
parent df13e96dcd
commit 1ffb796963
2 changed files with 50 additions and 71 deletions

View file

@ -7,10 +7,6 @@
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.WindowsApi.Contracts;
using SafeExamBrowser.WindowsApi.Contracts.Events;
@ -19,32 +15,24 @@ namespace SafeExamBrowser.WindowsApi
{
internal class Process : IProcess
{
private bool eventInitialized, namesInitialized;
private bool eventInitialized;
private ILogger logger;
private string name, originalName;
private System.Diagnostics.Process process;
private event ProcessTerminatedEventHandler TerminatedEvent;
public int Id
{
get { return process.Id; }
}
public bool HasTerminated
{
get { return IsTerminated(); }
}
public string Name
public int Id
{
get { return namesInitialized ? name : InitializeNames().name; }
get { return process.Id; }
}
public string OriginalName
{
get { return namesInitialized ? originalName : InitializeNames().originalName; }
}
public string Name { get; }
public string OriginalName { get; }
private event ProcessTerminatedEventHandler TerminatedEvent;
public event ProcessTerminatedEventHandler Terminated
{
@ -52,17 +40,12 @@ namespace SafeExamBrowser.WindowsApi
remove { TerminatedEvent -= value; }
}
internal Process(System.Diagnostics.Process process, ILogger logger)
internal Process(System.Diagnostics.Process process, string name, string originalName, ILogger logger)
{
this.process = process;
this.logger = logger;
}
internal Process(System.Diagnostics.Process process, string name, string originalName, ILogger logger) : this(process, logger)
{
this.name = name;
this.originalName = originalName;
this.namesInitialized = true;
this.process = process;
this.Name = name;
this.OriginalName = originalName;
}
public bool TryClose(int timeout_ms = 0)
@ -144,42 +127,6 @@ namespace SafeExamBrowser.WindowsApi
}
}
private (string name, string originalName) InitializeNames()
{
name = process.ProcessName;
try
{
using (var searcher = new ManagementObjectSearcher($"SELECT Name, ExecutablePath FROM Win32_Process WHERE ProcessId = {process.Id}"))
using (var results = searcher.Get())
using (var processData = results.Cast<ManagementObject>().First())
{
var executablePath = Convert.ToString(processData["ExecutablePath"]);
name = Convert.ToString(processData["Name"]);
if (File.Exists(executablePath))
{
originalName = FileVersionInfo.GetVersionInfo(executablePath).OriginalFilename;
}
else
{
logger.Warn("Could not find original name!");
}
}
}
catch (Exception e)
{
logger.Error("Failed to initialize names!", e);
}
finally
{
namesInitialized = true;
}
return (name, originalName);
}
private bool WaitForTermination(int timeout_ms)
{
var terminated = process.WaitForExit(timeout_ms);

View file

@ -36,14 +36,14 @@ namespace SafeExamBrowser.WindowsApi
{
var processes = new List<IProcess>();
var running = System.Diagnostics.Process.GetProcesses();
var names = LoadProcessNames();
var names = LoadAllProcessNames();
foreach (var process in running)
{
var name = names.FirstOrDefault(n => n.processId == process.Id).name;
var originalName = names.FirstOrDefault(n => n.processId == process.Id).originalName;
processes.Add(new Process(process, name, originalName, LoggerFor(process)));
processes.Add(new Process(process, name, originalName, LoggerFor(process, name)));
}
return processes;
@ -64,7 +64,8 @@ namespace SafeExamBrowser.WindowsApi
raw = System.Diagnostics.Process.Start(path, string.Join(" ", args));
}
var process = new Process(raw, LoggerFor(raw));
var (name, originalName) = LoadProcessNamesFor(raw);
var process = new Process(raw, name, originalName, LoggerFor(raw, name));
logger.Info($"Successfully started process '{path}' with ID = {process.Id}.");
@ -102,13 +103,15 @@ namespace SafeExamBrowser.WindowsApi
if (raw != default(System.Diagnostics.Process))
{
process = new Process(raw, LoggerFor(raw));
var (name, originalName) = LoadProcessNamesFor(raw);
process = new Process(raw, name, originalName, LoggerFor(raw, name));
}
return process != default(IProcess);
}
private IEnumerable<(int processId, string name, string originalName)> LoadProcessNames()
private IEnumerable<(int processId, string name, string originalName)> LoadAllProcessNames()
{
var names = new List<(int, string, string)>();
@ -147,9 +150,38 @@ namespace SafeExamBrowser.WindowsApi
return names;
}
private ILogger LoggerFor(System.Diagnostics.Process process)
private (string name, string originalName) LoadProcessNamesFor(System.Diagnostics.Process process)
{
return logger.CloneFor($"{nameof(Process)} '{process.ProcessName}' ({process.Id})");
var name = process.ProcessName;
var originalName = default(string);
try
{
using (var searcher = new ManagementObjectSearcher($"SELECT Name, ExecutablePath FROM Win32_Process WHERE ProcessId = {process.Id}"))
using (var results = searcher.Get())
using (var processData = results.Cast<ManagementObject>().First())
{
var executablePath = Convert.ToString(processData["ExecutablePath"]);
name = Convert.ToString(processData["Name"]);
if (File.Exists(executablePath))
{
originalName = FileVersionInfo.GetVersionInfo(executablePath).OriginalFilename;
}
}
}
catch (Exception e)
{
logger.Error($"Failed to load process names for {process.ProcessName}!", e);
}
return (name, originalName);
}
private ILogger LoggerFor(System.Diagnostics.Process process, string name)
{
return logger.CloneFor($"{nameof(Process)} '{name}' ({process.Id})");
}
}
}