initial checkin of yaulw (locally)

This commit is contained in:
Donald Duck
2016-02-15 12:32:26 -05:00
commit 857eda29e3
115 changed files with 27392 additions and 0 deletions

274
Process/PStarter.cs Normal file
View File

@@ -0,0 +1,274 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
namespace Yaulw.Process
{
/// <remarks>
/// Used to Manage Launching/Killing Processes In an Application
/// </remarks>
public static class PStarter
{
#region Private Static Members
private static Dictionary<uint, String> _StartedProcesses = new Dictionary<uint, String>();
#endregion
#region Public Process Starter Methods
/// <summary>
/// Use this to call a DosCommand in a hidden command prompt and have the command return
/// you a value back, read from standard output
/// </summary>
/// <param name="processStart">processStartInfo</param>
/// <param name="bWait">true to wait till process ends, false otherwise</param>
/// <returns>the PID of the the newly started Process, or 0 if an error occured</returns>
public static string RunDosCommand(string DosCommand)
{
ProcessStartInfo processStart = PStartInfo.CreateCMDDosCommandProcess(DosCommand, true);
processStart.RedirectStandardOutput = true;
string output = String.Empty;
if ((processStart != null) && System.IO.File.Exists(processStart.FileName))
{
// Start the Process
try
{
System.Diagnostics.Process p1;
p1 = System.Diagnostics.Process.Start(processStart);
output = p1.StandardOutput.ReadToEnd();
p1.WaitForExit();
if (String.IsNullOrEmpty(output))
output = p1.StandardOutput.ReadToEnd();
}
catch (Exception e) { string msg = e.Message; /* ignore */ }
}
return output;
}
/// <summary>
/// Always Starts a New Process
/// </summary>
/// <param name="processStart">processStartInfo</param>
/// <param name="bWait">true to wait till process ends, false otherwise</param>
/// <param name="bMustBeUnique">true to check if the process of the same name has already been started, false otherwise</param>
/// <returns>the PID of the the newly started Process, or 0 if an error occured</returns>
//public static uint StartProcess(ProcessStartInfo processStart, bool bWait = false, bool bMustBeUnique = false)
public static uint StartProcess(ProcessStartInfo processStart, bool bWait, bool bMustBeUnique)
{
if ((processStart != null) && System.IO.File.Exists(processStart.FileName))
{
// Enforce Uniqueness * DISABLED * We can't ENFORCE UNIQUENESS WITHOUT ALSO INCLUDING COMMAND-LINE PARAMETERS
// ~TO DO SOMETIME LATER * DOESN"T MATTER HERE * ALREADY HANDLED BY CALLER ANYWAY *
//if (bMustBeUnique && ContainsProcessExe(processStart.FileName))
//{
// return 0;
//}
//else if (bMustBeUnique)
//{
// // Iterate the system's Processes's and make sure that the same process doesn't exist
// System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(Path.GetFileNameWithoutExtension(processStart.FileName));
// foreach (System.Diagnostics.Process process in processes)
// {
// // Found, return 0
// if (String.Compare(process.MainModule.FileName, processStart.FileName, true) == 0)
// return 0;
// }
//}
// Start the Process
try
{
System.Diagnostics.Process p1;
p1 = System.Diagnostics.Process.Start(processStart);
// DISABLED
// Map if for later use
//_StartedProcesses.Add((uint)p1.Id, processStart.FileName.ToLower());
// Wait if asked
if (bWait)
p1.WaitForExit();
return (uint)p1.Id;
}
catch (Exception) { /* ignore */ }
}
return 0;
}
/// <summary>
/// Kills any process started thru PStarter, if it matches the Passed in PID
/// </summary>
/// <param name="PID">The Pid of the Process to Stop</param>
/// <param name="bMustBeHaveBeenStartedByUs">true to only shutdown a process that was started by PStarted</param>
/// <param name="CloseWaitTimeInSeconds">The time in Seconds to wait after closing the Process</param>
/// <param name="bTryClosingMainWindowFirst">true to try sending WM_CLOSE message to Window prior Killing Process</param>
/// <param name="MainWindowCloseWaitTimeInSeconds">The time in Seconds to wait after sending WM_CLOSE message for Process to Close * Only takes effect if bTryClosingMainWindowFirst is true *</param>
/// <returns>true if process stopped, false otherwise</returns>
//public static bool KillProcess(uint PID, bool bMustBeHaveBeenStartedByUs = false, uint CloseWaitTimeInSeconds = 1, bool bTryClosingMainWindowFirst = true, uint MainWindowCloseWaitTimeInSeconds = 2)
public static bool KillProcess(uint PID, bool bMustBeHaveBeenStartedByUs, uint CloseWaitTimeInSeconds, bool bTryClosingMainWindowFirst, uint MainWindowCloseWaitTimeInSeconds)
{
// Valid Process Id
bool bValidToClose = (PID != 0);
// Make sure that PStarted Started This Process
if (bValidToClose && bMustBeHaveBeenStartedByUs)
bValidToClose = _StartedProcesses.ContainsKey(PID);
// Is this process valid to close?
if (bValidToClose)
{
System.Diagnostics.Process p1 = null;
// Try getting the Process
try { p1 = System.Diagnostics.Process.GetProcessById((int)PID); }
catch (Exception) {/* ignore */}
// Process Found
if (p1 != null)
{
// If Main Window Exists, Try Closing this first
if (bTryClosingMainWindowFirst)
{
IntPtr hWnd = p1.MainWindowHandle;
if (hWnd == IntPtr.Zero)
{
// Try getting the window handle by Iterating TopLevel Windows
hWnd = Win32.Functions.GetFirstTopLevelWindowForProcess((int)PID);
}
// If we have a valid Window Handle, try closing it nicely
if (hWnd != IntPtr.Zero && Win32.User32.IsWindow(hWnd))
{
// Try the new school way && the old school way !!!
p1.CloseMainWindow();
Win32.User32.PostMessage(hWnd, (int)Win32.Definitions.WM.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
// Wait a little.. as specified by the configuration
System.Threading.Thread.Sleep((int)TimeSpan.FromSeconds(MainWindowCloseWaitTimeInSeconds).TotalMilliseconds);
// Retry getting the Process *Should be closed by now*
try { p1 = null; p1 = System.Diagnostics.Process.GetProcessById((int)PID); }
catch (Exception) {/* ignore */}
}
}
// Last Resort, Always try to Kill the Process
try { if (p1 != null) p1.Kill(); }
catch (Exception) { /* ignore */ }
// Wait a little
System.Threading.Thread.Sleep((int)TimeSpan.FromSeconds(CloseWaitTimeInSeconds).TotalMilliseconds);
// Retry getting the Process *Must be closed by now*
try { p1 = null; p1 = System.Diagnostics.Process.GetProcessById((int)PID); }
catch (Exception) {/* ignore */}
if (p1 == null)
{
// DISABLED
//_StartedProcesses.Remove(PID);
return true;
}
}
}
return false;
}
#endregion
#region Public Process Starter Helper Methods
/// <summary>
/// Retrieves the PIDs that were started using PStarter
/// </summary>
/// <returns>an uint[] array with Pids, or an empty array if none found</returns>
public static uint[] AllStartedProcessIDs()
{
// DISABLED
//List<uint> Pids = new List<uint>();
//foreach (int key in _StartedProcesses.Keys)
// Pids.Add((uint)key);
//return Pids.ToArray();
return null;
}
/// <summary>
/// Since when we start a Process and it can die/killed externally we wouldn't know,
/// PIDs #'s could be re-used by the OS, so we could accidentially kill a Process that isn't our own.
/// This functions allows a monitoring program to call in with currently running PIDs they know are good
/// on the running system, we can use these numbers and discard any PIDs internally that are no longer accurate
/// * This function will DELETE PIDs/Keys internally * call it only with is a complete list of all PIDs.
/// </summary>
/// <param name="currentlyRunningPIDs">an uint[] array with currently Running PIDs, that we can compare to our started PIDs</param>
public static void PerformGeneralCleanupOfAllStartedProcessIDs(uint[] currentlyRunningPIDs)
{
// DISABLED
//if ((currentlyRunningPIDs != null) && (currentlyRunningPIDs.Length > 0))
//{
// // Iterate thru the Internal DS and track any PID Keys that are no longer valid
// List<uint> RunningPidKeysToRemove = new List<uint>();
// foreach (uint key in _StartedProcesses.Keys)
// {
// if (!currentlyRunningPIDs.Contains(key))
// RunningPidKeysToRemove.Add(key);
// }
// // Remove * no longer valid * PID / Keys
// foreach (uint keyToRemove in RunningPidKeysToRemove)
// _StartedProcesses.Remove(keyToRemove);
//}
}
/// <summary>
/// Returns true if the ProcessExe was started with PStarter, False otherwise
/// </summary>
/// <param name="FileName">Process Executable Filename and Path</param>
/// <returns>true, if found, false otherwise</returns>
public static bool ContainsProcessExe(string FileName)
{
return _StartedProcesses.ContainsValue(FileName.ToLower());
}
/// <summary>
/// Get's the first PID that matches the Given Exe Process FileName
/// </summary>
/// <param name="FileName">Process Executable Filename and Path</param>
/// <returns>a Valid PID or 0 if not found</returns>
public static uint GetFirstPIDForProcessExe(string FileName)
{
if (ContainsProcessExe(FileName))
{
foreach (uint key in _StartedProcesses.Keys)
{
if (String.Compare(_StartedProcesses[key], FileName, true) == 0)
return key;
}
}
return 0;
}
/// <summary>
/// Get's all the PIDs that matches the Given Exe Process FileName
/// </summary>
/// <param name="FileName">Process Executable Filename and Path</param>
/// <returns>valid PIDs or empty PID array, if not found</returns>
public static uint[] GetPIDsForProcessExe(string FileName)
{
List<uint> foundProcess = new List<uint>();
if (ContainsProcessExe(FileName))
{
foreach (uint key in _StartedProcesses.Keys)
{
if (String.Compare(_StartedProcesses[key], FileName, true) == 0)
foundProcess.Add(key);
}
}
return foundProcess.ToArray();
}
#endregion
}
}