diff --git a/MemTestHelper2/App.config b/MemTestHelper2/App.config
index 191a322..4339f7b 100644
--- a/MemTestHelper2/App.config
+++ b/MemTestHelper2/App.config
@@ -1,9 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MemTestHelper2/FodyWeavers.xml b/MemTestHelper2/FodyWeavers.xml
new file mode 100644
index 0000000..a5dcf04
--- /dev/null
+++ b/MemTestHelper2/FodyWeavers.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/MemTestHelper2/FodyWeavers.xsd b/MemTestHelper2/FodyWeavers.xsd
new file mode 100644
index 0000000..44a5374
--- /dev/null
+++ b/MemTestHelper2/FodyWeavers.xsd
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+ A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
+
+
+
+
+ A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
+
+
+
+
+ A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
+
+
+
+
+ A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
+
+
+
+
+ The order of preloaded assemblies, delimited with line breaks.
+
+
+
+
+
+ This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
+
+
+
+
+ Controls if .pdbs for reference assemblies are also embedded.
+
+
+
+
+ Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
+
+
+
+
+ As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
+
+
+
+
+ Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
+
+
+
+
+ Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
+
+
+
+
+ A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
+
+
+
+
+ A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
+
+
+
+
+ A list of unmanaged 32 bit assembly names to include, delimited with |.
+
+
+
+
+ A list of unmanaged 64 bit assembly names to include, delimited with |.
+
+
+
+
+ The order of preloaded assemblies, delimited with |.
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/MemTestHelper2/MainWindow.xaml b/MemTestHelper2/MainWindow.xaml
index fe58154..1199906 100644
--- a/MemTestHelper2/MainWindow.xaml
+++ b/MemTestHelper2/MainWindow.xaml
@@ -35,7 +35,7 @@
-
+
@@ -62,28 +62,27 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/MemTestHelper2/MainWindow.xaml.cs b/MemTestHelper2/MainWindow.xaml.cs
index 9a01b7a..dbb35fc 100644
--- a/MemTestHelper2/MainWindow.xaml.cs
+++ b/MemTestHelper2/MainWindow.xaml.cs
@@ -23,11 +23,14 @@ namespace MemTestHelper2
{
public partial class MainWindow : MetroWindow
{
+ private const string VERSION = "2.1.0";
private readonly int NUM_THREADS, MAX_THREADS;
// Update interval (in ms) for coverage info list.
private const int UPDATE_INTERVAL = 200;
+ private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
+
private MemTest[] memtests;
private MemTestInfo[] memtestInfo;
private BackgroundWorker coverageWorker;
@@ -38,8 +41,12 @@ public partial class MainWindow : MetroWindow
public MainWindow()
{
InitializeComponent();
+ lblVersion.Content = $"Version {VERSION}";
+
+ log.Info($"Starting MemTestHelper v{VERSION}");
NUM_THREADS = Convert.ToInt32(Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS"));
+ log.Info($"CPU Threads: {NUM_THREADS}");
MAX_THREADS = NUM_THREADS * 4;
memtests = new MemTest[MAX_THREADS];
// Index 0 stores the total.
@@ -130,6 +137,7 @@ private void Window_Closing(object sender, CancelEventArgs e)
{
CloseMemTests();
SaveConfig();
+ log.Info("Closing MemTestHelper");
}
private void Window_StateChanged(object sender, EventArgs e)
@@ -172,7 +180,7 @@ private void Window_StateChanged(object sender, EventArgs e)
}
// User may have changed offsets while minimised.
- LayOutMemTests();
+ LayoutMemTests();
// Hack to bring form to top.
Topmost = true;
@@ -200,14 +208,13 @@ private void btnStart_Click(object sender, RoutedEventArgs e)
btnStop.IsEnabled = true;
chkStopAt.IsEnabled = false;
txtStopAt.IsEnabled = false;
- chkStopAtTotal.IsEnabled = false;
chkStopOnError.IsEnabled = false;
chkStartMin.IsEnabled = false;
// Run in background as StartMemTests() can block.
RunInBackground(() =>
{
- StartMemTests();
+ if (!StartMemTests()) return;
if (!coverageWorker.IsBusy)
coverageWorker.RunWorkerAsync();
@@ -236,10 +243,7 @@ private void btnStop_Click(object sender, RoutedEventArgs e)
btnStop.IsEnabled = false;
chkStopAt.IsEnabled = true;
if (chkStopAt.IsEnabled)
- {
txtStopAt.IsEnabled = true;
- chkStopAtTotal.IsEnabled = true;
- }
chkStopOnError.IsEnabled = true;
chkStartMin.IsEnabled = true;
@@ -249,11 +253,17 @@ private void btnStop_Click(object sender, RoutedEventArgs e)
// Update speed.
var ram = Convert.ToInt32(txtRAM.Text);
- var elapsedTime = TimeSpan.ParseExact((string)lblElapsedTime.Content, @"hh\hmm\mss\s",
- CultureInfo.InvariantCulture).TotalSeconds;
- // 0 is the total coverage.
- var speed = (memtestInfo[0].Coverage / 100) * ram / elapsedTime;
- lblSpeed.Content = $"{speed:f2}MB/s";
+ var elapsedTime = TimeSpan.ParseExact(
+ (string)lblElapsedTime.Content,
+ @"hh\hmm\mss\s",
+ CultureInfo.InvariantCulture
+ ).TotalSeconds;
+ lock (memtestInfo)
+ {
+ // 0 is the total coverage.
+ var speed = (memtestInfo[0].Coverage / 100) * ram / elapsedTime;
+ lblSpeed.Content = $"{speed:f2}MB/s";
+ }
MessageBox.Show("Please check if there are any errors", "MemTest finished");
}
@@ -277,7 +287,7 @@ private void btnShow_Click(object sender, RoutedEventArgs e)
isMinimised = false;
// User may have changed offsets while minimised.
- LayOutMemTests();
+ LayoutMemTests();
Activate();
});
@@ -313,7 +323,7 @@ private void cboThreads_SelectionChanged(object sender, SelectionChangedEventArg
private void Offset_Changed(object sender, RoutedPropertyChangedEventArgs e)
{
- RunInBackground(() => { LayOutMemTests(); });
+ RunInBackground(() => { LayoutMemTests(); });
}
private void btnCentre_Click(object sender, RoutedEventArgs e)
@@ -329,13 +339,11 @@ private void cboRows_SelectionChanged(object sender, SelectionChangedEventArgs e
private void chkStopAt_Checked(object sender, RoutedEventArgs e)
{
txtStopAt.IsEnabled = true;
- chkStopAtTotal.IsEnabled = true;
}
private void chkStopAt_Unchecked(object sender, RoutedEventArgs e)
{
txtStopAt.IsEnabled = false;
- chkStopAtTotal.IsEnabled = false;
}
private void txtDiscord_DoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
@@ -377,8 +385,8 @@ private void InitLstCoverage()
{
for (var i = 0; i <= (int)cboThreads.SelectedItem; i++)
{
- // First row is average coverage.
- memtestInfo[i] = new MemTestInfo(i == 0 ? "A" : i.ToString(), 0.0, 0);
+ // First row is the total coverage.
+ memtestInfo[i] = new MemTestInfo(i == 0 ? "T" : i.ToString(), 0.0, 0);
}
lstCoverage.ItemsSource = memtestInfo;
@@ -462,9 +470,6 @@ private bool LoadConfig()
case "stopAtValue":
txtStopAt.Text = appSettings[key];
break;
- case "stopAtTotal":
- chkStopAtTotal.IsChecked = Boolean.Parse(appSettings[key]);
- break;
case "stopOnError":
chkStopOnError.IsChecked = Boolean.Parse(appSettings[key]);
@@ -473,21 +478,13 @@ private bool LoadConfig()
case "startMin":
chkStartMin.IsChecked = Boolean.Parse(appSettings[key]);
break;
-
- default:
- MessageBox.Show($"Unknown key: {key}");
- break;
}
}
}
- catch (ConfigurationErrorsException e)
- {
- MessageBox.Show(e.BareMessage);
- return false;
- }
- catch (FormatException e)
+ catch (Exception e)
{
- MessageBox.Show(e.Message);
+ MessageBox.Show("Failed to load config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ log.Error(e.Message);
return false;
}
@@ -508,7 +505,6 @@ private bool SaveConfig()
dict.Add("rows", cboRows.SelectedItem.ToString());
dict.Add("stopAt", chkStopAt.IsChecked.ToString());
dict.Add("stopAtValue", txtStopAt.Text);
- dict.Add("stopAtTotal", chkStopAtTotal.IsChecked.ToString());
dict.Add("stopOnError", chkStopOnError.IsChecked.ToString());
dict.Add("startMin", chkStartMin.IsChecked.ToString());
@@ -527,7 +523,8 @@ private bool SaveConfig()
}
catch (ConfigurationErrorsException e)
{
- MessageBox.Show(e.BareMessage);
+ MessageBox.Show("Failed to save config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ log.Error(e.Message);
return false;
}
@@ -540,12 +537,16 @@ private bool ValidateInput()
UInt64 totalRAM = ci.TotalPhysicalMemory / (1024 * 1024),
availableRAM = ci.AvailablePhysicalMemory / (1024 * 1024);
+ log.Info($"Total RAM: {totalRAM} Available RAM: {availableRAM}");
+
var ramText = txtRAM.Text;
+ log.Info($"Input RAM: {ramText}");
// Automatically input available RAM if empty.
if (ramText.Length == 0)
{
ramText = GetFreeRAM().ToString();
txtRAM.Text = ramText;
+ log.Info($"No RAM input. Free RAM: {ramText}");
}
else
{
@@ -558,6 +559,7 @@ private bool ValidateInput()
int threads = (int)cboThreads.SelectedItem,
ram = Convert.ToInt32(ramText);
+ log.Info($"Selected threads: {threads}");
if (ram < threads)
{
ShowErrorMsgBox($"Amount of RAM must be greater than {threads}");
@@ -638,7 +640,7 @@ private void CentreXYOffsets()
udYOffset.Value = yOffset;
}
- private void StartMemTests()
+ private bool StartMemTests()
{
CloseAllMemTests();
@@ -651,6 +653,27 @@ private void StartMemTests()
memtests[i].Start(ram, startMin);
});
+ for (int i = 0; i < threads; i++)
+ {
+ var mt = memtests[i];
+ if (!mt.Started)
+ {
+ ShowErrorMsgBox($"Failed to start MemTest instance with PID {mt.PID}");
+
+ txtRAM.IsEnabled = true;
+ cboThreads.IsEnabled = true;
+ btnStart.IsEnabled = true;
+ btnStop.IsEnabled = false;
+ chkStopAt.IsEnabled = true;
+ if (chkStopAt.IsEnabled)
+ txtStopAt.IsEnabled = true;
+ chkStopOnError.IsEnabled = true;
+ chkStartMin.IsEnabled = true;
+
+ return false;
+ }
+ }
+
/*
* Some nag message boxes won't be clicked due to concurrent execution.
* memTestA | memTestB
@@ -659,17 +682,18 @@ private void StartMemTests()
* SendNotifyMessage() |
* | SendNotifyMessage()
*
- * memTestB's window will be active while calling SendNotifyMessage()
- * for memTestA.
+ * memTestB's window will be active while calling SendNotifyMessage() for memTestA.
*/
foreach (var hwnd in WinAPI.FindAllWindows(MemTest.MSG2))
WinAPI.ControlClick(hwnd, MemTest.MSGBOX_OK);
if (!chkStartMin.IsChecked.Value)
- LayOutMemTests();
+ LayoutMemTests();
+
+ return true;
}
- private void LayOutMemTests()
+ private void LayoutMemTests()
{
int xOffset = (int)udXOffset.Value,
yOffset = (int)udYOffset.Value,
@@ -741,7 +765,7 @@ private void UpdateCoverageInfo(bool shouldCheck = true)
if (shouldCheck)
{
// Check coverage %.
- if (chkStopAt.IsChecked.Value && !chkStopAtTotal.IsChecked.Value)
+ if (chkStopAt.IsChecked.Value)
{
var stopAt = Convert.ToInt32(txtStopAt.Text);
if (coverage > stopAt)
@@ -756,7 +780,7 @@ private void UpdateCoverageInfo(bool shouldCheck = true)
var item = lstCoverage.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
if (errors > 0)
{
- memtest.ClickNagMessageBox("MemTest Error", MemTest.MsgBoxButton.NO);
+ memtest.CloseNagMessageBox("MemTest Error");
item.Foreground = Brushes.Red;
ClickBtnStop();
}
@@ -778,14 +802,6 @@ private void UpdateCoverageInfo(bool shouldCheck = true)
if (shouldCheck)
{
- // Check total coverage.
- if (chkStopAt.IsChecked.Value && chkStopAtTotal.IsChecked.Value)
- {
- var stopAt = Convert.ToInt32(txtStopAt.Text);
- if (totalCoverage > stopAt)
- ClickBtnStop();
- }
-
if (IsAllFinished()) ClickBtnStop();
}
});
diff --git a/MemTestHelper2/MemTest.cs b/MemTestHelper2/MemTest.cs
index d88ae2e..0ff5b84 100644
--- a/MemTestHelper2/MemTest.cs
+++ b/MemTestHelper2/MemTest.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Globalization;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
@@ -10,7 +11,9 @@ class MemTest
{
public static readonly string EXE_NAME = "memtest.exe";
public static readonly int WIDTH = 217, HEIGHT = 247,
- MAX_RAM = 2048;
+ MAX_RAM = 2048;
+
+ private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
public const string CLASSNAME = "#32770",
BTN_START = "Button1",
@@ -26,26 +29,19 @@ class MemTest
MSG2 = "Message for first-time users";
private Process process = null;
- private bool hasStarted = false, isFinished = false;
public enum MsgBoxButton { OK, YES, NO }
- public bool Started
- {
- get { return hasStarted; }
- }
+ public bool Started { get; private set; } = false;
- public bool Finished
- {
- get { return isFinished; }
- }
+ public bool Finished { get; private set; } = false;
public bool Minimised
{
- get { return hasStarted ? WinAPI.IsIconic(process.MainWindowHandle) : false; }
+ get { return Started ? WinAPI.IsIconic(process.MainWindowHandle) : false; }
set
{
- if (hasStarted)
+ if (Started)
{
var hwnd = process.MainWindowHandle;
@@ -64,6 +60,12 @@ public bool Minimised
public Point Location
{
+ get
+ {
+ var rect = new WinAPI.Rect();
+ WinAPI.GetWindowRect(process.MainWindowHandle, ref rect);
+ return new Point(rect.Left, rect.Top);
+ }
set
{
if (process != null && !process.HasExited)
@@ -75,7 +77,7 @@ public bool Stopping
{
get
{
- if (!hasStarted || isFinished || process == null || process.HasExited)
+ if (!Started || Finished || process == null || process.HasExited)
return false;
string str = WinAPI.ControlGetText(process.MainWindowHandle, STATIC_COVERAGE);
@@ -85,16 +87,36 @@ public bool Stopping
}
}
- public void Start(double ram, bool startMinimised)
+ public int PID
{
- process = Process.Start(EXE_NAME);
- hasStarted = true;
- isFinished = false;
+ get { return process != null ? process.Id : 0; }
+ }
+ public void Start(double ram, bool startMinimised, int timeoutms = 3000)
+ {
+ process = Process.Start(EXE_NAME);
+ Started = true;
+ Finished = false;
+
+ log.Info($"Started MemTest {PID} with {ram} MB, " +
+ $"start minimised: {startMinimised}, " +
+ $"timeout: {timeoutms}");
+
+ var end = DateTime.Now + TimeSpan.FromMilliseconds(timeoutms);
// Wait for process to start.
- while (string.IsNullOrEmpty(process.MainWindowTitle))
+ while (true)
{
- ClickNagMessageBox(MSG1);
+ if (DateTime.Now > end)
+ {
+ log.Error($"Process {process.Id}: Failed to close message box 1");
+ Started = false;
+ return;
+ }
+
+ if (!string.IsNullOrEmpty(process.MainWindowTitle))
+ break;
+
+ CloseNagMessageBox(MSG1);
Thread.Sleep(100);
process.Refresh();
}
@@ -104,35 +126,43 @@ public void Start(double ram, bool startMinimised)
WinAPI.ControlSetText(hwnd, STATIC_FREE_VER, "MemTestHelper by ∫ntegral#7834");
WinAPI.ControlClick(hwnd, BTN_START);
- while (!ClickNagMessageBox(MSG2))
- Thread.Sleep(100);
-
- if (startMinimised)
+ end = DateTime.Now + TimeSpan.FromMilliseconds(timeoutms);
+ while (true)
{
- WinAPI.PostMessage(hwnd, WinAPI.WM_SYSCOMMAND,
- new IntPtr(WinAPI.SC_MINIMIZE),
- IntPtr.Zero);
+ if (DateTime.Now > end)
+ {
+ log.Error($"Process {process.Id}: Failed to close message box 2");
+ Started = false;
+ return;
+ }
+
+ if (CloseNagMessageBox(MSG2))
+ break;
+
+ Thread.Sleep(100);
}
+
+ if (startMinimised) Minimised = true;
}
public void Stop()
{
- if (process != null && !process.HasExited &&
- hasStarted && !isFinished)
+ if (process != null && !process.HasExited && Started && !Finished)
{
+ log.Info($"Stopping MemTest {PID}");
WinAPI.ControlClick(process.MainWindowHandle, BTN_STOP);
- isFinished = true;
+ Finished = true;
}
}
public void Close()
{
- if (hasStarted && !process.HasExited)
+ if (Started && !process.HasExited)
process.Kill();
process = null;
- hasStarted = false;
- isFinished = false;
+ Started = false;
+ Finished = false;
}
// Returns (coverage, errors).
@@ -142,12 +172,21 @@ public Tuple GetCoverageInfo()
return null;
var str = WinAPI.ControlGetText(process.MainWindowHandle, STATIC_COVERAGE);
- if (str == "" || !str.Contains("Coverage")) return null;
+ if (str.Contains("Memory allocated") || str.Contains("Ending Test")) return null;
+ if (str == "" || !str.Contains("Coverage"))
+ {
+ log.Error($"Invalid static coverage string: '{str}'");
+ return null;
+ }
// Test over. 47.3% Coverage, 0 Errors
// ^^^^^^^^^^^^^^^^^^^^^^^^
var start = str.IndexOfAny("0123456789".ToCharArray());
- if (start == -1) return null;
+ if (start == -1)
+ {
+ log.Error("Failed to find start of coverage number");
+ return null;
+ }
str = str.Substring(start);
// 47.3% Coverage, 0 Errors
@@ -155,7 +194,12 @@ public Tuple GetCoverageInfo()
// some countries use a comma as the decimal point
var coverageStr = str.Split("%".ToCharArray())[0].Replace(',', '.');
double coverage;
- Double.TryParse(coverageStr, NumberStyles.Any, CultureInfo.InvariantCulture, out coverage);
+ var result = Double.TryParse(coverageStr, NumberStyles.Float, CultureInfo.InvariantCulture, out coverage);
+ if (!result)
+ {
+ log.Error($"Failed to parse coverage % from coverage string: '{coverageStr}'");
+ return null;
+ }
// 47.3% Coverage, 0 Errors
// ^^^^^^^^
@@ -163,54 +207,56 @@ public Tuple GetCoverageInfo()
str = str.Substring(start);
// 0 Errors
// ^
- var errors = Convert.ToInt32(str.Substring(0, str.IndexOf(" Errors")));
+ int errors;
+ result = Int32.TryParse(str.Substring(0, str.IndexOf(" Errors")), out errors);
+ if (!result)
+ {
+ log.Error($"Failed to parse error count from error string: '{str}'");
+ return null;
+ }
return Tuple.Create(coverage, errors);
}
- public bool ClickNagMessageBox(string messageBoxCaption, MsgBoxButton button = MsgBoxButton.OK,
- int maxAttempts = 10)
+ public bool CloseNagMessageBox(string messageBoxCaption, int timeoutms = 3000)
{
- if (!hasStarted || isFinished || process == null || process.HasExited)
+ if (!Started || Finished || process == null || process.HasExited)
return false;
+ var end = DateTime.Now + TimeSpan.FromMilliseconds(timeoutms);
var hwnd = IntPtr.Zero;
- var attempts = 0;
do
{
hwnd = WinAPI.GetHWNDFromPID(process.Id, messageBoxCaption);
- attempts++;
Thread.Sleep(10);
- } while (hwnd == IntPtr.Zero && attempts < maxAttempts);
+ } while (hwnd == IntPtr.Zero && DateTime.Now < end);
- if (hwnd == IntPtr.Zero || attempts == maxAttempts)
+ if (hwnd == IntPtr.Zero)
+ {
+ log.Error($"Failed to find nag message box with caption: '{messageBoxCaption}'");
return false;
- else
+ }
+
+ end = DateTime.Now + TimeSpan.FromMilliseconds(timeoutms);
+ while (true)
{
- string strBtn = "";
- switch (button)
+ if (DateTime.Now > end)
{
- case MsgBoxButton.OK:
- strBtn = MSGBOX_OK;
- break;
-
- case MsgBoxButton.YES:
- strBtn = MSGBOX_YES;
- break;
-
- case MsgBoxButton.NO:
- strBtn = MSGBOX_NO;
- break;
+ log.Error($"Failed to close nag message box with caption: '{messageBoxCaption}'");
+ return false;
}
-
- attempts = 0;
- while (!WinAPI.ControlClick(hwnd, strBtn) && attempts < maxAttempts)
+
+ if (WinAPI.SendNotifyMessage(hwnd, WinAPI.WM_CLOSE, IntPtr.Zero, null) != 0)
+ return true;
+ else
{
- Thread.Sleep(100);
- attempts++;
+ log.Error(
+ $"Failed to send notify message to nag message box with caption: '{messageBoxCaption}'. " +
+ $"Error code: {Marshal.GetLastWin32Error()}"
+ );
}
- return attempts != maxAttempts;
+ Thread.Sleep(100);
}
}
}
diff --git a/MemTestHelper2/MemTestHelper2.csproj b/MemTestHelper2/MemTestHelper2.csproj
index 9a3444e..872ea41 100644
--- a/MemTestHelper2/MemTestHelper2.csproj
+++ b/MemTestHelper2/MemTestHelper2.csproj
@@ -1,5 +1,6 @@
+
Debug
@@ -14,6 +15,8 @@
4
true
+
+
AnyCPU
@@ -40,6 +43,9 @@
..\packages\ControlzEx.3.0.2.4\lib\net462\ControlzEx.dll
+
+ ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll
+
..\packages\MahApps.Metro.1.6.5\lib\net47\MahApps.Metro.dll
@@ -47,10 +53,17 @@
..\packages\Microsoft.Xaml.Behaviors.Wpf.1.0.1\lib\net45\Microsoft.Xaml.Behaviors.dll
+
+ ..\packages\NLog.4.6.7\lib\net45\NLog.dll
+
+
+
+
+
..\packages\ControlzEx.3.0.2.4\lib\net462\System.Windows.Interactivity.dll
@@ -116,5 +129,16 @@
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
\ No newline at end of file
diff --git a/MemTestHelper2/WinAPI.cs b/MemTestHelper2/WinAPI.cs
index 6d6efd9..f2f4430 100644
--- a/MemTestHelper2/WinAPI.cs
+++ b/MemTestHelper2/WinAPI.cs
@@ -9,7 +9,10 @@ namespace MemTestHelper2
class WinAPI
{
public const int WM_SETTEXT = 0xC, WM_LBUTTONDOWN = 0x201, WM_LBUTTONUP = 0x202, WM_SYSCOMMAND = 0x112,
- SC_MINIMIZE = 0xF020, SW_SHOW = 5, SW_RESTORE = 9, SW_MINIMIZE = 6, BM_CLICK = 0xF5;
+ WM_CLOSE = 0x10, SC_MINIMIZE = 0xF020, SW_SHOW = 5, SW_RESTORE = 9, SW_MINIMIZE = 6,
+ BM_CLICK = 0xF5;
+
+ private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
public static bool ControlClick(IntPtr hwndParent, string className)
{
@@ -61,13 +64,20 @@ public static IntPtr GetHWNDFromPID(int pid, string windowTitle = "")
if (currPid == pid)
{
- if (windowTitle.Length == 0)
+ if (windowTitle.Length == 0)
hwnd = currHwnd;
else
{
if (sb.ToString() == windowTitle)
hwnd = currHwnd;
- else return true;
+ else
+ {
+ log.Info(
+ $"Found window with PID: {pid}, but target window title: '{windowTitle}' didn't " +
+ $"match window title: '{sb.ToString()}'"
+ );
+ return true;
+ }
}
return false;
@@ -153,6 +163,17 @@ public static List FindAllWindows(string windowTitle)
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
+ [DllImport("user32.dll")]
+ public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);
+
+ public struct Rect
+ {
+ public int Left { get; set; }
+ public int Top { get; set; }
+ public int Right { get; set; }
+ public int Bottom { get; set; }
+ }
+
#endregion
/*
diff --git a/MemTestHelper2/packages.config b/MemTestHelper2/packages.config
index 110604b..2604409 100644
--- a/MemTestHelper2/packages.config
+++ b/MemTestHelper2/packages.config
@@ -1,6 +1,9 @@
+
+
+
\ No newline at end of file