SEBWIN-312: Removed lazy loading of names for processes.
This commit is contained in:
parent
df13e96dcd
commit
1ffb796963
2 changed files with 50 additions and 71 deletions
|
@ -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);
|
||||
|
|
|
@ -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})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue